- Joined
- Nov 14, 2008
- Messages
- 3,256
I'll wait, nothing too serious just thought of making a TD and this is the every td creator's dream.
if u.moving then
set u.moving=false
set get=u
call thistype.STOP.fire()
endif
There is no point in tracking a dead unit >: P
Some maps might need you to track dead units, so you should use a static if.
Using this for a stamina system.
if 0<GetUnitAbilityLevel(GetUnitById(u),'Amov') then
set c=GetUnitCurrentOrder(GetUnitById(u))
if (0!=c and 851972!=c and 851993!=c) then
//natural movement
endif
EVENT_UNIT_ACQUIRED_TARGET
library IsUnitMoving uses UnitEvent
globals
private boolean array o //ordered
public integer array n //next moving
public integer array p //prev moving
public integer array nn //next not moving
private integer array np //previous not moving
private integer array nu //next unit
private integer array pu //previous unit
public boolean array m //is moving
private real array x //x coord
private real array y //y coord
private boolean array b //allocated
private integer th=0 //event leaks
private integer ch=0 //events up
private trigger t //acquired raneg trig
private integer array k //target id
private conditionfunc f //target function
endglobals
private function OO takes nothing returns boolean
local integer i
if (851972==GetIssuedOrderId() or 851993==GetIssuedOrderId()) then
set i=GetUnitUserData(GetTriggerUnit())
set k[i]=0
if (o[i]) then
set n[p[i]]=n[i]
set p[n[i]]=p[i]
set nn[i]=nn[0]
set np[nn[0]]=i
set np[i]=0
set nn[0]=i
set x[i]=GetWidgetX(GetUnitById(i))
set y[i]=GetWidgetY(GetUnitById(i))
set m[i]=false
set o[i]=false
endif
endif
return false
endfunction
private function OTO takes nothing returns boolean
local integer i=GetUnitUserData(GetTriggerUnit())
set k[i]=GetUnitUserData(GetEventTargetUnit())
if (b[i] and not o[i]) then
set nn[np[i]]=nn[i]
set np[nn[i]]=np[i]
set n[i]=n[0]
set p[n[0]]=i
set p[i]=0
set n[0]=i
set o[i]=true
set m[i]=true
set x[i]=GetWidgetX(GetUnitById(i))
set y[i]=GetWidgetY(GetUnitById(i))
endif
return false
endfunction
private function OC takes nothing returns boolean
local integer i=GetUnitUserData(GetTriggerUnit())
set k[i]=GetUnitUserData(GetSpellTargetUnit())
if (o[i]) then
set nn[i]=nn[0]
set np[nn[0]]=i
set np[i]=0
set nn[0]=i
set n[p[i]]=n[i]
set p[n[i]]=p[i]
set o[i]=false
set m[i]=false
set x[i]=GetWidgetX(GetUnitById(i))
set y[i]=GetWidgetY(GetUnitById(i))
endif
return false
endfunction
private function T takes nothing returns boolean
set k[GetUnitUserData(GetTriggerUnit())]=GetUnitUserData(GetEventTargetUnit())
return false
endfunction
private function ib takes integer u returns nothing
if 0<GetUnitAbilityLevel(GetUnitById(u),'Amov') then
set nu[u]=nu[0]
set pu[nu[0]]=u
set pu[u]=0
set nu[0]=u
set x[u]=GetWidgetX(GetIndexedUnit())
set y[u]=GetWidgetY(GetIndexedUnit())
set b[u]=true
set nn[u]=nn[0]
set np[nn[0]]=u
set np[u]=0
set nn[0]=u
set k[u]=0
endif
endfunction
private function db takes integer u returns nothing
if b[u] then
if (o[u]) then
set p[n[u]]=p[u]
set n[p[u]]=n[u]
set o[u]=false
else
set nn[np[u]]=nn[u]
set np[nn[u]]=np[u]
endif
set m[u]=false
set b[u]=false
set nu[pu[u]]=nu[u]
set pu[nu[u]]=pu[u]
set k[u]=0
endif
endfunction
private function I takes nothing returns boolean
set ch=ch+1
call ib(GetIndexedUnitId())
call TriggerRegisterUnitEvent(t,GetIndexedUnit(),EVENT_UNIT_ACQUIRED_TARGET)
return false
endfunction
private function D takes nothing returns boolean
local integer i=nu[0]
set th=th+1
set ch=ch-1
call db(GetIndexedUnitId())
if (th>25+ch) then
call DestroyTrigger(t)
set t=CreateTrigger()
call TriggerAddCondition(t,f)
set th=0
loop
exitwhen 0==i
call TriggerRegisterUnitEvent(t,GetUnitById(i),EVENT_UNIT_ACQUIRED_TARGET)
set i=nu[i]
endloop
endif
return false
endfunction
private function R takes nothing returns boolean
call ib(GetEventUnitId())
return false
endfunction
private function D2 takes nothing returns boolean
call db(GetEventUnitId())
return false
endfunction
private function S takes nothing returns nothing
local integer u=nu[0]
local real h
local real g
local integer q
loop
exitwhen (0==u)
set h=GetWidgetX(GetUnitById(u))
set g=GetWidgetY(GetUnitById(u))
if h==x[u] and g==y[u] then
if m[u] then
if (o[u]) then
set nn[u]=nn[0]
set np[nn[0]]=u
set np[u]=0
set nn[0]=u
set n[p[u]]=n[u]
set p[n[u]]=p[u]
set o[u]=false
endif
set m[u]=false
endif
else
set x[u]=h
set y[u]=g
if not m[u] then
set m[u]=true
if (not o[u]) then
set q=GetUnitCurrentOrder(GetUnitById(u))
if ((0!=q and 851972!=q and 851993!=q) or (0==q and 0!=k[u])) then
set nn[np[u]]=nn[u]
set np[nn[u]]=np[u]
set n[u]=n[0]
set p[n[0]]=u
set p[u]=0
set n[0]=u
set o[u]=true
endif
endif
endif
endif
set u=nu[u]
endloop
endfunction
private module Init
private static method onInit takes nothing returns nothing
local integer i=15
local trigger t1=CreateTrigger()
local trigger t2=CreateTrigger()
local trigger t3=CreateTrigger()
local player q
set t=CreateTrigger()
set f=Condition(function T)
call TriggerAddCondition(t,f)
loop
set q=Player(i)
call TriggerRegisterPlayerUnitEvent(t1,q,EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t2,q,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t2,q,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t3,q,EVENT_PLAYER_UNIT_SPELL_CHANNEL, null)
exitwhen 0==i
set i=i-1
endloop
call TriggerAddCondition(t1,Condition(function OO))
call TriggerAddCondition(t2,Condition(function OTO))
call TriggerAddCondition(t3,Condition(function OC))
call UnitEvent.RESURRECT.register(Condition(function R))
call UnitEvent.ANIMATE.register(Condition(function R))
call UnitEvent.DEATH.register(Condition(function D2))
set q=null
set t1=null
set t2=null
set t3=null
call RegisterUnitIndexEvent(Condition(function I), UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function D), UnitIndexer.DEINDEX)
call TimerStart(CreateTimer(),.031250000,true,function S)
endmethod
endmodule
struct UnitMoving extends array
implement Init
endstruct
endlibrary
Using SetUnitX/Y will crash a unit that doesn't have the Amov ability.
You probably did something else wrong.Weep, I tried "knocking back" towers and it spun wc3 into an infinite loop. I did this in patch 1.25 but I don't think that's something they fixed.
SetUnitX()
and SetUnitY()
, because even though they are moved, their model is not updated properly.'Amov'
ability can be moved without any problems, provided that they had more than 0 base movement speed.SetUnitPosition()
works properly in both cases.if 0 < GetUnitDefaultMoveSpeed(GetUnit(u)) then
instead of if 0 != GetUnitAbilityLevel(GetUnit(u), 'Amov') then
(this check will omit towers and alike as well, because they all have 0 base movement speed).AIDS_RegisterOnDeallocate(Filter(function thistype.index))
supposed to be AIDS_RegisterOnDeallocate(Filter(function thistype.deindex))
?Event 1.0: add to stationary
Event 1.1: remove from stationary
Event 2.1: remove from stationary (uh oh!)
Event 2.0: add to stationary