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

IsUnitInRange bugs out when unit status change

Status
Not open for further replies.
Level 3
Joined
Jun 12, 2022
Messages
8
Hello!
This is my first post on Hive, hope I'm following the rule and not causing any problem.

Recently I'm figuring out how to make trigger radius range perfectly matches Object Editor.(Include collision)
And through some recommendation, IsUnitInRange does detect collision and work pretty well.
However, the solution seems to introduce another issue and maybe that's a native bug in editor?

Let's say I create a radius spell and in trigger, I select all units in range and check with IsUnitInRange then deal damage.
When the units in range(example: 3 units) gained or changed their status by the spell(Stun or slow)
The next time when I cast the same spell to these same 3 units, only 1 of them will be damaged.
Similar thing happens when the damage is supposed to kill all 3 units, instead, 1 died and it seems the trigger stops here and the other 2 survive.

Does anyone have similar experience?
It would be great if I can get perfect radius range and any solution is appreciated:xxd:
 
Level 39
Joined
Feb 27, 2007
Messages
4,994
Nobody here is clairvoyant; you need to upload your map or the relevant triggers to get any sort of real, reasonable feedback.

 
Hello!
This is my first post on Hive, hope I'm following the rule and not causing any problem.

Recently I'm figuring out how to make trigger radius range perfectly matches Object Editor.(Include collision)
And through some recommendation, IsUnitInRange does detect collision and work pretty well.
However, the solution seems to introduce another issue and maybe that's a native bug in editor?

Let's say I create a radius spell and in trigger, I select all units in range and check with IsUnitInRange then deal damage.
When the units in range(example: 3 units) gained or changed their status by the spell(Stun or slow)
The next time when I cast the same spell to these same 3 units, only 1 of them will be damaged.
Similar thing happens when the damage is supposed to kill all 3 units, instead, 1 died and it seems the trigger stops here and the other 2 survive.

Does anyone have similar experience?
It would be great if I can get perfect radius range and any solution is appreciated:xxd:
Provide triggers or code, because it sounds like improperly set for some reason.
 
Level 3
Joined
Jun 12, 2022
Messages
8
Problem solved.
It was caused by another unit death event trigger cleared out location while the original trigger is dealing damage to group.
After the first unit died, location got cleared so the rest of the group got lost.
I thought local variable should not be affected between triggers.
But it seems not the case when one event can trigger multiple triggers, I got to be more careful.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,514
Problem solved.
It was caused by another unit death event trigger cleared out location while the original trigger is dealing damage to group.
After the first unit died, location got cleared so the rest of the group got lost.
I thought local variable should not be affected between triggers.
But it seems not the case when one event can trigger multiple triggers, I got to be more careful.
If it's a local variable it wouldn't be affected between triggers, that's simply not possible. It's definitely a global variable or at least behaving like one.

But yeah, there are a few niche cases where a triggers won't create an instance of itself and get added to the queue. Instead the Actions of one trigger are inserted directly into the Actions of another trigger. The "A unit dies" Event is one case of this and I believe there's some more Events that suffer from it as well. What I tell GUI users to do is create variables that are used exclusively for each Event:
DiesPlayer
DiesUnit
DiesPoint
etc...

At the end of the day there are only so many Events that your map will be using so it's not too difficult to do this.
 
Level 3
Joined
Jun 12, 2022
Messages
8
If it's a local variable it wouldn't be affected between triggers, that's simply not possible. It's definitely a global variable or at least behaving like one.

But yeah, there are a few niche cases where a triggers won't create an instance of itself and get added to the queue. Instead the Actions of one trigger are inserted directly into the Actions of another trigger. The "A unit dies" Event is one case of this and I believe there's some more Events that suffer from it as well. What I tell GUI users to do is create variables that are used exclusively for each Event:
DiesPlayer
DiesUnit
DiesPoint
etc...

At the end of the day there are only so many Events that your map will be using so it's not too difficult to do this.
Yes, right. I used to think local variable would totally be safe between trigger and trigger.
I'm not really sure about setting point part, but the end vJass clearing point line "call RemoveLocation( udg_P1)" can definitely conflicts with other trigger in some special cases.

Take mine as an example:
A trigger
10% drop item at location where unit dies

B trigger
Using IsUnitInRange to deal damage to precise range unit

