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

Make opponents Allied when base is destroyed

Level 2
Joined
Mar 8, 2024
Messages
6
The overall thought of the map is to destroy the opponents bases and thereby adding them to your team. You win when all the opponents are on your team.

My goal is to make the owner of the dying unit (the players opponent) their ally.
I have succeded in doing so, but the owner of the dying unit remains allied to their previous allies.

I wonder if it is possible to the "forces" to add and remove people from different forces?
I am quite new to map making so i hope someone has an idea.
Skærmbillede 2024-03-08 111719.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,569
Hello, so you should introduce some more variables to ensure that the references in your trigger aren't lost. I also recommend using unique variables when dealing with the "A unit dies" Event since it breaks the trigger queue and runs immediately. You also forgot to account for the fact that the killing player can have allies as well, which the dying player will need to become allied with too.

I believe this should work:
  • Actions
    • Set KillingPlayer = (Owner of (Killing unit))
    • Set DyingPlayer = (Owner of (Triggering unit))
    • Set TakeoverLoc = (Position of (Triggering unit))
    • -------- --------
    • Unit - Remove (Triggering unit) from the game
    • Unit - Create 1 Base for DyingPlayer at TakeoverLoc facing Default building facing degrees
    • Custom script: call RemoveLocation( udg_TakeoverLoc )
    • -------- --------
    • -------- Leave the dying player's team: --------
    • Set TakeoverPG = (All allies of DyingPlayer)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Enemy)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Enemy)
    • Custom script: call DestroyForce( udg_TakeoverPG )
    • -------- --------
    • -------- Join the killing player's team: --------
    • Set TakeoverPG = (All allies of KillingPlayer)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
    • Custom script: call DestroyForce( udg_TakeoverPG )
Also, please use this in the future instead of uploading pictures of your triggers:
 
Last edited:
Level 2
Joined
Mar 8, 2024
Messages
6
I made it work with your code, thanks!
Never thought about using variables in that way but that opens up alot of new things to do.

I will also post my triggers in the correct way going forward.
Thank you Uncle!
 
Level 2
Joined
Mar 8, 2024
Messages
6
Hello, so you should introduce some more variables to ensure that the references in your trigger aren't lost. I also recommend using unique variables when dealing with the "A unit dies" Event since it breaks the trigger queue and runs immediately. You also forgot to account for the fact that the killing player can have allies as well, which the dying player will need to become allied with too.

I believe this should work:
  • Actions
    • Set KillingPlayer = (Owner of (Killing unit))
    • Set DyingPlayer = (Owner of (Triggering unit))
    • Set TakeoverLoc = (Position of (Triggering unit))
    • -------- --------
    • Unit - Remove (Triggering unit) from the game
    • Unit - Create 1 Base for DyingPlayer at TakeoverLoc facing Default building facing degrees
    • Custom script: call RemoveLocation( udg_TakeoverLoc )
    • -------- --------
    • -------- Leave the dying player's team: --------
    • Set TakeoverPG = (All allies of DyingPlayer)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Enemy)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Enemy)
    • Custom script: call DestroyForce( udg_TakeoverPG )
    • -------- --------
    • -------- Join the killing player's team: --------
    • Set TakeoverPG = (All allies of KillingPlayer)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
    • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
    • Custom script: call DestroyForce( udg_TakeoverPG )
Also, please use this in the future instead of uploading pictures of your triggers:

Any chance you want to help me set up the victory condition?
I want the player who has made all the other players a part of their team to win.
I have been looking through the different kinds of triggers and browsed the forums for any help, but unfortunately i cant seem to figure it out.
If its not possible, it would sufficient to make all the allied players win togehter, as long as the game ends when there is no one left to fight.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,569
Any chance you want to help me set up the victory condition?
I want the player who has made all the other players a part of their team to win.
I have been looking through the different kinds of triggers and browsed the forums for any help, but unfortunately i cant seem to figure it out.
If its not possible, it would sufficient to make all the allied players win togehter, as long as the game ends when there is no one left to fight.
It's not too difficult.

