| 11-24-2009, 07:30 AM | #1 |
How can I use timers I have never used them before, just waits triggersleep action etc. With timers will it enable my spells to be cast before the wait duration has expired? |
| 11-24-2009, 11:50 AM | #2 |
The lack of multi-instanceability of GUI spells is the consequence of a lack of local variables in GUI more than the use of waits instead of timers. We still prefer to use timers in JASS because they are (more) accurate. We most often use timers in combination with TimerUtils, which allow us to recycle timers (thus avoiding some obscure bugs) as well as attach data to timers (thus allowing us to pass information to the function that the timer will run). A simple spell that kills all units in the target area after five seconds would look like this (the example also uses GroupUtils and SpellEvent): JASS:scope KillSpell initializer Init // The function Init will run when the map starts. // SPELL CALIBRATION SECTION globals private constant integer SPELL_ABILITY_ID = 'A000' private constant string EFFECT_PATH = "Spells//CustomSpellModel.mdx" endglobals private constant function EffectDelay takes integer level returns real return 5.0 endfunction private constant function AreaOfEffect takes integer level returns real // The values set in the object editor should match these values. return 200.0+50.0*level //level 1: 250 level 2: 300 level 3: 350 endfunction // END OF SPELL CALIBRATION private function GroupEnumFilter takes nothing returns nothing // If we wanted the spell to not kill all units, we would need to // add an if statemet here to check if the unit is a valid target. // For the purpose of this example, though, we'll just kill them all. call KillUnit(GetFilterUnit()) endfunction private struct timerData // This is the struct used to pass data to the delayed function. unit caster real targetx real targety real radius effect fx endstruct private function DelayedEffect takes nothing returns nothing // This is the function called by the timer. local timer t = GetExpiredTimer() // Get the timer that called this function. local integer i = GetTimerData(t) // Get the integer attached to the timer. local timerData d = timerData(i) // Convert the integer to our struct. // Okay, this was deliberately a bit long, it can be shortened to one line: // local timerData d = timerData(GetTimerData(GetExpiredTimer())) // The following line requires GroupUtils, it allows us to affect // all units covered by the spell's targeting circle. call GroupEnumUnitsInArea(ENUM_GROUP, d.targetx, d.targety, d.radius, Condition( function GroupEnumFilter )) // Cleanup. call DestroyEffect(d.fx) call d.destroy() call ReleaseTimer(GetExpiredTimer()) endfunction function SpellEffect takes nothing returns nothing // Get a timer. local timer t = NewTimer() // Get a timerData struct. local timerData d = timerData.create() // Convert the struct to an integer so we can attach it to the timer. local integer i = integer(d) // Get the level of the spell (example uses SpellEvent). local integer level = GetUnitAbilityLevel(SpellEvent.CastingUnit, SPELL_ABILITY_ID) // Set the timerData values (example uses SpellEvent). set d.caster = SpellEvent.CastingUnit set d.targetx = SpellEvent.TargetX set d.targety = SpellEvent.TargetY set d.radius = AreaOfEffect(level) set d.fx=AddSpecialEffect( EFFECT_PATH, d.targetx, d.targety ) // Attach the timer data to the timer. call SetTimerData(t, i) // We could have also done this without the local integer: // call SetTimerData(t, integer(d)) // Start the timer: call TimerStart(t, EffectDelay(level), false, function DelayedEffect ) endfunction private function Init takes nothing returns nothing // Using SpellEvent here: call RegisterSpellEffectResponse(SPELL_ABILITY_ID, SpellEffect) endfunction endscope |
| 11-24-2009, 12:41 PM | #3 |
what does it mean to set data to the timer ? is it creating a timer specific to this trigger? what is spellevent/grouputils? and why use it? |
| 11-24-2009, 01:59 PM | #4 | ||
Quote:
Quote:
|
| 11-24-2009, 05:29 PM | #5 |
ah thanks for explaining will explore timers with a bit more confidence now :) |
| 11-25-2009, 10:47 AM | #6 |
Uhm, why a constant function instead of a constant integer? And why it takes a integer if it always returns 5? |
| 11-25-2009, 01:09 PM | #7 | |
Quote:
|
