I can't seem to figure out a way to keep this MUI.
Basically i need a way to limit the amount of units created by this spell to a certain amount per level.
Heres how it works:
- Every X distance, unit is created.
- Unit is constantly given orders (crappy AI).
- Unit eventually dies.
However if you move a far distance, too many units are created.
The only half-decent way i know is to group units of a specific player on the map, but that would only be MPI.
So yeah, any way to limit the amount of units?
Script:
Basically i need a way to limit the amount of units created by this spell to a certain amount per level.
Heres how it works:
- Every X distance, unit is created.
- Unit is constantly given orders (crappy AI).
- Unit eventually dies.
However if you move a far distance, too many units are created.
The only half-decent way i know is to group units of a specific player on the map, but that would only be MPI.
So yeah, any way to limit the amount of units?
Script:
JASS:
scope SoulTrail initializer Init
globals
private constant integer Abil_id = 039;A001039;
private constant integer IS_stat_id = 039;A007039;
private constant integer Damage_id = 039;A008039;
private constant integer Attackspeed_id = 039;A009039;
private constant integer Dummy_id = 039;u001039;
private constant real Interval = 0.04
private constant real Distance = 150.00
private constant string Sfx = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
private constant string Point = "origin"
endglobals
//=======================================================================
private function Maxdist takes integer lvl returns real
return 1800.00-(200.00*lvl)
endfunction
private function MaxDuration takes integer lvl returns real
return 10.00
endfunction
private function LeashRange takes integer lvl returns real
return 1000.00
endfunction
private function Radius takes integer lvl returns real
return 600.00
endfunction
//=======================================================================
private keyword Data
private keyword Atad
globals
private Data array D
private Atad array A
private integer DT = 0
private integer AT = 0
private timer Timer = null
private boolexpr Truefilt = null
private boolexpr Enemyfilt = null
private constant integer Order_stop = 851972
private constant integer Order_smart = 851971
private constant integer Order_attack = 851983
endglobals
//=======================================================================
private function DistanceXY takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
endfunction
//=======================================================================
private function EnemyFilt takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405
endfunction
//=======================================================================
private struct Data
unit cast
real castx
real casty
real dist
endstruct
private struct Atad
unit cast
unit dum
real time
integer lvl
integer alpha
private method onDestroy takes nothing returns nothing
call ShowUnit(.dum,false)
call KillUnit(.dum)
set .cast = null
set .dum = null
endmethod
endstruct
//=======================================================================
private function Update takes nothing returns nothing
local Atad a = 0
local real x = 0.00
local real y = 0.00
local real dist = 0.00
local integer lvl = 0
local integer steplvl = 0
local integer i = 1
local unit u = null
loop
exitwhen i > DT
set x = GetUnitX(D<i>.cast)
set y = GetUnitY(D<i>.cast)
set dist = DistanceXY(D<i>.castx,D<i>.casty,x,y)
set lvl = GetUnitAbilityLevel(D<i>.cast,Abil_id)
set steplvl = GetUnitAbilityLevel(D<i>.cast,IS_stat_id)
set D<i>.dist = D<i>.dist + dist
if D<i>.dist >= Maxdist(lvl) then
call DestroyEffect(AddSpecialEffectTarget(Sfx,D<i>.cast,Point))
set a = Atad.create()
set a.cast = D<i>.cast
set a.dum = CreateUnit(GetOwningPlayer(D<i>.cast),Dummy_id,x,y,GetUnitFacing(D<i>.cast))
set a.alpha = 255
set a.time = 0.00
set a.lvl = lvl
call SetUnitMoveSpeed(a.dum,GetUnitMoveSpeed(D<i>.cast))
call SetUnitVertexColor(a.dum,255,255,255,a.alpha)
call SetUnitPathing(a.dum,false)
if steplvl > 0 then
call UnitAddAbility(a.dum,Damage_id)
call UnitAddAbility(a.dum,Attackspeed_id)
call SetUnitAbilityLevel(a.dum,Damage_id,steplvl)
call SetUnitAbilityLevel(a.dum,Attackspeed_id,steplvl)
endif
set AT = AT + 1
set A[AT] = a
set D<i>.dist = 0.00
endif
set D<i>.castx = x
set D<i>.casty = y
set i = i + 1
endloop
set i = 1
loop
exitwhen i > AT
set x = GetUnitX(A<i>.cast)
set y = GetUnitY(A<i>.cast)
set steplvl = GetUnitAbilityLevel(A<i>.cast,IS_stat_id)
if A<i>.time >= MaxDuration(A<i>.lvl) or GetWidgetLife(A<i>.cast) < 0.406 then
call A<i>.destroy()
set A<i> = A[AT]
set AT = AT - 1
set i = i - 1
else
call SetUnitVertexColor(A<i>.dum,255,255,255,A<i>.alpha)
if steplvl > 0 then
if GetUnitAbilityLevel(A<i>.dum,Damage_id) == 0 then
call UnitAddAbility(A<i>.dum,Damage_id)
call UnitAddAbility(A<i>.dum,Attackspeed_id)
endif
call SetUnitAbilityLevel(A<i>.dum,Damage_id,steplvl)
call SetUnitAbilityLevel(A<i>.dum,Attackspeed_id,steplvl)
else
if GetUnitAbilityLevel(A<i>.dum,Damage_id) > 0 then
call UnitRemoveAbility(A<i>.dum,Damage_id)
call UnitRemoveAbility(A<i>.dum,Attackspeed_id)
endif
endif
if not IsUnitInRange(A<i>.dum,A<i>.cast,LeashRange(A<i>.lvl)) then
call SetUnitX(A<i>.dum,x + Distance * Cos(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
call SetUnitY(A<i>.dum,y + Distance * Sin(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
call IssuePointOrderById(A<i>.dum,Order_attack,x + Distance * Cos(GetRandomReal(0.00,360.00) * bj_DEGTORAD),y + Distance * Sin(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
else
if GetUnitCurrentOrder(A<i>.cast) == Order_attack or GetUnitCurrentOrder(A<i>.cast) == Order_smart then
set u = GetOrderTargetUnit()
if u != null then
if IsUnitEnemy(u,GetOwningPlayer(A<i>.cast)) == true then
call IssueTargetOrderById(A<i>.dum,Order_attack,u)
else
call IssuePointOrderById(A<i>.dum,Order_attack,x + Distance * Cos(GetRandomReal(0.00,360.00) * bj_DEGTORAD),y + Distance * Sin(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
endif
else
if GetUnitCurrentOrder(A<i>.dum) != Order_attack then
call IssuePointOrderById(A<i>.dum,Order_attack,x + Distance * Cos(GetRandomReal(0.00,360.00) * bj_DEGTORAD),y + Distance * Sin(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
endif
endif
else
if GetUnitCurrentOrder(A<i>.dum) != Order_attack then
call IssuePointOrderById(A<i>.dum,Order_attack,x + Distance * Cos(GetRandomReal(0.00,360.00) * bj_DEGTORAD),y + Distance * Sin(GetRandomReal(0.00,360.00) * bj_DEGTORAD))
endif
endif
endif
set u = null
set A<i>.alpha = A<i>.alpha - 1
set A<i>.time = A<i>.time + Interval
endif
set i = i + 1
endloop
endfunction
//=======================================================================
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local Data d = 0
if GetLearnedSkill() == Abil_id and GetUnitAbilityLevel(cast,Abil_id) == 1 and IsUnitIllusion(cast) == false then
set d = Data.create()
set d.cast = cast
set d.castx = GetUnitX(d.cast)
set d.casty = GetUnitY(d.cast)
set d.dist = 0.00
set DT = DT + 1
if DT == 1 and AT == 0 then
call TimerStart(Timer,Interval,true,function Update)
endif
set D[DT] = d
endif
set cast = null
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
local unit dum = null
set Timer = CreateTimer()
set Truefilt = Filter(function TrueFilt)
set Enemyfilt = Filter(function EnemyFilt)
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_HERO_SKILL,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(trig,function Actions)
set dum = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00)
call UnitAddAbility(dum,Damage_id)
call UnitAddAbility(dum,Attackspeed_id)
call ShowUnit(dum,false)
call KillUnit(dum)
set dum = null
set trig = null
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>