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

PvP Event with random Players

Level 4
Joined
Jan 9, 2024
Messages
28
Hello map making community.
I need some help with the trigger I made. So the idea is to have a timed PvP event which picks 2 random players to fight against each other in one out of 3 arenas.
When I tested it with another player (the map is for 2-6 players) it ported me and the other player to different arenas.
The issue is that I can't test it that often because I need another player obviously, so I want it to work next time.

This is the trigger I made:

  • PvP Event
    • Events
      • Time - PvP_Timer expires
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of players in Player_Group_Playing) Greater than or equal to 2
        • Then - Actions
          • Trigger - Turn off player dies <gen>
          • Countdown Timer - Destroy PvP_Timer_Window
          • Sound - Play ClanInvitation <gen>
          • Game - Display to Player_Group_Playing the text: PvP Event!
          • Player Group - Pick every player in Player_Group_Playing and do (Actions)
            • Loop - Actions
              • Set VariableSet PvP_PN = (Player number of (Picked player))
              • Player Group - Add (Picked player) to Player_Group_PvP
              • Unit - Remove All except expiration timer buffs from player_unit[PvP_PN]
              • Unit - Set life of player_unit[PvP_PN] to 100.00%
              • Unit - Set mana of player_unit[PvP_PN] to 100.00%
              • Unit - Reset ability cooldowns for player_unit[PvP_PN].
          • Wait 2.00 seconds
          • Unit - Pause all units
          • Set VariableSet Random_Player_PvP = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP to PvP_Group1
          • Player Group - Remove Random_Player_PvP from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN = (Player number of Random_Player_PvP)
          • Set VariableSet PvP_Fighter = player_unit[PvP_Rnd_PN]
          • Set VariableSet Random_Player_PvP_2 = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP_2 to PvP_Group1
          • Player Group - Remove Random_Player_PvP_2 from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN_2 = (Player number of Random_Player_PvP_2)
          • Set VariableSet PvP_Fighter_2 = player_unit[PvP_Rnd_PN_2]
          • Player Group - Pick every player in PvP_Group1 and do (Actions)
            • Loop - Actions
              • Player - Make Random_Player_PvP treat Random_Player_PvP_2 as an Enemy with shared vision
              • Player - Make Random_Player_PvP_2 treat Random_Player_PvP as an Enemy with shared vision
              • Unit - Move PvP_Fighter instantly to (Center of Arena_Region[1]), facing (Center of Arena_Region[2])
              • Camera - Pan camera for (Owner of PvP_Fighter) to (Center of Arena_Region[7]) over 0.00 seconds
              • Unit - Move PvP_Fighter_2 instantly to (Center of Arena_Region[2]), facing (Center of Arena_Region[1])
              • Camera - Pan camera for (Owner of PvP_Fighter_2) to (Center of Arena_Region[7]) over 0.00 seconds
          • Set VariableSet Random_Player_PvP_3 = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP_3 to PvP_Group2
          • Player Group - Remove Random_Player_PvP_3 from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN_3 = (Player number of Random_Player_PvP_3)
          • Set VariableSet PvP_Fighter_3 = player_unit[PvP_Rnd_PN_3]
          • Set VariableSet Random_Player_PvP_4 = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP_4 to PvP_Group2
          • Player Group - Remove Random_Player_PvP_4 from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN_4 = (Player number of Random_Player_PvP_4)
          • Set VariableSet PvP_Fighter_4 = player_unit[PvP_Rnd_PN_4]
          • Player Group - Pick every player in PvP_Group2 and do (Actions)
            • Loop - Actions
              • Player - Make Random_Player_PvP_3 treat Random_Player_PvP_4 as an Enemy with shared vision
              • Player - Make Random_Player_PvP_4 treat Random_Player_PvP_3 as an Enemy with shared vision
              • Unit - Move PvP_Fighter_3 instantly to (Center of Arena_Region[3]), facing (Center of Arena_Region[4])
              • Camera - Pan camera for (Owner of PvP_Fighter_3) to (Center of Arena_Region[8]) over 0.00 seconds
              • Unit - Move PvP_Fighter_4 instantly to (Center of Arena_Region[4]), facing (Center of Arena_Region[3])
              • Camera - Pan camera for (Owner of PvP_Fighter_4) to (Center of Arena_Region[8]) over 0.00 seconds
          • Set VariableSet Random_Player_PvP_5 = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP_5 to PvP_Group3
          • Player Group - Remove Random_Player_PvP_5 from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN_5 = (Player number of Random_Player_PvP_5)
          • Set VariableSet PvP_Fighter_5 = player_unit[PvP_Rnd_PN_5]
          • Set VariableSet Random_Player_PvP_6 = (Random player from Player_Group_PvP)
          • Player Group - Add Random_Player_PvP_6 to PvP_Group3
          • Player Group - Remove Random_Player_PvP_6 from Player_Group_PvP.
          • Set VariableSet PvP_Rnd_PN_6 = (Player number of Random_Player_PvP_6)
          • Set VariableSet PvP_Fighter_6 = player_unit[PvP_Rnd_PN_6]
          • Player Group - Pick every player in PvP_Group3 and do (Actions)
            • Loop - Actions
              • Player - Make Random_Player_PvP_5 treat Random_Player_PvP_6 as an Enemy with shared vision
              • Player - Make Random_Player_PvP_6 treat Random_Player_PvP_5 as an Enemy with shared vision
              • Unit - Move PvP_Fighter_5 instantly to (Center of Arena_Region[5]), facing (Center of Arena_Region[6])
              • Camera - Pan camera for (Owner of PvP_Fighter_5) to (Center of Arena_Region[9]) over 0.00 seconds
              • Unit - Move PvP_Fighter_6 instantly to (Center of Arena_Region[6]), facing (Center of Arena_Region[5])
              • Camera - Pan camera for (Owner of PvP_Fighter_6) to (Center of Arena_Region[9]) over 0.00 seconds
          • Game - Display to (All players) the text: |cffffc519PvP start...
          • Wait 1.00 seconds
          • For each (Integer Sec_5) from 1 to 5, do (Actions)
            • Loop - Actions
              • Game - Display to (All players) the text: (|cffffc519 + (String(((Sec_5 - 6) x -1))))
              • Sound - Play BattleNetTick <gen>
              • Wait 1.00 seconds
          • Sound - Play ArrangedTeamInvitation <gen>
          • Unit - Unpause PvP_Fighter
          • Unit - Unpause PvP_Fighter_2
          • Unit - Unpause PvP_Fighter_3
          • Unit - Unpause PvP_Fighter_4
          • Unit - Unpause PvP_Fighter_5
          • Unit - Unpause PvP_Fighter_6
          • Countdown Timer - Start wavesDecay_timer as a One-shot timer that will expire in 120.00 seconds
          • Countdown Timer - Start Waves_Timer_PvP as a One-shot timer that will expire in 150.00 seconds
          • Countdown Timer - Create a timer window for Waves_Timer_PvP with title PvP Event Ending in...
          • Set VariableSet PvP_End_Window = (Last created timer window)
          • Trigger - Turn on PvP Hero Dies <gen>
        • Else - Actions
          • Countdown Timer - Destroy PvP_Timer_Window
          • Sound - Play Error <gen>
          • Game - Display to Player_Group_Playing the text: Not enough Players ...
          • Countdown Timer - Start waves_timer as a One-shot timer that will expire in 30.00 seconds
          • Set VariableSet waves_lvl = (waves_lvl + 1)
          • Countdown Timer - Create a timer window for waves_timer with title (Wave + (String(waves_lvl)))
          • Set VariableSet waves_timer_window = (Last created timer window)

