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

Trigger not always working.

Status
Not open for further replies.

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Hello, Hive.

I need help with a trigger. I have a building which has the following ability:
"Whenever a unit dies, there will be 20% chance for it to resurrect after a 2 seconds delay. This effect stacks once."
So if I have 2 of this building, the chance goes to 40%. Now, here is the issue; sometimes it works/sometimes it doesn't. I don't really know why and at what pattern it works/does not work. Posting trigger below, with few explanations:
-GoldShrines_Group[1] counts all buildings with the ability. Upon being created, the buildings are added in the group in another trigger.
-This trigger works for Players 1-4.
-Only a few units in the game have the "Legendary" ability, which you can see in the conditions of the trigger. That's not the issue here.
[trigger=""]Golden Shrine Red
Events
Unit - A unit Dies
Conditions
(Player number of (Owner of (Triggering unit))) Less than 5
((Triggering unit) is A structure) Equal to False
(Max life of (Triggering unit)) Greater than 5.00
(Level of Legendary for (Triggering unit)) Equal to 0
Actions
Set GoldenShrine_Unit = (Triggering unit)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Equal to 1
Then - Actions
Set GoldenShrineRed_Chance = 20.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Greater than or equal to 2
Then - Actions
Set GoldenShrineRed_Chance = 40.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random real number between 0.00 and 100.00) Less than or equal to GoldenShrineRed_Chance
Then - Actions
Set GoldenShrinesRed_Point = (Position of GoldenShrine_Unit)
Wait 2.00 game-time seconds
Special Effect - Create a special effect at GoldenShrinesRed_Point using Abilities\Spells\Human\Resurrect\ResurrectTarget.mdl
Special Effect - Destroy (Last created special effect)
Unit - Remove GoldenShrine_Unit from the game
Unit - Create 1 (Unit-type of GoldenShrine_Unit) for (Owner of GoldenShrine_Unit) at GoldenShrinesRed_Point facing Default building facing degrees
Custom script: call RemoveLocation (udg_GoldenShrinesRed_Point)
Else - Actions
[/trigger]
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Im not sure what it is, but here are two things:

1. You use Waits in combination with global variables. If your trigger fires again within those 2 seconds, your second execution overwrites the values from the first execution.

2. You remove "GoldenShrine_Unit" from the game, and after that you create a new unit with the type of "GoldenShrine_Unit". Im not sure, but maybe getting the type of a removed unit doesnt work properly.

If this is not the issue, what exactly isnt working? Are there no units at all which get revived, or do you think the chance is wrong?
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
You use Waits in combination with local variables. If your trigger fires again within those 2 seconds, your second execution overwrites the values from the first execution.
I've heard that <Triggering Unit> is local variable? Anyways, regardless of what I've heard, I did try making it local before and the issue was still there.
You remove "GoldenShrine_Unit" from the game, and after that you create a new unit with the type of "GoldenShrine_Unit". Im not sure, but maybe getting the type of a removed unit doesnt work properly.
That would explain the issue, but wouldn't Local Variable/Triggering Unit prevent it?
If this is not the issue, what exactly isnt working? Are there no units at all which get revived, or do you think the chance is wrong?
Sometimes units get ressurected properly, sometimes they don't. I don't think the problem lies within the chance. Oh, right, I forgot to mention something important. In the cases when it doesn't work, the Special Effect appears at the right point, but the unit does not get resurected.

EDIT: posting trigger with Local Variable.
[trigger=""]Golden Shrine Red
Events
Unit - A unit Dies
Conditions
(Player number of (Owner of (Triggering unit))) Less than 5
((Triggering unit) is A structure) Equal to False
(Max life of (Triggering unit)) Greater than 5.00
(Level of Legendary for (Triggering unit)) Equal to 0
Actions
Custom script: local unit udg_GoldenShrine_Unit
Set GoldenShrine_Unit = (Triggering unit)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Equal to 1
Then - Actions
Set GoldenShrineRed_Chance = 20.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Greater than or equal to 2
Then - Actions
Set GoldenShrineRed_Chance = 40.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random real number between 0.00 and 100.00) Less than or equal to GoldenShrineRed_Chance
Then - Actions
Set GoldenShrinesRed_Point = (Position of GoldenShrine_Unit)
Wait 2.00 game-time seconds
Special Effect - Create a special effect at GoldenShrinesRed_Point using Abilities\Spells\Human\Resurrect\ResurrectTarget.mdl
Special Effect - Destroy (Last created special effect)
Unit - Remove GoldenShrine_Unit from the game
Unit - Create 1 (Unit-type of GoldenShrine_Unit) for (Owner of GoldenShrine_Unit) at GoldenShrinesRed_Point facing Default building facing degrees
Custom script: call RemoveLocation (udg_GoldenShrinesRed_Point)
Else - Actions
Custom script: set udg_GoldenShrine_Unit = null
[/trigger]
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Triggering unit works like a local variable, no need to shadow it.

