• 🏆 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!

Basics - Timers

Status
Not open for further replies.
Level 2
Joined
Jul 12, 2018
Messages
17

Tasks

Code

Changes



Create a timer that fires a function "foo" after 2 seconds expired after map initialization.
In function "foo" the expired time must be printed on screen and the expired timer destroyed.


Following global variables must be declared and used (<type> , <name>):
  1. hashtable Hash
Create a unit on map initialization.
Create a timer on map initialiaztion.

The unit must be saved into hashtable, using the timer as ParentKey, which means that the used index must be directly related to the timer object itself.

The timer should periodicly (each second) call a function "DamageUnit", which goal is to retrieve the saved unit from hashatble, and to decrease it's life by "10".

In case the unit is dead, the timer must be destroyed.



JASS:
native UnitAlive takes unit whichUnit returns boolean
scope Part1n2 initializer init
    globals
        hashtable Hash = InitHashtable()
    endglobals
  
    private function foo takes nothing returns nothing
        local timer t = GetExpiredTimer()
      
        call BJDebugMsg(R2S(TimerGetElapsed(t)) + " second(s) elapsed")
        call DestroyTimer(t)
      
        set t = null
    endfunction
  
    private function DamageUnit takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local unit u = LoadUnitHandle(Hash, GetHandleId(t), 0)
      
        if UnitAlive(u) then
            call SetWidgetLife(u, GetWidgetLife(u) - 10)
        else
            call FlushChildHashtable(Hash, GetHandleId(t))
            call DestroyTimer(t)
        endif
      
        set t = null
        set u = null
    endfunction
    private function init takes nothing returns nothing
        local timer clock = CreateTimer()
        local timer dpsTimer = CreateTimer()
      
        call SaveUnitHandle(Hash, GetHandleId(dpsTimer), 0, CreateUnit(Player(0), 'hfoo', 0, 0, 0))
      
        call TimerStart(clock, 2, false, function foo)
        call TimerStart(dpsTimer, 1, true, function DamageUnit)
    endfunction
endscope



-submission


-now uses UnitAlive
-replaced any GetUnitState and SetUnitState with GetWidgetLife and SetWidgetLife

 

Attachments

  • [Crash Course] Basics - Timers.w3m
    23.9 KB · Views: 66
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
GetUnitState(u, UNIT_STATE_LIFE) > 0 is not the best way to check if a unit is alive/dead
A unit dies, if its hp is <= 0.405.
Using code (SetWidgetLife), you could change the hp of dead unit (corpse) to a positive value. Even though the unit is still dead, checking for its hit points will not tell you whether it is alive or not.
By the way using GetWdigetLife instead of GetUnitState(u, UNIT_STATE_LIFE) is better, because it is shorter to type and also executed faster.

There are two good ways to check whether a unit is alive/dead.
One is to use IsUnitType(u,UNIT_TYPE_DEAD). I think you used that one in the code for another crash course.
The best method is to use UnitAlive. It is a native defined in common.ai. You can use it, if you put
native UnitAlive takes unit whichUnit returns boolean in the code. It is the fastest method known.

Check out JASS Benchmarking Results if you are interested in how fast certain functions are.
 
Level 2
Joined
Jul 12, 2018
Messages
17
Noted

v1.1

-now uses UnitAlive
-replaced any GetUnitState and SetUnitState with GetWidgetLife and SetWidgetLife
 
Status
Not open for further replies.
Top