- Joined
- Apr 24, 2012
- Messages
- 9,802
Don't forget the GUI version (local unit udg_CastingUnit = GetTriggerUnit()). 
Good job though.

Good job though.
//Replace with accurate timer
call TriggerSleepAction(0)
local timer t = CreateTimer()
call SaveInteger(TimerHash, GetHandleId(t), 0, data)
call TimerStart(t, x, false, function callback)
local timer t = GetExpiredTimer()
local data d = LoadInteger(TimerHash, GetHandleId(t), 0)
call FlushChildHashtable(TimerHash, GetHandleId(t))
call DestroyTimer(t)
set t = null
function INeedTimersThatContinueThisFunction takes nothing returns boolean
local integer i = 1
loop
if (1 > 10) then
return true
endif
call TriggerSleepAction(1.5)
set i = i + 1
endloop
return false
endfunction
what xonox showed is OK for all cases. What is the meaning of your example by the way? I assume u wantedThat will do for most cases but there are still things that are not so easily done.
if (i>10) then
This specific code will freeze or crash the game.
There's 2 ways really:
Use an indexed array and a looping trigger
Store the current index in a hashtable and use a looping timer
native UnitAlive takes unit u returns boolean
//! import "MoveMod.j"
//! import "ExtraFunctions.j"
library Rockfall initializer in requires MoveMod
globals
private trigger CastTrig = CreateTrigger()
private trigger LoopTrig = CreateTrigger()
private real array TargetX
private real array TargetY
private unit array Caster
private real array Area
private integer array Rocks
private integer array Ticks
private real array DropFactor
private integer Targets = 0
private unit array Unit
private unit array Owner
private real array Damage
private integer array Fall
private integer Units = 0
private unit array Victim
private integer array Slow
private integer array Duration
private integer Slows = 0
private constant integer SLOW_AMOUNT = 300//R1000
private constant real FALL_DELAY = 0.7
private constant real SPLASH = 150
private constant integer ABIL = 'A000'
private constant string SFX = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
private constant integer DUMMY = 'h000'
private constant real TIMEOUT = 0.0312500
private player p
endglobals
private function filter takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitAlly(u,p) then
return false
endif
if not(UnitAlive(u)) then
return false
endif
return true
endfunction
private function Loop takes nothing returns nothing
local integer i = 1
local real r
local real x
local real y
local real angle
local group g
local unit u
local integer ID
loop
exitwhen i > Slows
if Duration[i] == 0 then
set ID = GetUnitUserData(Victim[i])
call AddMoveSpeedRating(Victim[i],ID,-Slow[i])
set Victim[i] = Victim[Slows]
set Slow[i] = Slow[Slows]
set Duration[i] = Duration[Slows]
set Slows = Slows - 1
else
set Duration[i] = Duration[i] - 1
set i = i + 1
endif
endloop
set i = 1
loop
exitwhen i > Units
if Fall[i] == 0 then
call KillUnit(Unit[i])
call DestroyEffect(AddSpecialEffect(SFX,GetUnitX(Unit[i]),GetUnitY(Unit[i])))
set g = CreateGroup()
set p = GetOwningPlayer(Owner[i])
call GroupEnumUnitsInRange(g,GetUnitX(Unit[i]),GetUnitY(Unit[i]),SPLASH,Filter(function filter))
loop
set u = FirstOfGroup(g)
exitwhen u == null
set ID = GetUnitUserData(u)
call UnitDamageTarget(Owner[i],u,Damage[i],true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
call AddMoveSpeedRating(u,ID,-SLOW_AMOUNT)
call Debug(R2S(GetUnitMoveSpeed(u)))
set Slows = Slows + 1
set Victim[Slows] = u
set Slow[Slows] = -SLOW_AMOUNT
set Duration[Slows] = 32
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
set Unit[i] = Unit[Units]
set Owner[i] = Owner[Units]
set Damage[i] = Damage[Units]
set Fall[i] = Fall[Units]
set Units = Units - 1
else
set Fall[i] = Fall[i] - 1
set i = i + 1
endif
endloop
set i = 1
loop
exitwhen i > Targets
if Ticks[i] == 0 then
set TargetX[i] = TargetX[Targets]
set TargetY[i] = TargetY[Targets]
set Caster[i] = Caster[Targets]
set Area[i] = Area[Targets]
set Rocks[i] = Rocks[Targets]
set Ticks[i] = Ticks[Targets]
set DropFactor[i] = DropFactor[Targets]
set Targets = Targets - 1
else
set r = I2R(Ticks[i])*DropFactor[i]
loop
if r < Rocks[i] then
set r = GetRandomReal(0,Area[i])
set angle = GetRandomReal(0,360)
set x = TargetX[i] + r * Cos(angle * bj_DEGTORAD)
set y = TargetY[i] + r * Sin(angle * bj_DEGTORAD)
set Units = Units + 1
set Unit[Units] = CreateUnit(GetOwningPlayer(Caster[i]),DUMMY,x,y,GetRandomReal(0,360))
set Owner[Units] = Caster[i]
set Damage[Units] = GetHeroInt(Caster[i],true)
set Fall[Units] = R2I(0.7/TIMEOUT)
call SetUnitFlyHeight(Unit[Units],0,1000./FALL_DELAY)
set Rocks[i] = Rocks[i] - 1
else
exitwhen true
endif
endloop
set Ticks[i] = Ticks[i] - 1
set i = i + 1
endif
endloop
if Slows == 0 and Units == 0 and Targets == 0 then
call DisableTrigger(LoopTrig)
endif
endfunction
private function Cast takes nothing returns nothing
if GetSpellAbilityId() == ABIL then
set Targets = Targets + 1
set TargetX[Targets] = GetSpellTargetX()
set TargetY[Targets] = GetSpellTargetY()
set Caster[Targets] = GetTriggerUnit()
set Area[Targets] = 400
set Rocks[Targets] = 30
set Ticks[Targets] = R2I(I2R(5)/TIMEOUT)
set DropFactor[Targets] = I2R(Rocks[Targets])/I2R(Ticks[Targets])
call EnableTrigger(LoopTrig)
endif
endfunction
private function in takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 15
call TriggerRegisterPlayerUnitEvent(CastTrig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
endloop
call TriggerAddAction(CastTrig,function Cast)
call TriggerRegisterTimerEvent(LoopTrig,TIMEOUT,true)
call TriggerAddAction(LoopTrig,function Loop)
endfunction
endlibrary
native UnitAlive takes unit u returns boolean
//! import "TimerHash.j"
library Spawner
private function handler takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer ID = GetHandleId(t)
local unit u = LoadUnitHandle(TimerHash,ID,0)
local integer id
if UnitAlive(u) or GetUnitTypeId(u) != null then
set id = LoadInteger(TimerHash,ID,1)
call CreateUnit(GetOwningPlayer(u),id,GetUnitX(u),GetUnitY(u),0)
else
call DestroyTimer(t)
call FlushChildHashtable(TimerHash,ID)
endif
set t = null
endfunction
function DesignateSpawner takes unit u, integer id, real timeout returns nothing
local timer t = CreateTimer()
local integer ID = GetHandleId(t)
call SaveUnitHandle(TimerHash,ID,0,u)
call SaveInteger(TimerHash,ID,1,id)
call TimerStart(t,timeout,true,function handler)
set t = null
endfunction
endlibrary