To get the team "leader" of any team you can introduce a Player array variable. The [index] of this array will be set to a player's Player Number, allowing it to store a unique value for each Player. Let's set this up at the start of the game and by default each Player will act as their own team leader:
  • Game Start
    • Events
      • Game - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Set TakeoverTeamLeader[(Player number of (Picked player))] = (Picked player))
Then modify the previous Takeover trigger to also do a Player count comparison to see if someone has taken over everyone else:
  • -------- Join the killing player's team: --------
  • Set TakeoverTeamLeader[(Player number of DyingPlayer)] = TakeoverTeamLeader[(Player number of KillingPlayer)]
  • Set TakeoverPG = (All allies of KillingPlayer)
  • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
  • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
  • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • TakeoverTotalAllies Greater than or equal to (Number of players in (All players))
    • Then - Actions
      • Trigger - Run Game Over (ignoring conditions)
    • Else - Actions
  • Custom script: call DestroyForce( udg_TakeoverPG )
Lastly, we introduce the Game Over trigger which runs once a TakeoverPG contains every Player.
WinningPlayer is who won the game, everyone else lost, and you can make them all win/lose by referencing every player inside of TakeoverPG:
  • Game Over
    • Events
    • Conditions
    • Actions
      • Set WinningPlayer = TakeoverTeamLeader[(Player number of KillingPlayer)]
      • -------- Run Victory for WinningPlayer and then run Defeat for everyone else --------
Note that (All players) will include pretty much everyone so you'll want to modify it to fit your maps needs. Basically, make sure it only references players that can actually be taken over.
 
Last edited:
Level 2
Joined
Mar 8, 2024
Messages
6
It's not too difficult.

To get the team "leader" of any team you can introduce a Player array variable. The [index] of this array will be set to a player's Player Number, allowing it to store a unique value for each Player. Let's set this up at the start of the game and by default each Player will act as their own team leader:
  • Game Start
    • Events
      • Game - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Set TakeoverTeamLeader[(Player number of (Picked player))] = (Picked player))
Then modify the previous Takeover trigger to also do a Player count comparison to see if someone has taken over everyone else:
  • -------- Join the killing player's team: --------
  • Set TakeoverTeamLeader[(Player number of DyingPlayer)] = TakeoverTeamLeader[(Player number of KillingPlayer)]
  • Set TakeoverPG = (All allies of KillingPlayer)
  • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
  • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
  • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • TakeoverTotalAllies Greater than or equal to (Number of players in (All players))
    • Then - Actions
      • Trigger - Run Game Over (ignoring conditions)
    • Else - Actions
  • Custom script: call DestroyForce( udg_TakeoverPG )
Lastly, we introduce the Game Over trigger which runs once a TakeoverPG contains every Player.
WinningPlayer is who won the game, everyone else lost, and you can make them all win/lose by referencing every player inside of TakeoverPG:
  • Game Over
    • Events
    • Conditions
    • Actions
      • Set WinningPlayer = TakeoverTeamLeader[(Player number of KillingPlayer)]
      • -------- Run Victory for WinningPlayer and then run Defeat for everyone else --------
Note that (All players) will include pretty much everyone so you'll want to modify it to fit your maps needs. Basically, make sure it only references players that can actually be taken over.
Thank you for your reply. Its amazing that you want to help me!

However, have been trying your ideas but i cant seem to make it work. I think im having trouble with making the individual players win. As it is right now when i take over one opponent i win the game even though there are opponents left who are not my allies.

  • Player Array
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Set TakeoverTeamLeader[(Player number of (Picked player))] = (Picked player))
  • Player Takeover
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Base
    • Actions
      • Set TakeoverLoc = (Position of (Triggering unit))
      • Set KillingPlayer = (Owner of (Killing unit))
      • Set DyingPlayer = (Owner of (Dying unit))
      • Unit - Remove (Triggering unit) from the game
      • Unit - Create 1 Base for DyingPlayer at TakeoverLoc facing Default building facing degrees
      • Custom script: call RemoveLocation( udg_TakeoverLoc )
      • -------- Leave Dying Players Team --------
      • Set TakeoverPG = (All allies of DyingPlayer)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Enemy)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Enemy)
      • Custom script: call DestroyForce( udg_TakeoverPG )
      • -------- Join killing players team --------
      • Set TakeoverTeamLeader[(Player number of DyingPlayer)] = TakeoverTeamLeader[(Player number of KillingPlayer)]
      • Set TakeoverPG = (All allies of KillingPlayer)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
      • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TakeoverTotalAllies Greater than or equal to (Number of players in (All players))
        • Then - Actions
          • Trigger - Run Game Over <gen> (ignoring conditions)
        • Else - Actions
      • Custom script: call DestroyForce( udg_TakeoverPG )