Is there a better way for picking random players and if - lets say there are only 3 players, the third player has to be a spectator of the PvP match between player 1 and 2?

I'm glad for any answer and help!
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
When I tested it with another player (the map is for 2-6 players) it ported me and the other player to different arenas.
Is this surprising, though? The trigger does exactly what you wanted:
a timed PvP event which picks 2 random players to fight against each other in one out of 3 arenas
If there were only 2 of you, then the question is not "Why is each of us teleported to different arena?", but "Why does Player_Group_Playing contain more than 2 players if there are only two of us?"


The issue is that I can't test it that often because I need another player obviously, so I want it to work next time.
But you can test this yourself. You can even use a computer player for this. Just create computer players, add them to Player_Group_Playing and the player_unit[] array and you will be set for testing.

Is there a better way for picking random players
Yes there is. Instead of having PvP_Fighter, PvP_Fighter_2, PvP_Fighter_3 ... PvP_Fighter_6 variables, you use a PvP_Fighters[] array. Units under indexes 1 and 2 go into first arena, indexes 3 and 4 to second arena and 5 and 6 to last arena.
You can randomly assign units into this array in a similar way you do now:
  • have an integer variable 'PvP_Index', set value to 1
  • pick random player from Player_Group_PvP
  • set PvP_Fighters[PvP_Index] = player_unit[PvP_PN]
  • increment PvP_Index by one
  • remove picked player from Player_Group_PvP
  • repeat for each player in Player_Group_PvP
