• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Sorting Players into Multiple teams ingame

Status
Not open for further replies.
Level 23
Joined
Oct 20, 2012
Messages
3,075
Yup, as the title says, I'm supposedly making a team sorter where, when a dialog button is clicked, it sorts out all 12 players into either 2 teams, 6 teams, or Free for All.

  • Button Teams Of 6
    • Events
      • Dialog - A dialog button is clicked for A_GAME_TS_Dialog
    • Conditions
      • (Clicked dialog button) Equal to A_GAME_TS_DialogButtonTeam
    • Actions
      • For each (Integer A) from 1 to 2, do (Actions)
        • Loop - Actions
          • For each (Integer B) from 1 to 6, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                • Then - Actions
                • Else - Actions
      • Game - Unpause the game
Yes, I know, the trigger is empty. I couldn't think of any ways to distribute the players evenly and randomly. That's where I need help from you guys. How can I do that exactly, without using too many trigger actions?
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
You park all players in a force, count the members, divide it by the number of teams, rounding down. Then you progressively draw random players from the force and add them to the current team starting with the first one. When this one reaches its share of players (totalPlayerCount / teamCount), you proceed to the next team and so on. For the remaining players you randomize the teams. Put them in a data structure as well and draw them, so each one may receive a single player at max.
 
Level 5
Joined
Jan 27, 2014
Messages
164
> but there would be a chance that the same player...
Whenever you draw the random player from that player group, you remove that player from the group as well. Then you won't have a chance to double pick.

  • Two Teams
    • Events
    • Conditions
    • Actions
      • Set playergp = (All players matching (((Matching player) slot status) Equal to Is playing))
      • Set int = ((Number of players in playergp) / 2)
      • -------- Team 1 Setup --------
      • For each (Integer A) from 0 to int, do (Actions)
        • Loop - Actions
          • Set player = (Random player from playergp)
          • Player Group - Add player to playergp_team[1]
          • Player Group - Remove player from playergp
      • -------- Team 2 Setup --------
      • Player Group - Pick every player in playergp and do (Actions)
        • Loop - Actions
          • Player Group - Add (Picked player) to playergp_team[2]
      • -------- Set Alliance Team 1 enemy to Team 2 --------
      • Player Group - Pick every player in playergp_team[1] and do (Actions)
        • Loop - Actions
          • Set player = (Picked player)
          • Player Group - Pick every player in playergp_team[2] and do (Actions)
            • Loop - Actions
              • Player - Make player treat (Picked player) as an Enemy
      • -------- Set Alliance Team 2 enemy to Team 1 --------
      • Player Group - Pick every player in playergp_team[2] and do (Actions)
        • Loop - Actions
          • Set player = (Picked player)
          • Player Group - Pick every player in playergp_team[1] and do (Actions)
            • Loop - Actions
              • Player - Make player treat (Picked player) as an Enemy
      • Custom script: call DestroyForce (udg_playergp)
This is crude for 2 teams selection. I'm not even sure if this would work. Just something I can come up with.
The Team 2 addition is pretty much redundant but just to make things easier to understand.

Edit: To begin with, all players are supposed to be allies to each other.
 
