• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Units Standing for X amount of time

Status
Not open for further replies.
Level 6
Joined
Nov 1, 2015
Messages
62
I have had an idea for an ability that would trigger after (for example) 10 seconds a unit has been idle (from the point it was issued the order "stop")
it would do something (like kill the unit, give the player gold or something)

I haven't found anywhere on google a way how to set individual unit's timers and so I have to ask here if anyone has any ideas?
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Seems pretty difficult to me, since you can't (for example) just check for the time since the last order issued to a unit. If I order a footman to attack a group of 2 low-health grunts, when it kills the grunt it will switch targets to the second... but no issue was ordered for it to do so. You could instead also track when a unit hasn't dealt damage or been damaged with a Damage Detection System, and as long as its moving, but ultimately you're going to have to do something like:
  • Whenever a unit 'does' something (however you judge that, since it's more complicated than just catching orders), store the current game under the unit's Handle ID in a hashtable (overwriting the last saved value, if any)
  • Every 0.25 or 0.5 seconds, loop through all units on the map. Load the time they last did something from the hashtable and compare it to the current game time; if > 10.00 seconds then do whatever you want with it.
  • Every time a unit dies or is removed from the game, clear its entry from the hashtable (to avoid memory building up over time)
tl;dr IMO this is not easy.
 
Level 6
Joined
Nov 1, 2015
Messages
62
Thx for the quick reply, I was thinking about those Multi-instanced spells, where complicated code happens for multiple units at once
Can't you set these multiple timers to multiple units? I don't really know how it would work like that,
but I wanted to avoid loops, as it is intended to be used for many units (30-40 per map) and that would maybe lag wouldn't it?
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
It is not a good idea to make a timer for each unit on the map. Allocating mass timers is general speaking advised against, and having a shitton simultaneously running is also not good practice when you could do the same with less overhead. You can achieve the same functionality by having 1 low-timeout (< 1 second) timer and checking every unit in a group (or every unit on the map) and update whichever ones are necessary. This is how pretty much any time-dependent triggered spell works.

Imagine your timer runs ever 0.10 seconds. Every time it updates the "duration since last action" for each unit by increasing it by 0.10 (the time since the timer last ran) and resaving the value in a hashtable. If the new value is > 10.00 then do whatever you need to do.
 
Level 6
Joined
Nov 1, 2015
Messages
62
i've never worked with hashtables, but if theres no other way i'll do it with them,
one last idea though; would it be too laggy to create a group every 0.1 seconds from all the units that have this ability, instead of hashtables set their custom values ++1 and then check/erase their status if their order changed or they reached 100 custom value (seconds)?
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
That would work fine as long as you don't have to use CV for anything else in your map. Many triggered spells depend on a Unit Indexer which co-opts the Custom Value of units to index them. In fact you probably can keep the group between iterations of the trigger so you don't have to repopulate it every time. Keep in mind, though, that storing how long the units have been inactive for is far less complicated than detecting when the units become inactive.
 
Level 12
Joined
May 22, 2015
Messages
1,051
I did something like this for one hero ability called "meditate". It basically checks if the unit is in the same spot (compares X and Y coordinates) it was last time it checked every tenth of a second. If it is the same, it increments a counter. If the number was above a certain amount, it would activate the ability which was just some mana and health regeneration. If the unit attacked or casted a spell, it set the counter back to 0 and set the stored coordinates to -99999, -99999 (just anywhere not on the map will do). That way, it fully resets the counter.

Mine was not MUI but I made it before I knew JASS. It wouldn't be hard to make it MUI but it would be some work to put a system together that is as efficient as possible. It could potentially need to store a lot of data depending on what you're using it for.
 
Status
Not open for further replies.
Top