I have a trigger-driven skill on my map which involves checking all units of the triggering player.
It goes like this:
Paste #6348 is expired.
..for reasons beyond my understanding, this does *not* destroy all units like it's supposed to.
This trigger is called when the ability has completed being cast, and I have two different ways to cast this ability.
#1 One of the buildings have MyAbility, which I have given it via data editor. Players can use it after selecting that building, the natural way. (Only this building is assigned Psionic type)
#2 I have another trigger that orders that building to use MyAbility. This is a part of custom UI made with dialog boxes.
If the above code is triggered by #1 the code works seamlessly. The problem occurs when #2 triggers the code.
Often only 1 unit (and it is *not* a Psionic unit) is not destroyed, Sometimes none is left, all units are destroyed.
I can't think of any plausible causes of this behavior:/
Any help would be appreciated. Thanks for reading!
Have you tried running debug message tests to see what the trigger is "really" doing? For each possible action you have a different debug message and also another debug message for displaying variable before and after to see what happened.
I've made triggers before which I thought did one thing but did another.
I've done some testing and I've found perhaps one problem. In your repeat/switch-case part of the trigger, killing a unit does not remove it from the unitgroup, in which case the trigger may be reusing an already dead unit (closet unit to point). To fix it, create another unitgroup variable, copy the original unitgroup to the new variable, and use this new variable instead for the repeat/switch part, and after you kill the unit add a trigger to remove the unit from the new variable.
See if this solves the problem, otherwise I'll have to keep looking.
Alright, try to run heavy on debug messages and other debug output. Increase the interval from 0.125 to something like 2 seconds. Print the name of the unit currently checked. Maybe create a special effect on the unit currently checked. Maybe print the remaining amount of units in the group compared to the remaining runs of the loop at all times. Clarify, what exactly the loop does for each iteration.
At first glance, it looks okay to me, however there might be some interaction with the unit groups and dead units, which break your approach. You can also try to save all units in a separate unit array from the start, as well as the initial unit count. This way, you would make sure to avoid any possible interaction with the internal group cleanup functions. Or you could add a death time to the units, so they remain on the map and in the unit group for the duration and don't mess up the group while the loop is running (you would probably need a check for already dead units in this case).
@Kueken531: Go:) That's basically what I did. Recreated the framework trigger, debugged the hell out of it, and found dead units getting referenced again.
Im not exactly sure whats happening, i think the problem might be that depending on the death time of units they might remain in the loop for some time, causing them to be the closest unit to your point multiple times.
Since your loop just executes based on the amount of units, this can lead to units being skipped.
Try this (pseudo code)
unitgroup ug = ...
while(!UnitGroupIsEmpty()) {
unit u = closest unit..
<do stuff>
remove u from ug
kill u
}
I've done some testing and I've found perhaps one problem. In your repeat/switch-case part of the trigger, killing a unit does not remove it from the unitgroup, in which case the trigger may be reusing an already dead unit (closet unit to point)
That did the trick! I have just finished testing with 16 or more units for 100+ times, It's completely fixed.
Many thanks for advices and taking your time for fixing this problem:)
..One thing bugs me though. If the cause was duplicate referencing, why would it miss a unit -only- when the ability is casted *indirectly* via custom UI?
If I casted it directly this trigger does what it does, even without remove u from ug hack.
I have a trigger-driven skill on my map which involves checking all units of the triggering player.
It goes like this:
..for reasons beyond my understanding, this does *not* destroy all units like it's supposed to.
This trigger is called when the ability has completed being cast, and I have two different ways to cast this ability.
#1
One of the buildings have MyAbility, which I have given it via data editor. Players can use it after selecting that building, the natural way. (Only this building is assigned Psionic type)#2
I have another trigger that orders that building to use MyAbility. This is a part of custom UI made with dialog boxes.If the above code is triggered by #1 the code works seamlessly. The problem occurs when #2 triggers the code.
Often only 1 unit (and it is *not* a Psionic unit) is not destroyed, Sometimes none is left, all units are destroyed.
I can't think of any plausible causes of this behavior:/
Any help would be appreciated. Thanks for reading!
Please post the exact galaxy-code in here.
If your editor version isnt english, just view the raw script of the map and copy paste the relevant code (since this is always english).
Have you tried running debug message tests to see what the trigger is "really" doing? For each possible action you have a different debug message and also another debug message for displaying variable before and after to see what happened.
I've made triggers before which I thought did one thing but did another.
@Mille25: Go
I've replaced the post with raw script. Some of the variables got hashed though:/
@zandose: Go
Yes. From what I've tried, sometimes the loop runs 1 times less than it's actual parameters ( = number of units in 'fuel' group )
For instance if the # of 'fuel' units is 10 then sometimes the switch only executes 9 times.
@butterflo: Go
You said raw version, does that mean you made it in GUI? If so post that too. I'm not too good at reading raw/galaxy.
@zandose: Go
Attached. My Editor is not in English so I used 'View raw data' option.
I've done some testing and I've found perhaps one problem. In your repeat/switch-case part of the trigger, killing a unit does not remove it from the unitgroup, in which case the trigger may be reusing an already dead unit (closet unit to point). To fix it, create another unitgroup variable, copy the original unitgroup to the new variable, and use this new variable instead for the repeat/switch part, and after you kill the unit add a trigger to remove the unit from the new variable.
See if this solves the problem, otherwise I'll have to keep looking.
Alright, try to run heavy on debug messages and other debug output. Increase the interval from 0.125 to something like 2 seconds. Print the name of the unit currently checked. Maybe create a special effect on the unit currently checked. Maybe print the remaining amount of units in the group compared to the remaining runs of the loop at all times. Clarify, what exactly the loop does for each iteration.
At first glance, it looks okay to me, however there might be some interaction with the unit groups and dead units, which break your approach. You can also try to save all units in a separate unit array from the start, as well as the initial unit count. This way, you would make sure to avoid any possible interaction with the internal group cleanup functions. Or you could add a death time to the units, so they remain on the map and in the unit group for the duration and don't mess up the group while the loop is running (you would probably need a check for already dead units in this case).
@Kueken531: Go :) That's basically what I did. Recreated the framework trigger, debugged the hell out of it, and found dead units getting referenced again.
Im not exactly sure whats happening, i think the problem might be that depending on the death time of units they might remain in the loop for some time, causing them to be the closest unit to your point multiple times.
Since your loop just executes based on the amount of units, this can lead to units being skipped.
Try this (pseudo code)
unitgroup ug = ...
while(!UnitGroupIsEmpty()) {
unit u = closest unit..
<do stuff>
remove u from ug
kill u
}
This should definatly work.
That did the trick! I have just finished testing with 16 or more units for 100+ times, It's completely fixed. Many thanks for advices and taking your time for fixing this problem:)
..One thing bugs me though. If the cause was duplicate referencing, why would it miss a unit -only- when the ability is casted *indirectly* via custom UI? If I casted it directly this trigger does what it does, even without remove u from ug hack.
@butterflo: Go That message at the bottom is so small that I didn't even see it until checking back a day later.
I have no idea why it does what it does. if you really want to know debug each line of code.