Using the PvP_Fighters[] array will also enable you to have a single set of trigger actions for picking random PvP fighters, moving them to arena and then panning the camera for their owners, instead of having that set of actions repeated 3 times for each pair of PvP fighters.

This action block is completely useless:
  • Player Group - Pick every player in PvP_Group1 and do (Actions)
    • Loop - Actions
      • Player - Make Random_Player_PvP treat Random_Player_PvP_2 as an Enemy with shared vision
      • Player - Make Random_Player_PvP_2 treat Random_Player_PvP as an Enemy with shared vision
      • Unit - Move PvP_Fighter instantly to (Center of Arena_Region[1]), facing (Center of Arena_Region[2])
      • Camera - Pan camera for (Owner of PvP_Fighter) to (Center of Arena_Region[7]) over 0.00 seconds
      • Unit - Move PvP_Fighter_2 instantly to (Center of Arena_Region[2]), facing (Center of Arena_Region[1])
      • Camera - Pan camera for (Owner of PvP_Fighter_2) to (Center of Arena_Region[7]) over 0.00 seconds
and the same applies for the other groups.
You don't use the player picked by the 'Pick every player' action, instead you manually move both players' units and cameras.
So basically you move both units and cameras twice for each player.

  • Game - Display to (All players) the text: (|cffffc519 + (String(((Sec_5 - 6) x -1))))
((Sec_5 - 6) x -1)
:goblin_cry:
why not just "(6 - Sec_5)" ?


lets say there are only 3 players, the third player has to be a spectator of the PvP match between player 1 and 2?
You can use the modulo operation on integer. Get number of players in Player_Group_Playing modulo 2. This gives you the remainder after integer division. If the remainder is 1, then you have odd number of players playing. So after you create pairs of PvPers, you can take the last (odd) one and move him to spectate one of the fights.
 
Level 4
Joined
Jan 9, 2024
Messages
28
Thank you for the fast reply. I try to figure out how to build the trigger based on your explanation.
  • Set VariableSet PvP_Index = 1
  • Set VariableSet Random_Player_PvP = (Random player from Player_Group_PvP)
  • Set VariableSet PvP_Fighters[PvP_Index] = player_unit[PvP_PN]
  • Set VariableSet PvP_Index = (PvP_Index + 1)