I think im doing something wrogn with my Game Over triggers.

  • Game Over
    • Events
    • Conditions
    • Actions
      • Set WinPlayer = TakeoverTeamLeader[(Player number of DyingPlayer)]
      • Player Group - Pick every player in TakeoverPG and do (Game - Victory (Picked player) (Show dialogs, Show scores))
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,569
1) To clarify on what I said before, (All players) may not actually reference the players you desire:
make sure it only references players that can actually be taken over.
So make sure you're actually getting a reference to everyone you want, Computers included if they can be taken over. I was under the impression that (All players) contained Users/CPUs by default but perhaps you have to include Computers manually. You can always display a text message of the name of each Player in (All players) to see who is actually being considered.

2) Your Game Over trigger isn't using the WinPlayer variable. You're simply winning the game for everyone in TakeoverPG. Remember, the last time we set the TakeoverPG variable it was set to (All allies of KillingPlayer). The DyingPlayer was NOT an ally of the KillingPlayer at that time so it will not be included. Variables don't automatically change, they contain whatever data you give them at that exact moment and retain that specific information forever.
 
Last edited:
Level 2
Joined
Mar 8, 2024
Messages
6
Thank you so much for all your help, but I'm afraid I'm unable to make it work. I've been trying, and I'm starting to get frustrated. I think I'll just ignore the winning condition, and then people will simply have to leave when they're all on the same team. I believe my knowledge of programming and variables isn't sufficient to make it work. Perhaps one day I will return to it.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,569
Thank you so much for all your help, but I'm afraid I'm unable to make it work. I've been trying, and I'm starting to get frustrated. I think I'll just ignore the winning condition, and then people will simply have to leave when they're all on the same team. I believe my knowledge of programming and variables isn't sufficient to make it work. Perhaps one day I will return to it.
Did you ever confirm if (All players) actually contains "all players"? Because that's very closely related to your issue:
As it is right now when i take over one opponent i win the game even though there are opponents left who are not my allies.
And we know that this is the part of the trigger that causes that issue:
  • -------- Join the killing player's team: --------
  • Set TakeoverPG = (All allies of KillingPlayer)
  • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • TakeoverTotalAllies Greater than or equal to (Number of players in (All players))
    • Then - Actions
      • Trigger - Run Game Over (ignoring conditions)
    • Else - Actions
We know that TakeoverTotalAllies has to be >= the total number of players in order for the Game Over trigger to run. So that tells us that when you takeover the first opponent either TakeoverTotalAllies is set to the wrong value, (Number of players in (All players)) is getting the wrong value, or both are wrong. My theory is that (All players) doesn't actually contain all of your Computer players, so it's value is way less than it should be. The solution here is very simple, use a Player Group that does contain ALL of the players.

This can be done in multiple ways but I think this new trigger and new Player Group variable would work best:
  • Events
    • Game - Elapsed game time is 0.01 seconds
  • Conditions
  • Actions
    • Set AllPlayersPG = (All players)
    • -------- Now manually add your Computer players --------
    • Player Group - Add Player 1 (Red) to AllPlayersPG
    • Player Group - Add Player 2 (Blue) to AllPlayersPG
    • Player Group - Add Player 3 (Teal) to AllPlayersPG
AllPlayersPG is a Player Group variable that you setup at the start of the game and fill with "all players". You can then manually add your Computer players to it if need be. You can then replace (All players) with it, hopefully getting rid of the issue:
  • If - Conditions
    • TakeoverTotalAllies Greater than or equal to (Number of players in AllPlayersPG)