As you know range damage by trigger is usually done by selecting units in a certain range of a point, then deal damage individually by loop.
I think how WE handle trigger is like receiving order.
When the very first unit got killed in the loop, it triggers A trigger to clear the point.
And vJass "call RemoveLocation( udg_P1)" seems don't bother to nuke any P1 that currently is set regardless which trigger it is.
And that cause unfinished B trigger lost P1 point and unable to find the next unit.

Anyway, I ended up changing A trigger set point to global variable with individual array.
And the problem is 100% gone.
 
Level 39
Joined
Feb 27, 2007
Messages
4,994
But yeah, there are a few niche cases where a triggers won't create an instance of itself and get added to the queue. Instead the Actions of one trigger are inserted directly into the Actions of another trigger. The "A unit dies" Event is one case of this and I believe there's some more Events that suffer from it as well.
I tested and I cannot confirm this statement. The following two triggers print that the value of omgastring is properly still read as 'something' (globally) rather than 'nothing' (locally). The value 'something' is assigned at default in the variable editor:

  • Escape
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Custom script: local string udg_omgastring
      • Set VariableSet omgastring = nothing
      • Game - Display to (All players) the text: (Set to: + omgastring)
      • Unit - Kill (Random unit from (Units owned by Player 1 (Red).))
  • Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Cinematic - Ping minimap for (All players) at (Center of (Playable map area)) for 1.00 seconds
      • Game - Display to (All players) the text: (Value is: + omgastring)
If it worked as you claim, the second trigger's actions would be concatenated into the first's and it would inherit the local value of omgastring which is 'nothing'.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,514
I tested and I cannot confirm this statement. The following two triggers print that the value of omgastring is properly still read as 'something' (globally) rather than 'nothing' (locally). The value 'something' is assigned at default in the variable editor:

  • Escape
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Custom script: local string udg_omgastring
      • Set VariableSet omgastring = nothing
      • Game - Display to (All players) the text: (Set to: + omgastring)
      • Unit - Kill (Random unit from (Units owned by Player 1 (Red).))
  • Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Cinematic - Ping minimap for (All players) at (Center of (Playable map area)) for 1.00 seconds
      • Game - Display to (All players) the text: (Value is: + omgastring)
If it worked as you claim, the second trigger's actions would be concatenated into the first's and it would inherit the local value of omgastring which is 'nothing'.
Maybe my explanation was misleading but what I was trying to point out was this issue:
  • A
    • Events
      • Player - Player 1 (Red) types a chat message containing -test as An exact match
    • Actions
      • Set Variable SharedVariable = 1
      • Unit - Kill TestDummy
      • Game - Display to (All players) for 30.00 seconds the text: String(SharedVariable)
  • B
    • Events
      • Unit - A unit dies
    • Actions
      • Set Variable SharedVariable = 2
When you type -test you will end up with the Actions executing in this order which is the issue Ssin ran into:
  • Actions
    • Set Variable SharedVariable = 1
    • Unit - Kill TestDummy
    • Set Variable SharedVariable = 2
    • Game - Display to (All players) for 30.00 seconds the text: String(SharedVariable)
Most of the time this isn't the case though and the Trigger instance that was created from Trigger B will execute after the Actions of Trigger A have completed (if there's no Waits involved). At least this is my understanding of it.
 

Attachments

  • Demo.w3m
    17.5 KB · Views: 3
Level 39
Joined
Feb 27, 2007
Messages
4,994
I don’t understand why that behavior seems unexpected to you. It has been my intuition and understanding as long as I have worked with wc3 that firing the event of another trigger while within a different one always pauses the first trigger until the second triggered one has completed. Can you identify an example where that doesn’t happen?

That’s expected behavior to me. Wc3 is single-threaded. It almost couldn’t possibly run any other way.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,514
I don’t understand why that behavior seems unexpected to you. It has been my intuition and understanding as long as I have worked with wc3 that firing the event of another trigger while within a different one always pauses the first trigger until the second triggered one has completed. Can you identify an example where that doesn’t happen?

That’s expected behavior to me. Wc3 is single-threaded. It almost couldn’t possibly run any other way.
I'm trying to find the thread but I swear this issue has come up before where it was inconsistent. Maybe I'm just going crazy.
 
Status
Not open for further replies.
Top