[Trigger] SOLVED - Triggered summon: Why is the owner of unit changing?

Level 11
Joined
Aug 24, 2022
Messages
430
Hello once more Hivers! I've came here now to ask for some advice.

I have an ability called "Call of the Tribes", that each 1.5 seconds, summons a group of trolls at random places inside a region. The spell is working fine, but, sometimes, the owner of the summoned units changes to another allied player. Mechanically, there is no problem, since my project is a teamplay game, but summoned units must be owned by the casting player. Below, I'll put the spell:

  • This trigger is the setup, when the player casts the spell:
  • Call of the Tribes
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Call of the Tribes (Tier 3)
    • Actions
      • Set VariableSet Temp_Player = (Owner of (Casting unit))
      • Set VariableSet Trapper_Ability_Level = (Level of (Ability being cast) for (Casting unit))
      • Sound - Play UltimateTrapper <gen>
      • Floating Text - Create floating text that reads ((Name of (Ability being cast)) + !) above (Triggering unit) with Z offset 0.00, using font size 12.00, color (100.00%, 100.00%, 0.00%), and 0.00% transparency
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Set the velocity of (Last created floating text) to 128.00 towards 90.00 degrees
      • Floating Text - Change the fading age of (Last created floating text) to 1.20 seconds
      • Floating Text - Change the lifespan of (Last created floating text) to 3.60 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of (Ability being cast) for (Casting unit)) Equal to 1
        • Then - Actions
          • Set VariableSet Trapper_Units[1] = Troll Warlord (1)
          • Set VariableSet Trapper_Units[2] = Troll Hunter (1)
          • Set VariableSet Trapper_Units[3] = Troll Priest (1)
          • Set VariableSet Trapper_Units[4] = Troll Sorcerer (1)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of (Ability being cast) for (Casting unit)) Equal to 2
            • Then - Actions
              • Set VariableSet Trapper_Units[1] = Troll Warlord (2)
              • Set VariableSet Trapper_Units[2] = Troll Hunter (2)
              • Set VariableSet Trapper_Units[3] = Troll Priest (2)
              • Set VariableSet Trapper_Units[4] = Troll Sorcerer (2)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of (Ability being cast) for (Casting unit)) Equal to 3
                • Then - Actions
                  • Set VariableSet Trapper_Units[1] = Troll Warlord (3)
                  • Set VariableSet Trapper_Units[2] = Troll Hunter (3)
                  • Set VariableSet Trapper_Units[3] = Troll Priest (3)
                  • Set VariableSet Trapper_Units[4] = Troll Sorcerer (3)
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Level of (Ability being cast) for (Casting unit)) Equal to 4
                    • Then - Actions
                      • Set VariableSet Trapper_Units[1] = Troll Warlord (4)
                      • Set VariableSet Trapper_Units[2] = Troll Hunter (4)
                      • Set VariableSet Trapper_Units[3] = Troll Priest (4)
                      • Set VariableSet Trapper_Units[4] = Troll Sorcerer (4)
                    • Else - Actions
      • Trigger - Turn on Trapper Summons <gen>

  • This trigger is the looped effect, that occurs every 1.5 seconds:
  • Trapper Summons
    • Events
      • Time - Every 1.50 seconds of game time
    • Conditions
    • Actions
      • Set VariableSet Trapper_Counter = (Trapper_Counter + 1)
      • Set VariableSet Temp_Spell_Location = (Random point in Player Arena Spawn <gen>)
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Unit - Create (Random integer number between 1 and Trapper_Ability_Level) Trapper_Units[(Integer A)] for Temp_Player at Temp_Spell_Location facing Default building facing degrees
          • Special Effect - Create a special effect at Temp_Spell_Location using Flamestrike Dark Void I.mdx
          • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation( udg_Temp_Spell_Location )
      • Trigger - Run Summon Condition <gen> (checking conditions)

  • And this one is the condition to make the loop stop, and turn off the looping trigger:
  • Summon Condition
    • Events
    • Conditions
      • Trapper_Counter Equal to 5
    • Actions
      • Set VariableSet Trapper_Counter = 0
      • Trigger - Turn off Trapper Summons <gen>

I don't know what is happening, since I think that when we define the casting player via "Temp_Player", it can track who is the owner of the summoned units. Maybe the logic of the spell is wrong and I've just missplaced something, or something is missing here... I don't know. What I've checked so far:

  • Temp_Player was only used by the troll hero, on all noticed times that units changed their owner;
  • The spell is unique, so there is no chance that it can be casted twice, since the hero that have this spell is unique, as well all other abilities in the project;
  • Temp_Spell_Location is only being used in this trigger, nowhere else;

And another small question for you who is reading: I'm noticing that my project is getting a certain number of triggered spells using "Temp_Location", "Temp_Point", and so on. Is it good to change these temporary variables into arrays (6 in total), and set them via "Triggering Player"? I think this will prevent some bugs to occur, when two or more players cast spells that use these temporary variables.

Curiosity: "Why didn't you use Dark Portal casted by dummies instead of this trigger?" Because the idea behind this spell, is to create groups that can self-sustain themselves. With the trigger, I can set a minimum of 1 unit of each type (4 types total), not possible with the standard Dark Portal, that summon the units from the list randomly.
 