How do I continue from here?
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
You can utilize loops:
  • -------- ---------------------------------------------- --------
  • -------- Populate array by PvPers in random order --------
  • Set VariableSet PlayerCount = (Number of players in Player_Group_PvP)
  • For each (Integer PvP_Index) from 1 to PlayerCount, do (Actions)
    • Loop - Actions
      • Set VariableSet Random_Player_PvP = (Random player from Player_Group_PvP)
      • Player Group - Remove Random_Player_PvP from Player_Group_PvP.
      • Set VariableSet PvP_Fighters[PvP_Index] = player_unit[(Player number of Random_Player_PvP)]
  • -------- ---------------------------------------------- --------
  • -------- Move pairs into their arenas --------
  • Set VariableSet PairCount = (PlayerCount / 2)
  • For each (Integer PvP_Index) from 1 to (PairCount x 2), do (Actions)
    • Loop - Actions
      • Set VariableSet loc = (Center of Arena_Regions[PvP_Index])
      • Set VariableSet facingLoc = (Center of Arena_Regions[(((PvP_Index - 1) / 2) + 7)])
      • Unit - Move PvP_Fighters[PvP_Index] instantly to loc, facing facingLoc
      • Camera - Pan camera for (Owner of PvP_Fighters[PvP_Index]) to facingLoc over 0.00 seconds
      • Custom script: call RemoveLocation(udg_loc)
      • Custom script: call RemoveLocation(udg_facingLoc)
  • -------- ---------------------------------------------- --------
  • -------- Set alliances --------
  • For each (Integer loopInt) from 0 to (PairCount - 1), do (Actions)
    • Loop - Actions
      • Set VariableSet offset = (loopInt x 2)
      • Player - Make (Owner of PvP_Fighters[(offset + 1)]) treat (Owner of PvP_Fighters[(offset + 2)]) as an Enemy with shared vision
      • Player - Make (Owner of PvP_Fighters[(offset + 2)]) treat (Owner of PvP_Fighters[(offset + 1)]) as an Enemy with shared vision
  • -------- ---------------------------------------------- --------
  • -------- Check if there are odd number of players --------
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (PairCount x 2) Less than PlayerCount
    • Then - Actions
      • -------- you have odd number of players --------
    • Else - Actions
Also, you may notice I have added the 'loc' and 'facingLoc' point variables. That is to prevent memory leaks.
 
Last edited:
Level 4
Joined
Jan 9, 2024
Messages
28
Ah ty, I haven't thought about using loops here. This trigger definitely looks clean in comparison to mine. I don't have to use so many variables and player groups now.

But you can test this yourself. You can even use a computer player for this. Just create computer players, add them to Player_Group_Playing and the player_unit[] array and you will be set for testing.
I will use this method after I made the trigger!

Edit:
You can utilize loops:
  • -------- Set alliances --------
  • For each (Integer loopInt) from 0 to (PairCount - 1), do (Actions)
    • Loop - Actions
      • Set VariableSet offset = (loopInt x 2)
      • Player - Make (Owner of PvP_Fighters[(offset + 1)]) treat (Owner of PvP_Fighters[(offset + 2)]) as an Enemy with shared vision
      • Player - Make (Owner of PvP_Fighters[(offset + 2)]) treat (Owner of PvP_Fighters[(offset + 1)]) as an Enemy with shared vision
So after the PvP Event is over, I need to revert the Alliances back to normal. Can I use this action again to get the players back to be allies?

Another question:
When the Arena starts, I need to unpause the Fighters inside the Arena, how can I pick them?

I'm trying
  • Unit - Unpause player_unit[PvP_PN]
now!
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
So after the PvP Event is over, I need to revert the Alliances back to normal. Can I use this action again to get the players back to be allies?
Yes, that should work

When the Arena starts, I need to unpause the Fighters inside the Arena, how can I pick them?
You can again use a loop in a similar way I used when moving only pairs of fighters to arena:
  • For each (Integer PvP_Index) from 1 to (PairCount x 2), do (Actions)
    • Loop - Actions
      • Unit - Unpause PvP_Fighters[PvP_Index]
 
Level 4
Joined
Jan 9, 2024
Messages
28
Yep, that both worked, ty!
One last question:
You can utilize loops:
  • -------- Check if there are odd number of players --------
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (PairCount x 2) Less than PlayerCount
    • Then - Actions
      • -------- you have odd number of players --------
    • Else - Actions

How do I track the odd player unit here? So I can move the unit to a location for example.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
You have up to 6 players. If you have a single player then you don't run the arena at all.
That leaves the odd player either at index 3 or 5 in PvP_Fighters[], depending on whether you have 3 or 5 players.
As you know the number of pairs via PairCount, you can get the odd player's unit as PvP_Fighters[(PairCount x 2) + 1]
 
Top