Level 23
Joined
Oct 20, 2012
Messages
3,075
I tried a few hours ago (3 A.M. Seriously.) and I think I have a working trigger. I don't know why it doesn't work with multiplayer emulation though.

  • Button Two Teams
    • Events
      • Dialog - A dialog button is clicked for A_GAME_TS_Dialog
    • Conditions
      • (Clicked dialog button) Equal to A_GAME_TS_DialogButtonTeam
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Number of players in A_GAME_PlayerAll) Equal to 2
              • (Number of players in A_GAME_PlayerAll) Equal to 4
              • (Number of players in A_GAME_PlayerAll) Equal to 6
              • (Number of players in A_GAME_PlayerAll) Equal to 8
              • (Number of players in A_GAME_PlayerAll) Equal to 10
              • (Number of players in A_GAME_PlayerAll) Equal to 12
        • Then - Actions
          • Set A_GAME_TempInteger[1] = ((Number of players in A_GAME_PlayerAll) / 2)
          • Set A_GAME_TempInteger[2] = ((Number of players in A_GAME_PlayerAll) / 2)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Number of players in A_GAME_PlayerAll) Equal to 3
                  • (Number of players in A_GAME_PlayerAll) Equal to 5
                  • (Number of players in A_GAME_PlayerAll) Equal to 7
                  • (Number of players in A_GAME_PlayerAll) Equal to 9
                  • (Number of players in A_GAME_PlayerAll) Equal to 11
            • Then - Actions
              • Set A_GAME_TempInteger[1] = ((((Number of players in A_GAME_PlayerAll) - 1) / 2) + 1)
              • Set A_GAME_TempInteger[2] = (((Number of players in A_GAME_PlayerAll) - 1) / 2)
            • Else - Actions
      • For each (Integer A) from 1 to 2, do (Actions)
        • Loop - Actions
          • For each (Integer B) from 1 to A_GAME_TempInteger[(Integer A)], do (Actions)
            • Loop - Actions
              • Set A_GAME_Player = (Random player from A_GAME_PlayerGroup[1])
              • Player Group - Add A_GAME_Player to A_GAME_PlayerGroup[((Integer A) + 1)]
              • Player Group - Remove A_GAME_Player from A_GAME_PlayerGroup[1]
      • Player Group - Pick every player in A_GAME_PlayerGroup[2] and do (Actions)
        • Loop - Actions
          • Game - Display to (All players) the text: (Team 1 : + (Name of (Picked player)))
          • Set A_GAME_Player = (Picked player)
          • Player Group - Pick every player in (All players matching (A_GAME_Player Not equal to (Matching player))) and do (Actions)
            • Loop - Actions
              • Player - Make A_GAME_Player treat (Picked player) as an Ally with shared vision
          • Player Group - Pick every player in A_GAME_PlayerGroup[3] and do (Actions)
            • Loop - Actions
              • Player - Make A_GAME_Player treat (Picked player) as an Enemy
      • Player Group - Pick every player in A_GAME_PlayerGroup[3] and do (Actions)
        • Loop - Actions
          • Game - Display to (All players) the text: (Team 2 : + (Name of (Picked player)))
          • Set A_GAME_Player = (Picked player)
          • Player Group - Pick every player in (All players matching (A_GAME_Player Not equal to (Matching player))) and do (Actions)
            • Loop - Actions
              • Player - Make A_GAME_Player treat (Picked player) as an Ally with shared vision
          • Player Group - Pick every player in A_GAME_PlayerGroup[2] and do (Actions)
            • Loop - Actions
              • Player - Make A_GAME_Player treat (Picked player) as an Enemy
      • Set A_GAME_TempInteger[1] = 1
      • Game - Unpause the game
      • Trigger - Run Distribute Goods <gen> (ignoring conditions)
      • Trigger - Run Distribute Hero Selector <gen> (ignoring conditions)
      • Trigger - Run Two Team Multiboard Create <gen> (ignoring conditions)
      • Custom script: call DestroyTrigger(GetTriggeringTrigger())
BTW, Seems like LAN (or maybe Battlenet too) requires at least two forces to start the map, so I had to divide the players into two teams.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Model players as a set. You break them into X teams by removing elements from the set and adding them to the team sets in a round-robin fashion. You could randomize the allocation order (which team is given a member first) to make the team allocations a little more fair in the case of left over players (balanced teams not possible).

Obviously a force or player group in GUI acts as a set of players.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Elaborating on further approaches, if your map keeps track of how good players are (e.g. they have a code to load their points) you could also add a little spice to make the teams as fair as possible (avoid having stacked teams). For example, get the total summed points of all the players, and then try to make it so each team has close to the total points divided by the size of each team. Of course it won't work always (e.g. one guy has 1000 points, but everyone else has 0, in which case no matter what you do one team will be "stacked."). Just some thoughts if you want to pick fair teams and not just completely random.

Of course, if those situations happen, you can have the game detect how "close" each match is. A game where it's impossible to avoid a stacked team should give very few points to the stacked winners, while if there is an upset then obviously more points should be awarded. That way even if a pro keeps playing, he won't get many points by beating newbs.
 
Status
Not open for further replies.
Top