Level 11
Joined
Aug 24, 2022
Messages
430
While I was writing this post, I've ocassionally found the problem. Both Invoker and Death Knight (Heroes that got the summoned trolls), use an "Auto-Select" trigger for summoned units, like this one:

  • Auto Select Death Jailor T3
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
      • (Unit-type of (Summoning unit)) Equal to Death Knight - |cffff0000Rank 3|r
    • Actions
      • Set VariableSet Temp_Player = (Owner of (Summoning unit))
      • Set VariableSet Temp_Group = (Units owned by Temp_Player matching (((Unit-type of (Matching unit)) Equal to Death Jailor (5)) or (((Unit-type of (Matching unit)) Equal to Death Jailor (6)) or (((Unit-type of (Matching unit)) Equal to Death Jailor (7)) or ((Unit-type of (Matching unit)) E
      • Unit Group - Pick every unit in Temp_Group and do (Selection - Add (Picked unit) to selection for Temp_Player)
      • Custom script: call DestroyGroup(udg_Temp_Group)

Seeing this trigger, we see that Temp_Player can be changed while "Call of the Tribes" is still active, and following the logic, summoned trolls after this change, change their owner.

To prevent this to happen again, I ask again: Is it good to change temporary variables into arrays, so they can be set up for each player?
 
Level 25
Joined
Mar 29, 2020
Messages
1,466
you are periodically using "TempPlayer" in the trapper summons trigger, however you do not define this variable in the periodic trigger but only in the "call of the tribes setup".

this is a global variable, and is overwritten as soon as "call of the tribes setup" is cast again by anyone else.
 
Level 11
Joined
Aug 24, 2022
Messages
430
you are periodically using "TempPlayer" in the trapper summons trigger, however you do not define this variable in the periodic trigger but only in the "call of the tribes setup".

this is a global variable, and is overwritten as soon as "call of the tribes setup" is cast again by anyone else.
I've found that the same variable is being used for that auto-select summon, and that's what caused the issue. Also, studying more about the problem and seeing some posts here at Hive, I've discovered more interesting things, like TempVariables with array, and the custom script to remove then:

  • Custom script: call RemoveLocation( udg_Temp_Location_TEST[GetConvertedPlayerId(GetTriggerPlayer())] )
Thank you for you help. I'm now searching for global variables inside the project, and checking if strange things like that can happen again with another variable.
 
Level 25
Joined
Mar 29, 2020
Messages
1,466
Thank you for you help. I'm now searching for global variables inside the project, and checking if strange things like that can happen again with another variable.
it's not strange things .Once you get how global variables work it will make perfect sense. I will elaborate here at the risk of explaining things that are obvious to you (If that is the case please don't take offense...).

lets say you define a global variable - for example "ImportantPlayer" - when a spell is cast.

Then you have a periodic trigger which gives "ImportantPlayer" 100 gold every second that passes that is turned on by the previous trigger. lets say this has an integer counter, and turns itself off after it runs 10 times.

Lets say the red player cast the spell. If in those 10 seconds, nothing changes the variable "ImportantPlayer", then all will work as it should, and that player will get 1000 gold over 10 seconds.

That will not be the case however, if after 4 seconds (just an example) the blue player also casts that spell. now the variable "ImportantPlayer" will be pointing to the blue player. the red player will have only gotten 400 gold, and no more. but the blue player will also only get the remaining 6 tics of gold until the counter reaches 10 and turns off the periodic trigger.

this is an elaborate example of the "funny behaviour" that could happen by misusing global variables.

I hope this was helpful.
 
Level 11
Joined
Aug 24, 2022
Messages
430
it's not strange things .Once you get how global variables work it will make perfect sense. I will elaborate here at the risk of explaining things that are obvious to you (If that is the case please don't take offense...).

lets say you define a global variable - for example "ImportantPlayer" - when a spell is cast.

Then you have a periodic trigger which gives "ImportantPlayer" 100 gold every second that passes that is turned on by the previous trigger. lets say this has an integer counter, and turns itself off after it runs 10 times.

Lets say the red player cast the spell. If in those 10 seconds, nothing changes the variable "ImportantPlayer", then all will work as it should, and that player will get 1000 gold over 10 seconds.

That will not be the case however, if after 4 seconds (just an example) the blue player also casts that spell. now the variable "ImportantPlayer" will be pointing to the blue player. the red player will have only gotten 400 gold, and no more. but the blue player will also only get the remaining 6 tics of gold until the counter reaches 10 and turns off the periodic trigger.

this is an elaborate example of the "funny behaviour" that could happen by misusing global variables.

I hope this was helpful.
Your explanation is exactly what I’ve thought here. I’ve noticed other issues related with other spells (using Temp_Location), and noticed that they are only occurring because all of them are using the called “Global Variable” (that now I know what it is).

For example, I have a hero that have a dummy that casts Rain of Chaos. Another hero casted another spell that also uses the Temp_Location, and the 1st dummy couldn’t cast Rain of Chaos (out of cast range). The principle is the same and now I have path to fix these things.

I didn’t take offense… Knowledge is always welcome wherever it comes.
 
Top