[JASS] Timer as loop using unit indexer

Status
Not open for further replies.
I'm shifting from loops to timers. Something I should have done a long time ago really.

Anyhow, I want to pass two units and four reals to the timer; the caster, a spawned missile unit, it's x position, y position, direction and the remaining duration of the timer. Basically it is a line spell. (projectile moves in direction)

I uses Bribe's Unit Indexer, since another system uses it anyway.

Basically, I just want to know what to do exactly to pass the information.

JASS:
function FiSp_Loop takes nothing returns nothing
  
endfunction

function FiSp_Init takes nothing returns nothing
    local unit caster       = GetSpellAbilityUnit()
    local integer level     = GetUnitAbilityLevel(caster, 'A000')
    local real casterX      = GetUnitX(caster)
    local real casterY      = GetUnitY(caster)
    local location ta       = GetSpellTargetLoc()
    local real targetX      = GetLocationX(ta)
    local real targetY      = GetLocationY(ta)
    local timer t           = CreateTimer()
    local integer t_id      = GetHandleId(t)
    local integer u_id      = GetUnitUserData(caster)
    local real duration     = 1.5
  
    if (GetSpellAbilityId() != 'A000') then
        set ta = null
        set t = null
        return
    endif
  
    call DisplayTextToPlayer(Player(0), 0., 0., I2S(u_id))
  
    call TimerStart (t, duration, false, function FiSp_Loop)

  
  
     set ta = null
     set t = null
endfunction
[VJass]
 
Hashtable can be used. For example attaching an integer to a timer works like:

JASS:
function bar
    local timer clock = GetExpiredTimer()
    local integer handleId = GetHandleId(clock)
    local integer value = LoadInteger(HASH, handleId, 0)


function foo
    local integer value
    local timer clock
    local integer handleId

    set value = 2
    set clock = CreateTimer()
    set handleId = GetHandleId(clock)
    call SaveInteger(HASH, handleid, 0, value)
    call TimerStart(clock, 1, false, function bar)
function foo saves an integer, function bar loads the integer
It's assumed that "HASH" is an initialisized hashtable.
 
I'm not used to use hashtables either, so it doesn't make it easier, haha. My goto for storage is arrays. Might be inefficient, but I use them in other languages, so I've been to lazy to change so far.

Do I just initialize the hashtable on map startup, and can I use the same for all loop spells, or do I need one for each spell, or one for each spell run?
 
I assume you use JassHelper (it's already in JNGP), as you wrote "vjass"?

Anyways, no, you probably don't need multiple hashtables for the spells. There can be one hashtable, yes, assigned somewhere on map start,
and then all spells can internaly create timers and use the hashtable to save values to the handle id of the timer.

Hashtable is similar like an array, but not 1D, but 2D. So it can be imagined like columns and rows.
You save something in Column "HandleId of Timer" (which is always unique), and Row "0".
And later when you wanna lookup the value, you look into Column "HandleId of Timer", and Row "0" and get to your entry again.
 
I just wanted to point out that you can use TriggerAddCondition() over TriggerAddAction() to make your on cast function look a lot cleaner:

JASS:
function onCast takes nothing returns boolean
    local unit caster   
    local integer level
    local real casterX   
    local real casterY    
    local real targetX    
    local real targetY    
    local timer t        
    if GetSpellAbilityId() = 'A000' then
        set unit caster       = GetTriggerUnit()
        set integer level     = GetUnitAbilityLevel(caster, 'A000')
        set real casterX      = GetUnitX(caster)
        set real casterY      = GetUnitY(caster)
        set real targetX      = GetSpellTargetX()
        set real targetY      = GetSpellTargetY()
        set timer t           = CreateTimer()

        // do other on cast stuff
    endif
    return false
endfunction

function onInit takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function onCast))
endfunction

Also, i see that you are using GetSpellTargetLoc() and then immediately using coordinates with GetLocationX & Y. There is a native that does this already xD GetSpellTargetX() GetSpellTargetY().
 
Status
Not open for further replies.
Top