• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Making countdown timers MUI

Status
Not open for further replies.

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,522
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.
 
Level 9
Joined
Jun 25, 2009
Messages
427
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:
 
Level 9
Joined
Jun 25, 2009
Messages
427
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.
Top