- Joined
- Jun 17, 2007
- Messages
- 1,433
This tutorial requires a decent understanding of vJASS to fully comprehend. A read through the JASSHelper manual should be enough.
This tutorial will cover two methods of achieving multi-unit instance-ability using two methods; each ideal for different tasks.
Many of you may have read Dynasti's tutorial on struct indexing, however, that code isn't modulare. Certainly you'd rather not have to create a global timer, a global integer, an integer array, etc... . This is where the glory of TimedLoop comes in. Here is an example of the standard form of struct indexing:
The above is a simple spell which heals a unit every .10 seconds. The problem is that none of this code is being reused, and it's adding unneeded complexity to our script. 65 lines could easilly be reduced. Surely we can do better? This is where TimedLoop comes in. To use TimedLoop, we have to 'implement' it. I'll comment the next script to help you understand it.
I'll finish the second half later today.
This tutorial will cover two methods of achieving multi-unit instance-ability using two methods; each ideal for different tasks.
Many of you may have read Dynasti's tutorial on struct indexing, however, that code isn't modulare. Certainly you'd rather not have to create a global timer, a global integer, an integer array, etc... . This is where the glory of TimedLoop comes in. Here is an example of the standard form of struct indexing:
JASS:
scope SomeSpell initializer Init
globals
private constant integer SPELL_ID = 'A000'
private constant real HP = 5
private constant real INTERVAL = 0.1
private timer Tim = CreateTimer()
private integer array Queue
private integer Total = 0
endglobals
struct SomeStruct
integer x = 0
unit u = null
static method Loop takes nothing returns nothing
local thistype dat
local integer i = 0
loop
exitwhen i >= Total
set dat = Queue[i]
if dat.x < 10 then
set dat.x = dat.x + 1
call SetWidgetLife(dat.u, GetWidgetLife(dat.u) + HP)
else
call dat.destroy()
set Total = Total - 1
set Queue[i] = Queue[Total]
set i = i - 1
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
static method create takes unit u returns thistype
local thistype dat = thistype.allocate()
set dat.u = u
if Total == 0 then
call TimerStart(Tim, INTERVAL, true, function SomeStruct.Loop)
endif
set Queue[Total] = dat
set Total = Total + 1
return dat
endmethod
endstruct
private function Actions takes nothing returns nothing
call SomeStruct.create(GetTriggerUnit())
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddAction(t, function Actions)
call TriggerAddCondition(t, Condition(function Conditions))
endfunction
endscope
JASS:
scope SomeSpell initializer Init
globals
private constant integer SPELL_ID = 'A000'
private constant real HP = 5
endglobals
struct SomeStruct
integer x = 0
unit u = null
implement TimedLoop
method onTimedLoop takes nothing returns boolean
//The method must be name 'onTimedLoop' and must
//return boolean.
set .x = .x + 1
call SetWidgetLife(.u, GetWidgetLife(.u) + HP)
if .x >= 10 then
return TimedLoop_STOP
//When you want it to stop an instace of a struct, you must return false.
//the TimedLoop_STOP is simply a constant.
endif
return TimedLoop_CONTINUE
//Otherwise, return true
endmethod
static method create takes unit u returns thistype
local thistype dat = thistype.allocate()
set dat.u = u
call dat.startTimedLoop()
//This must be called once for every struct instance.
return dat
endmethod
endstruct
private function Actions takes nothing returns nothing
call SomeStruct.create(GetTriggerUnit())
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddAction(t, function Actions)
call TriggerAddCondition(t, Condition(function Conditions))
endfunction
endscope
I'll finish the second half later today.
Last edited: