• 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.

detecting spell readiness

Status
Not open for further replies.
Level 12
Joined
May 22, 2015
Messages
1,051
There is no built-in way. You would have to keep track of it using triggers (start a timer when the unit casts the spell). If you have cooldown resets, you would need to make sure all the cooldown variables are reset and the timers are destroyed.

This can be a huge pain if you have many units to keep track of, but it may not be a huge deal if it is just one ability on one hero.
 
Just a guess: when you order a unit to do something, it returns a boolean as to whether the order was successfully carried out. If there is some error or any reason that the unit wouldn't be able to complete the order (e.g. stunned, cooldown, invalid target, etc.) then the order will return "false". Note that this method will interrupt the unit's current order if successful.

Go to the object editor and look up the ability's order string field. There are three custom scripts to order the unit (you'll have to choose one based on whether it is a target/point/immediate order):
JASS:
native IssueImmediateOrder          takes unit whichUnit, string order returns boolean
native IssuePointOrder              takes unit whichUnit, string order, real x, real y returns boolean
native IssueTargetOrder             takes unit whichUnit, string order, widget targetWidget returns boolean

If you're not familiar with JASS, it may be a bit tough to use. But I'll give an example of a target order:
  • Set CooldownCaster = (Triggering unit)
  • Set CooldownTarget = <Some unit>
  • Custom script: set udg_OffCooldown = IssueTargetOrder(udg_CooldownCaster, "stormbolt", udg_CooldownTarget)
  • If (All Conditions are true) then do (Then Actions) Else do (Else actions)
    • If - Conditions
      • OffCooldown Equal to True
    • Then - Actions
      • Unit - Order CooldownCaster to Stop
    • Else - Actions
The above example uses three variables: CooldownCaster (unit), CooldownTarget (unit), and OffCooldown (boolean). The custom script line tests to see if the order was successful, and assigns the result to be stored in "OffCooldown". The if/then/else will check if the ability is off-cooldown. I ordered the unit to stop, but you can do whatever you'd like.
 
Level 8
Joined
Dec 10, 2006
Messages
67
Thank you for confirming what I already suspected to be true. Unfortunately, there are multiple units with multiple spells. I have an inelegant workaround involving Return Success conditions. Basically the unit has to determine potential targets and try to cast the spell with future actions determined by success or failure such as the possibility of attempting a different spell. I was hoping there was a way I could determine if the spell was ready before waisting time determining said targets. This is being done from within a perodic driven event. This also means that universal variables would be unreliable.
 
Level 12
Joined
May 22, 2015
Messages
1,051
You could probably do this with a hashtable and timers. I am not sure what you mean with all that targeting, but it sounds complicated.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,286
Unfortunately WC3 lacks the cooldown and charge natives that SC2 has.

As people said above you are pretty much forced to manually track ability readiness. This requires you to detect ability casts, have a table of ability cooldowns and store the timing information on a per-unit basis.

For mapping units to their data use hashtables. Parent is unit handle (remember to clear on death) and child the ability which you want to query. If there is no entry assume the ability is ready. If there is an entry the entry could be the expected time for when the ability is ready (allows planning for the future).

You need another hashtable to map the abilities to their cooldowns since WC3 does not have catalog natives to do this like SC2 has. Parent should be ability type ID and child some magic constant.

You also need a timed event queue. A timer then waits the timeout until the next event in the queue and process it. Events in the queue correspond to abilities being ready. Each event contains the unit and ability which has to be made ready. When an ability is ready you clear it from the hashtable for that unit.

When an ability starts to cooldown (after effect runs successfully) you then add an event to the timer queue (and start the timer if the queue was empty). Because the queue must be ordered I recommend a binary tree (eg an AVL tree) so that insertion and removal scales very well. You could use a simple ordered linked list (easy to implement) for better removal complexity but at the cost of worse insertion complexity. If you get a new head of the queue you need to adjust the timer timeout appropriately.

Other requirements such as resources (enough mana), tech and buffs require other systems to manage but are fairly straight forward to implement.
 
Level 8
Joined
Dec 10, 2006
Messages
67
You could probably do this with a hashtable and timers. I am not sure what you mean with all that targeting, but it sounds complicated.

Here's an example

If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current research level of Ranger Training - Level 2 for playerElves) Greater than or equal to 2

(Number of units in (Units within 500.00 of (Position of (Picked unit)) matching ((Evaluate MatchingUnit Living Hostile Organic Level 5Plus <gen> conditions) Equal to True))) Greater than or equal to minFoes_Ranger_Locust

(Successful: Order (Picked unit) to (Convert locustswarm to untargeted order)) Equal to True

Then - Actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in (Units within range_Ranger_Quillbeast of (Position of (Picked unit)) matching ((Evaluate MatchingUnit Living Hostile <gen> conditions) Equal to True))) Greater than or equal to minFoes_Ranger_Quillbeast

(Number of units in (Units owned by playerElves matching ((Evaluate MatchingUnit Ranger Living Quillbeast Minion <gen> conditions) Equal to True))) Equal to 0

(Successful: Order (Picked unit) to (Convert summonquillbeast to untargeted order)) Equal to True
Then - Actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in (Units within range_Ranger_Bear of (Position of (Picked unit)) matching ((Evaluate MatchingUnit Living Hostile Ground Unit <gen> conditions) Equal to True))) Greater than or equal to minFoes_Ranger_Bear

(Number of units in (Units owned by playerElves matching ((Evaluate MatchingUnit Ranger Living Bear Minion <gen> conditions) Equal to True))) Equal to 0

(Successful: Order (Picked unit) to (Convert summongrizzly to untargeted order)) Equal to True
Then - Actions
Else - Actions
 
Status
Not open for further replies.
Top