Making countdown timers MUI

Status
Not open for further replies.
Yea, try making a stack of objects to handle within 1 global timer which is paused and started (but never destroyed)

Here's an example from my contest submission:

JASS:
scope blast initializer i
    private struct kbDat
        unit pushee
        real degDirection
        integer power
    endstruct
    
    globals
        private constant integer BLASTID='A004'
        private unit tempCaster
        private timer time=CreateTimer()
        private integer dbIndex=-1
        private group grp=CreateGroup()
        private kbDat array kbDB
    endglobals
    
    private function p takes nothing returns nothing
        local integer index=0
        local kbDat tempDat
        local real x
        local real y
        loop
            exitwhen index>dbIndex
            set tempDat=kbDB[index]
            set x=GetUnitX(tempDat.pushee)+tempDat.power*Cos(tempDat.degDirection*bj_DEGTORAD)
            set y=GetUnitY(tempDat.pushee)+tempDat.power*Sin(tempDat.degDirection*bj_DEGTORAD)
            if IsTerrainWalkable(x,y) then
                call SetUnitX(tempDat.pushee,x)
                call SetUnitY(tempDat.pushee,y)
            else
                set tempDat.power=1
            endif
            set tempDat.power=tempDat.power-1
            if tempDat.power<1 then
                call tempDat.destroy()
                set kbDB[index]=kbDB[dbIndex]
                set dbIndex=dbIndex-1
                if dbIndex==-1 then
                    call PauseTimer(time)
                endif
            endif
            set index=index+1
        endloop
    endfunction

    private function f takes nothing returns boolean
        local kbDat tempDat
        if IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(tempCaster)) then
            set tempDat=kbDat.create()
            set tempDat.pushee=GetFilterUnit()
            set tempDat.degDirection=bj_RADTODEG*Atan2(GetUnitY(GetFilterUnit())-GetUnitY(tempCaster),GetUnitX(GetFilterUnit())-GetUnitX(tempCaster))
            set tempDat.power=20
            set dbIndex=dbIndex+1
            set kbDB[dbIndex]=tempDat
            if dbIndex==0 then
                call TimerStart(time,.03,true,function p)
            endif
        endif
        return false
    endfunction
    
    private function c takes nothing returns boolean
        if GetSpellAbilityId()==BLASTID then
            set tempCaster=GetSpellAbilityUnit()
            call GroupEnumUnitsInRange(grp,GetUnitX(GetSpellAbilityUnit()),GetUnitY(GetSpellAbilityUnit()),500,Filter(function f))
        endif
        return false
    endfunction
    
    private function i takes nothing returns nothing
        local trigger t=CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t,Condition(function c))
    endfunction
endscope
 
Tiche3, since I know you mostly use GUI and Cokemonkey11's way might be too advanced for you, your easiest solutions are:

• If you are working with low value timers, create a dummy unit and give it an expiration timer. Attach every value the dummy unit should have via hashtables. Example:
  • Trigger
  • Events
    • Map Initialization
  • Conditions
  • Actions
    • Hashtable - Create a hashtable
    • Set Hashtable = (Last created hashtable)
  • Trigger1
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
  • Actions
    • Set Point1 = (Position of (Triggering unit))
    • Unit - Create 1 dummytimer for (Owner of (Triggering unit)) at Point1 facing default building degrees
    • Hashtable - Save 900.00 as (Key(life)) of (Key(Last created unit)) in Hashtable //Hashtable - Save Real
    • Hashtable - Save Handle of (Triggering unit) as (Key(caster)) of (Key(Last created unit)) in Hashtable //Hashtable - Save Unit
    • Unit - Add a 2.00 seconds generic expiration timer to (Last created unit)
    • Custom script: call RemoveLocation (udg_Point1)
  • Trigger2
  • Events
    • Unit - A unit dies
  • Conditions
    • (Unit-type of (Triggering unit)) Equal to dummytimer
  • Actions
    • Set Unit1 = (Load (Key(caster)) of (Key(Triggering unit)) in Hashtable)
    • Set Real1 = (Load (Key(life)) of (Key(Triggering unit)) in Hashtable)
    • Unit - Set life of Unit1 to ((Life of Unit1) + Real1)
    • Hashtable - Clear all child hashtables of (Key(Triggering unit)) from Hashtable
This will restore 900.00 hp after 2.00 seconds.

• If you are working with higher values, e.g. 14 seconds, you can use a periodic event that substracts value.
  • Trigger1
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
  • Actions
    • Unit Group - Add (Triggering unit) to TempGroup
    • Hashtable - Save 14 as (Key(timer)) of (Key(Triggering unit)) in Hashtable //Hashtable - Save Integer
    • Trigger - Turn on Trigger2 <gen>
  • Trigger2
  • Events
    • Time - Every 1.00 seconds of game-time
  • Conditions
  • Actions
    • If (All conditions are true) then do (Actions) else do (Actions)
      • If - Conditions
        • (TempGroup is empty) Equal to True
      • Then - Actions
        • Trigger - Turn off (This trigger)
      • Else - Actions
        • Unit Group - Pick every unit in TempGroup and do (Actions)
          • Loop - Actions
            • Set Integer = (Load (Key(timer)) of (Key(Picked unit)) from Hashtable)
            • If (All conditions are true) then do (Actions) else do (Actions
              • If - Conditions
                • Integer Not Equal to 0
              • Then - Actions
                • Hashtable - Save (Integer - 1) as (Key(timer)) of (Key(Picked unit)) in Hashtable
                • Unit - Set life of (Picked unit) to (((Life of (Picked unit)) + 20.00)
              • Else - Actions
                • Unit Group - Remove (Picked unit) from TempGroup
                • Hashtable - Clear all child hashtables of (Key(Picked unit)) from Hashtable
This one will add 20.00 life to your unit every second, for 14 seconds.

Disclaimer: The methods mentioned are not better than the solution proposed by Cokemonkey11 and king_drift_alex, it's just the easiest way for someone that uses GUI.
 
Hmm thanks guys, but it's kind of for my hero reviving countdown timers. :) Tell me if you have another way please, because the ones you wrote is for abilities and using groups or so, i don't really get Htables (and believe me i read tuts).
So yeah, i'll be waiting for further answers :)

Tiche3:grin:
 
Could you show us the code you used please? I'd rather explain to you what's wrong with yours and how to fix it than make it for you.

Okay.

  • Hero Revive
    • Events:
      • Unit - A unit Dies
    • Conditions:
      • (Triggering Unit) is A Hero
    • Actions:
      • If (All conditions) are True then (Do actions) else (Do actions)
        • If - Conditions:
          • (Owner of (Triggering Unit)) is Player 2 (Blue)
        • Then - Actions:
          • Countdown Timer - Start Hero_Timer[1] as a One Shot timer that expires in (Real(Level of (Triggering Unit))x2)
          • Countdown Timer - Hide (Last Created Countdown Timer)
          • Countdown Timer - Show (Last Created Countdown Timer) to (Owner of (Triggering Unit))
          • Wait - Wait (Real(Level of (Triggering Unit))x2) seconds
          • Set Revive_Pos[1]=(Position of (Circles[1]))
          • Hero - Revive (Triggering Unit) instantly at Revive_Pos[1] Show revival graphics
          • Countdown Timer - Destroy (Last Created Countdown Timer)
          • Custom script: call RemoveLocation(udg_Revive_Pos[1])
And on else i do the same with every player.

Hope for answers ;p:grin:
 
Status
Not open for further replies.
Back
Top