HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Changing timeout onthefly

03-02-2010, 01:48 PM#1
Saishy
I have a regen spell that regen faster if the unit is damaged, I'm currently releasing the timer and calling a new timer at each timeout, but is there a way to keep the current timer and change the timeout?


Edit: Can I make the boolean IsPeriodic False and them keep calling timerstart?
03-02-2010, 02:16 PM#2
Michael Peppers
Quote:
Originally Posted by Saishy
I have a regen spell that regen faster if the unit is damaged, I'm currently releasing the timer and calling a new timer at each timeout, but is there a way to keep the current timer and change the timeout?
As a test, I'd try to give the timeout a global variable and then change it, but I don't think it'll work, to be honest

Quote:
Originally Posted by Saishy
Edit: Can I make the boolean IsPeriodic False and them keep calling timerstart?
I'm a bit confused by this sentence, if you're thinking about a timer that goes in loop, calling TimerStart in the same function that is used for "code", yes, you can, but you'd have to find a way to stop that loop (for example if s.n != 0 then using an integer in a struct, getting it from and attaching it to the timer everytime, with a decreasing value) if you don't want the game to crash =)

I just hope I've not written a blob of words here.
03-02-2010, 02:50 PM#3
DioD
TimerStart(GetExpiredTimer(), TimerGetTimeOut - 0.01)

or something like that will work fine.
03-02-2010, 03:06 PM#4
moyack
Or work with a fixed, small timer period and just modify a rate.

Example

Periodic timer with a period of 0.05 seconds

If you set a regen of 10 hp/sec then every 0.05 will heal 10*0.05 hp = 0.5hp
30 hp/sec will heal 30*0.05 = 1.5hp and so on....
03-02-2010, 06:34 PM#5
Saishy
Quote:
Originally Posted by DioD
TimerStart(GetExpiredTimer(), TimerGetTimeOut - 0.01)

or something like that will work fine.
Are you considering a already running timer or a timer that have already stopped?

Well, I achieved this, is that right? The spell is supposed to regen 10% of his hp per level.
(Its working)

Collapse JASS:
scope YoukaiBlood initializer Init_Youkaiblood

globals
    private constant integer ID = 'A01C'
    private constant integer BUFF = 'B00U'
    private constant real COUNT = 15
    private constant real TIMER = 1.
endglobals

private struct Youkai_data
    unit caster
    integer level
    real regen_rate
    real regen_amount
    integer count
endstruct

function Youkaiblood_Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == ID)
endfunction

function Youkaiblood_Regen takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Youkai_data s = GetTimerData(t)
    local real hp = GetUnitState(s.caster, UNIT_STATE_LIFE)
    local real hpmax = GetUnitState(s.caster, UNIT_STATE_MAX_LIFE)
    set hp = hp + (hp * s.regen_amount)
    
    if hp > hpmax then
        set hp = hpmax
    endif
    
    call SetUnitState(s.caster, UNIT_STATE_LIFE, hp)
    
    set s.count = s.count + 1
    
    if (s.count == COUNT) then
        call UnitRemoveAbility(s.caster, BUFF)
        call ReleaseTimer(t)
        set s.caster = null
        call s.destroy()
    else
        set s.regen_rate = TIMER * (hp / hpmax)
        call TimerStart(t, s.regen_rate, false, function Youkaiblood_Regen)
    endif
endfunction

function Youkaiblood_Actions takes nothing returns nothing
    local Youkai_data s = Youkai_data.create()
    local timer t = NewTimer()
    set s.caster = GetTriggerUnit()
    set s.count = 0
    set s.level = GetUnitAbilityLevel(s.caster, ID)
    set s.regen_rate = TIMER * (GetUnitState(s.caster, UNIT_STATE_LIFE) / GetUnitState(s.caster, UNIT_STATE_MAX_LIFE))
    set s.regen_amount = (s.level * 0.1) / COUNT
    
    call SetTimerData(t, s)
    call TimerStart(t, s.regen_rate, false, function Youkaiblood_Regen)
endfunction

//===========================================================================
function Init_Youkaiblood takes nothing returns nothing
    local trigger trg_Youkaiblood = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(trg_Youkaiblood, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(trg_Youkaiblood, Condition(function Youkaiblood_Conditions))
    call TriggerAddAction(trg_Youkaiblood, function Youkaiblood_Actions )
    set trg_Youkaiblood = null
endfunction

endscope
03-02-2010, 07:00 PM#6
Michael Peppers
Nothing seems wrong as far as I can tell, disregard the sentences below.

The thing that seems off to me is:
Collapse JASS:
    else
        set s.regen_rate = TIMER * (hp / hpmax)
        call TimerStart(t, s.regen_rate, false, function Youkaiblood_Regen)
    endif
I think you'd have to add SetTimerData(t, s) before TimerStart(t, s.regen_rate, false, function Youkaiblood_Regen), because otherwise s.count in the timer won't be updated to the new value... but again, I'm totally unsure about this..., use some debug messages just to be sure.
03-02-2010, 09:44 PM#7
Ammorth
Structs are like units, in the way that if you set a unit to a variable, and then kill the unit, the variable will also show the unit being dead.

Once you attach a struct to something, you never have to again, even if you update values within the struct.
03-02-2010, 09:53 PM#8
Michael Peppers
Quote:
Originally Posted by Ammorth
Structs are like units, in the way that if you set a unit to a variable, and then kill the unit, the variable will also show the unit being dead.

Once you attach a struct to something, you never have to again, even if you update values within the struct.
I do have to learn a lot of things, it seems... thanks, I have to remove those SetTimerData thingamabobs in my map now.