Store the unit typre into a (local) variable before removing the unit. Use the variable when creating the new unit. You might also want to use a local variable for the location.

Well, I get errors:
Type mismatch in assignment: set udg_GoldenShrine_Type = GetUnitTypeId(GetTriggerUnit())
Invalid argument type (unittype): set udg_GoldenShrine_Type = null

I assume "unittype" is the local variable for Unit Type?
[trigger=""]Golden Shrine Red
Events
Unit - A unit Dies
Conditions
(Player number of (Owner of (Triggering unit))) Less than 5
((Triggering unit) is A structure) Equal to False
(Max life of (Triggering unit)) Greater than 5.00
(Level of Legendary for (Triggering unit)) Equal to 0
Actions
Custom script: local unittype udg_GoldenShrine_Type
Custom script: local location udg_GoldenShrinesRed_Point
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Equal to 1
Then - Actions
Set GoldenShrineRed_Chance = 20.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Greater than or equal to 2
Then - Actions
Set GoldenShrineRed_Chance = 40.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random real number between 0.00 and 100.00) Less than or equal to GoldenShrineRed_Chance
Then - Actions
Set GoldenShrinesRed_Point = (Position of (Triggering unit))
Wait 2.00 game-time seconds
Special Effect - Create a special effect at GoldenShrinesRed_Point using Abilities\Spells\Human\Resurrect\ResurrectTarget.mdl
Special Effect - Destroy (Last created special effect)
Set GoldenShrine_Type = (Unit-type of (Triggering unit))
Unit - Remove (Triggering unit) from the game
Unit - Create 1 GoldenShrine_Type for (Owner of (Triggering unit)) at GoldenShrinesRed_Point facing Default building facing degrees
Custom script: set udg_GoldenShrine_Type = null
Custom script: call RemoveLocation (udg_GoldenShrinesRed_Point)
Else - Actions
Custom script: set udg_GoldenShrinesRed_Point = null
[/trigger]
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Store the unit typre into a (local) variable before removing the unit. Use the variable when creating the new unit. You might also want to use a local variable for the location.

No need to make it local, since you immediately use it a global works just fine.

Try this:
[trigger=""]Golden Shrine Red
Events
Unit - A unit Dies
Conditions
(Player number of (Owner of (Triggering unit))) Less than 5
((Triggering unit) is A structure) Equal to False
(Max life of (Triggering unit)) Greater than 5.00
(Level of Legendary for (Triggering unit)) Equal to 0
Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Equal to 1
Then - Actions
Set GoldenShrineRed_Chance = 20.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in GoldenShrines_Group[1]) Greater than or equal to 2
Then - Actions
Set GoldenShrineRed_Chance = 40.00
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random real number between 0.00 and 100.00) Less than or equal to GoldenShrineRed_Chance
Then - Actions
Wait 2.00 game-time seconds
Set GoldenShrinesRed_Point = (Position of (Triggering unit))
Special Effect - Create a special effect at GoldenShrinesRed_Point using Abilities\Spells\Human\Resurrect\ResurrectTarget.mdl
Special Effect - Destroy (Last created special effect)
Set GoldenShrine_Type = (Unit-type of (Triggering unit))
Unit - Remove (Triggering unit) from the game
Unit - Create 1 GoldenShrine_Type for (Owner of (Triggering unit)) at GoldenShrinesRed_Point facing Default building facing degrees
Custom script: set udg_GoldenShrine_Type = null
Custom script: call RemoveLocation (udg_GoldenShrinesRed_Point)
Else - Actions
[/trigger]
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
No need to make it local, since you immediately use it a global works just fine.