Also, remember that you can display text messages in-game to figure out what's wrong. So you don't have to just guess, it's a simple math problem we're dealing with here and you can easily display the math in-game:
  • -------- Join the killing player's team: --------
  • Set TakeoverPG = (All allies of KillingPlayer)
  • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
  • Game - Display to (All players) the text: (Integer(Number of players in (All players)))
  • Game - Display to (All players) the text: (Integer(TakeoverTotalAllies)
This will give us a really good idea of what's going wrong since we will know exactly what these values are. If Number of players in (All players) is lower than the total number of Players in the game then it's safe to assume that it's excluding computers. If TakeoverTotalAllies is too high then we know that we did the math wrong, maybe we weren't supposed to add 1 to it, or maybe there's some other mistake in our logic that we're overlooking.
 
Last edited:
Level 2
Joined
Mar 8, 2024
Messages
6
Now it works!
I found out that All Players does include computer players with the help of your displaying text idea. Then i found out i might have added a "Set TakeoverPG" the wrong place and suddenly things started to work. I didnt need to make a AllPlayersPG.
This is what it looks like now and it works.
  • Player Takeover
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Base
    • Actions
      • Set TakeoverLoc = (Position of (Triggering unit))
      • Set KillingPlayer = (Owner of (Killing unit))
      • Set DyingPlayer = (Owner of (Dying unit))
      • Unit - Remove (Triggering unit) from the game
      • Unit - Create 1 Base for DyingPlayer at TakeoverLoc facing Default building facing degrees
      • Custom script: call RemoveLocation( udg_TakeoverLoc )
      • -------- Leave Dying Players Team --------
      • Set TakeoverPG = (All allies of DyingPlayer)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Enemy)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Enemy)
      • Custom script: call DestroyForce( udg_TakeoverPG )
      • -------- Join killing players team --------
      • Set TakeoverTeamLeader[(Player number of DyingPlayer)] = TakeoverTeamLeader[(Player number of KillingPlayer)]
      • Set TakeoverPG = (All allies of KillingPlayer)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make DyingPlayer treat (Picked player) as an Ally with shared vision)
      • Player Group - Pick every player in TakeoverPG and do (Player - Make (Picked player) treat DyingPlayer as an Ally with shared vision)
      • Set TakeoverTotalAllies = ((Number of players in TakeoverPG) + 1)
      • Game - Display to (All players) for 5.00 seconds the text: (String((Number of players in (All players))))
      • Game - Display to (All players) for 5.00 seconds the text: (String(TakeoverTotalAllies))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TakeoverTotalAllies Greater than or equal to (Number of players in (All players))
        • Then - Actions
          • Wait 3.00 seconds
          • Trigger - Run Game Over <gen> (ignoring conditions)
        • Else - Actions
      • Custom script: call DestroyForce( udg_TakeoverPG )
I will disable the display text, but other than that it just works.

  • Game Over
    • Events
    • Conditions
    • Actions
      • Set WinPlayer = TakeoverTeamLeader[(Player number of KillingPlayer)]
      • Player Group - Remove WinPlayer from TakeoverPG
      • Game - Victory WinPlayer (Show dialogs, Show scores)
      • Player Group - Pick every player in TakeoverPG and do (Game - Defeat (Picked player) with the message: Defeat!)
Thank you so much!!!!
Now i can begin fleshing out the different units players can use. Its amazing to finally have the foundation of the map in place!
You are for sure going to be added to the credits!
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,569
Glad it works.

One last thing, I recommend adding this Pause action before your Wait 3.00 seconds:
  • Then - Actions
    • Unit - Pause all units
    • Wait 3.00 seconds game-time
    • Trigger - Run Game Over <gen> (ignoring conditions
And use Wait game time. If I understand correctly the other Wait action will continue to run even while the game is paused. But that could be old, outdated information, I read about it here -> [Trigger] - Memory leaks with "wait"

That way you ensure that nothing else happens during the game over sequence. It's also a good time to Turn Off any triggers that may interfere.
 
Last edited:
Top