The point is to write good code. Code that is not prone to bugs and no unnecessary function calls.

Using triggering unit after a wait with death event can lead to the trigger misbehaving if the unit is removed from the game before the wait time expires.

Being removed from the game can happen either with a trigger or by death time and decay times expiring.
 

sentrywiz

S

sentrywiz

"Whenever a unit dies, there will be 20% chance for it to resurrect after a 2 seconds delay. This effect stacks once."
So if I have 2 of this building, the chance goes to 40%.

This effect stacks once, but if you have two buildings it goes to 40%?
Sorry mate, you just negated yourself in the same sentence xD

Anyway to your question - don't use waits. i'm sure you know this by now.

Not sure why you are setting the chance in the same trigger where you check it, since its a building i would be increasing/decreasing the chance when the building is constructed or placed or bought or whatever - and in this trigger, i'd check if its greater than 0, and then try with the random integer 1 to 100 less or equal than chance.

Why are you removing units from the game? they're dead anyways, so you might as well create a unit = unit type of dying unit. I feel your trigger is overtly complicated for no reason.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
This effect stacks once, but if you have two buildings it goes to 40%?
Sorry mate, you just negated yourself in the same sentence xD
I dont see what your problem is?
Does not stack = only one instance at the same time
Stacks once= up to two instances at the same time
Stacks twice= up to 3 instances at the same time
etc. you get the idea.

Or is it the 40%? Yea you could argue that a combination of two chances should be calculated as rolling a dice a second time. Then you get:
1.-(1.-0.2)*(1.-0.2) = 36% Chance
But thats subject to personal interpretation of how "stacking" is defined.

Anyway to your question - don't use waits. i'm sure you know this by now.
Waits are not always that bad. In this situation i dont see why he shouldnt use them.
The Thing is: in Jass you obviously would use timers, but in GUI they are a pain in the ass. So why bloat the GUI code when when Waits work too?
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
This effect stacks once, but if you have two buildings it goes to 40%?
Sorry mate, you just negated yourself in the same sentence xD
1 Building = 20%
2 Buildings = 20%+20% (They stack 1 time)
3 Buildings = 20%+20%+20% (They stack 2 times)
What's the problem again?
Or did you think that 1 stack = 0 stacks? *giggles*
Or is it the 40%? Yea you could argue that a combination of two chances should be calculated as rolling a dice a second time. Then you get:
1.-(1.-0.2)*(1.-0.2) = 36% Chance
But thats subject to personal interpretation of how "stacking" is defined.
Additive stacking. 20% + 20%, etc... :)
Anyway to your question - don't use waits. i'm sure you know this by now.
Coding is my worst part in WE. Always been, but I am managing. Most of the time everything that is trigger-related can be done in a better/more optimized way. But I know waits can cause lots of problems if used incorrectly. However, I am sure they aren't completely unusable and I believe we got them to work fine with Maker and muzzel here.
Not sure why you are setting the chance in the same trigger where you check it, since its a building i would be increasing/decreasing the chance when the building is constructed or placed or bought or whatever - and in this trigger, i'd check if its greater than 0, and then try with the random integer 1 to 100 less or equal than chance.
This seems more efficient for sure. But it doesn't help the problem, does it?
Why are you removing units from the game? they're dead anyways, so you might as well create a unit = unit type of dying unit. I feel your trigger is overtly complicated for no reason.
Because I want to simulate resurrection. You know, when you resurrect, your corpse doesn't remain there. By removing the unit, I remove the corpse, so it doesn't get reanimated by other skills in the game. I feel you think way too simple. That's not how you design a map.
Unit types are actually integers and GetUnitTypeId returns an integer.
So, how do I create <Unit Type> of dying unit, if it's an integer? >_>
 
Level 4
Joined
Jul 9, 2007
Messages
50
to avoid all this complicated stuff with storing the unit type (and also the owner), just create the new unit first then remove the old one like this:

Create 1 (Unit type of GoldenShrineUnit) for (Owner of .......
Remove GoldenShrineUnit from the game

this way the GoldenShrineUnit / triggering unit still exists and you can still get its unit type (and owner)
it won't look any different ingame
 
Status
Not open for further replies.
Top