Last Update: This tutorial is outdated. See the 14th post for a better way to do this.
I added a map with better documentation, though it has been customized so it won't follow this thread exactly. Do whatever with it as you like. Read this for more info. Also if the walkthrough is too hard for you to follow, just download the map and look at the triggers, game variants/attributes, and player properties.
I just recently made a map that needs 4 identical teams of 2, in which also needed allies to be placed next to each other. I'm going to go through what I did to make this possible. Since this is my first walkthrough/tutorial, I hope it's easy to follow.
Summary (Don't worry if you don't understand it yet): I detected each unique alliance to get the teams set up as the lobby was and then placed their units and stuff via action definitions for each team.
Here's how I did this:
- Before you begin, just a heads up, this is what I've done for a map that had no computer players or preplaced units at all. You may have to use an 'if statement' to detect if there's any non-human player who has preplaced units and ignore it if it does. Ideally, for each human player you will have to make an 'action definition' described later for placing their units instead of placing them on the map via the terrain editor. So now's a good time to start replacing any starting units owned by human players with regions or points (which should be named well enough to let you know later what they are for).
Detecting Teams:
First I added all the players (My map is limited to 8 players so I only used what I needed.) into a Player Group Variable called 'Unassigned Players'. The built-in 'Allies of Player' player group does not also count the player being checked for allies; so I made my own variable (which I had called 'Allies of Player' ironically) which would include both a player and the player's allies. My own 'Allies of Player' variable was also an array which I set to 8.
Sorting Teams:
Next I took each alliance in my 'Unassigned Players' player group, added the first alliance to a 'Team' global variable (an array of 4 by the way) I created, and then removed all the players from the 'Team' that was set from the 'Unassigned Players' player group. Pretty much just moving each alliance from one player group to another. I repeated this only as many times as I wanted teams (hense why 'Team' was an array of 4).
Also while I was moving the alliances to my teams variable, I was also checking for more than 2 players in each team. I moved them all to team one, so later, I could move them into the other teams (to prevent breaking the map) one by one.
Balancing Teams:
After sorting each alliance into a team, I now have any extra players detected in team 1. Here I push all the extra players into any holes in the teams, balancing them. (Note: This only work if you need 2 players in each team. Check the map attached to this post for another balancing setup for more than 2 players in each team.)
Finalizing Teams:
Here I went through each team setting how they should treat each other. I did these individually because I couldn't think of a way to put them in a 'pick each integer' action. I'll only show the setting of enemies for the first team since it's a bit long to post all of them.
Placing starting units and setting up variables (ment for my map).
Detecting Teams (again):
Here I'm gathering the first player from each team (to represent each team) and putting them into another Global Player Group variable called 'Teams for Sorting'. You shouldn't need to have 'Teams for Sorting' as a global variable for this, I did it because I wanted to make sure it was being set up correctly (which it is now).
Random Placement (You can skip this if you don't want it. This may also be a little confusing.):
Here I'm setting a integer variable called 'Static Number of Players from Teams for Sorting'. I did this to make sure that the number of teams to place wouldn't change as I'm running the loop for placement (I'm not sure it's really needed but I did it anyway to be sure it will work as intended). Next is the first part of my placement loop which is selecting a random team to place.
Based on the initial random setting for my local integer variable called 'Placement Setting' (randomly either 1 or 2) I'm choosing which direction I want to place my teams incrementally (I didn't show the backwards way cause it would be a larger picture).
Here's what's happening for how I wanted to place teams: 1 vs 1 team matches players will always be straight across the map from each other (local integer variable 'Place to Populate' equals 1 then equals 2). The other two teams (or single team) will randomly be placed in the last two spots on the map.
Note: Going 'backwards' as I called it worked like this. 'Place to Populate' first equals 4 then equals 3, and again the last two teams randomly end up in the other two spots.
Setting up an Action Definition for each Team:
Here's an 'action definition' that I'm using to place units. It works like a trigger, only you can use it as a fuction in other triggers, using a variable from another trigger (great to use in a loop). I made one for each team on the map.
Once made, I created a player group 'parameter' that I put any team into to create units and set variables. I also included an if statement that checked for a second player on a team (because I made my map to where a single player team would still be equal to a two player one.) I'm not going to cover my team balancing because it's too proprietary to my map to bother with. Make your own based on your map.
Setting up a final Action Definition to use the others:
Here I created one last action definition to deside which of the other action definitions to use. I used two perameters, one for the team and the other for where to put the selected team. Pretty straight forward, just continue the chain for each place to put teams.
Finally placing units:
Here I'm incrementally placing each teams units. Using the final action definition I'm able to easily put each team into a random place.
I'm still working on this at the moment, but this works perfectly fine and gets the job done. If there are any errors that pop-up, please leave a comment so I know and I may return to help you and myself. I may update this as I continue to work on my map and see that one is needed.
Update: I added a map to the tutorial which has better documentation. Do whatever with it as you like.
Note that you may want to add a global boolean variable and call it "Map Started". If you're using any triggers that need to see if a player has units, have a condition for the trigger and have it see if "Map Started" is set to true.
Lastly the uploaded map was customized via request. I don't intend to do too many more unless it's something I could improve the code with.
thanks for the tutorial, but when i load the map to see the actual triggers, this is the error it gives.
[9/24/20104:43:45PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,45319931,Lib:0)[9/24/20104:43:45PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,35E4FAAF,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,7290EDDC,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,6CC00AC7,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,0807881D,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,C4169A3B,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,6AE612E0,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,9D363D89,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,243D4704,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,B60B21AE,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,1D428CAB,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,79F06FE3,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,CAEF256D,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,3D91224F,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,C770C7F9,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,049EB78D,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,F4A2940E,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,97521195,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,5D12D17A,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,2681C85A,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,EC75CB1E,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,0B466F48,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,C74BF74B,Lib:0)[9/24/20104:43:46PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,B2C902DB,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,45319931,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,35E4FAAF,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,7290EDDC,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,6CC00AC7,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,0807881D,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,C4169A3B,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,6AE612E0,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,9D363D89,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,243D4704,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,B60B21AE,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,1D428CAB,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,79F06FE3,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,CAEF256D,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,3D91224F,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,C770C7F9,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,049EB78D,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,F4A2940E,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,97521195,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,5D12D17A,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,2681C85A,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,EC75CB1E,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,0B466F48,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Number Of Players In Player Group'(ParameterValue,C74BF74B,Lib:0)[9/24/20104:46:10PM]Warning:OrphanedtriggerparameterremovedfromFunctionCall'Player From Player Group'(ParameterValue,B2C902DB,Lib:0)
EDIT: It's nothing to worry about, just ignore it. The map still works. I think it might be corruption from the copy/paste and then editing it without exiting the editor from start to finish. Just opening the editor cleans the code in the map so it's nothing to worry about. So saving the map again should prevent those messages from showing up a second time.
I think I have a much more elegant solution (though the fact we all have to burn mental calories thinking this shite through becasue Blizztard can't write software since they got addicted to boning out crappy MMO grindfest content CHAFES MY EYEBALLS AND MY OTHER BALLS).
Fire IQ cannon!
Fix the colour of the slots in the lobby, then make use of the player/get colour accessor.
Intact link between lobby and player property?
Not tested it yet. I am on an all-nighter and need bacon.
I havn't read the entire first post but umm... guys... u do realise this has been fixed in 1.1?
colour assignment should work fine right off the bat unless you've forced it in your map, works perfectly for me anyway and has since day 1
lobbies are assigned very easily. You ready for it?
For each integer I in 1 to 8
Player - make all players in Players on Team i treat each other as ally with shared vision
I guess what i'm saying is theres no need for a tutorial
The above snipped of code will set all players within any lobby teams as allies. Colours will also match up according to who chooses what in the lobby
Starting positions can be done with only a fraction more work. I'll assume a 2v2v2v2 map
Place 8 starting locations wherever u want, presumably in pairs of 2
Open trigger editor, create a global variable called PlayerLocations as an array of 4,2 (since theres 4 teams of 2 players) and type as point
Create 8 'set variable' commands pointing PlayerLocation[1,1] to team1's 1st standing position, PlayerLocation[1,2] to team1's 2nd starting position etc for all of them
Then underneath that
For each integer 'team' from 1 to 4
for each integer 'player' from 1 to 2
pan camera to position PlayerLocation[team,player] for player (player in player group team) over 0.0 seconds
create 1 unit *whatever you use* for player (player in player group team) at position PlayerLocation[team,player]
doneskies, i've just written it in text not copied from the editor so I might have a minor layout error, but thats basically all you want. In combination with the above snippet (which sets all lobby allies as allies in game) will also center that players camera on his starting location, and create a unit/units at their starting locations
edit: /rant seriously whats up with the page layout on this site? why do I have to hit enter twice just to put something on the next line. It's annoying and messy... /endrant
Last Update: This tutorial is outdated. See the 14th post for a better way to do this.
I added a map with better documentation, though it has been customized so it won't follow this thread exactly. Do whatever with it as you like. Read this for more info. Also if the walkthrough is too hard for you to follow, just download the map and look at the triggers, game variants/attributes, and player properties.
I just recently made a map that needs 4 identical teams of 2, in which also needed allies to be placed next to each other. I'm going to go through what I did to make this possible. Since this is my first walkthrough/tutorial, I hope it's easy to follow.
Summary (Don't worry if you don't understand it yet): I detected each unique alliance to get the teams set up as the lobby was and then placed their units and stuff via action definitions for each team.
Here's how I did this:
- Before you begin, just a heads up, this is what I've done for a map that had no computer players or preplaced units at all. You may have to use an 'if statement' to detect if there's any non-human player who has preplaced units and ignore it if it does. Ideally, for each human player you will have to make an 'action definition' described later for placing their units instead of placing them on the map via the terrain editor. So now's a good time to start replacing any starting units owned by human players with regions or points (which should be named well enough to let you know later what they are for).
Detecting Teams:
First I added all the players (My map is limited to 8 players so I only used what I needed.) into a Player Group Variable called 'Unassigned Players'. The built-in 'Allies of Player' player group does not also count the player being checked for allies; so I made my own variable (which I had called 'Allies of Player' ironically) which would include both a player and the player's allies. My own 'Allies of Player' variable was also an array which I set to 8.
Sorting Teams:
Next I took each alliance in my 'Unassigned Players' player group, added the first alliance to a 'Team' global variable (an array of 4 by the way) I created, and then removed all the players from the 'Team' that was set from the 'Unassigned Players' player group. Pretty much just moving each alliance from one player group to another. I repeated this only as many times as I wanted teams (hense why 'Team' was an array of 4). Also while I was moving the alliances to my teams variable, I was also checking for more than 2 players in each team. I moved them all to team one, so later, I could move them into the other teams (to prevent breaking the map) one by one.
Balancing Teams:
After sorting each alliance into a team, I now have any extra players detected in team 1. Here I push all the extra players into any holes in the teams, balancing them. (Note: This only work if you need 2 players in each team. Check the map attached to this post for another balancing setup for more than 2 players in each team.)
Finalizing Teams:
Here I went through each team setting how they should treat each other. I did these individually because I couldn't think of a way to put them in a 'pick each integer' action. I'll only show the setting of enemies for the first team since it's a bit long to post all of them.
Placing starting units and setting up variables (ment for my map).
Detecting Teams (again):
Here I'm gathering the first player from each team (to represent each team) and putting them into another Global Player Group variable called 'Teams for Sorting'. You shouldn't need to have 'Teams for Sorting' as a global variable for this, I did it because I wanted to make sure it was being set up correctly (which it is now).
Random Placement (You can skip this if you don't want it. This may also be a little confusing.):
Here I'm setting a integer variable called 'Static Number of Players from Teams for Sorting'. I did this to make sure that the number of teams to place wouldn't change as I'm running the loop for placement (I'm not sure it's really needed but I did it anyway to be sure it will work as intended). Next is the first part of my placement loop which is selecting a random team to place. Based on the initial random setting for my local integer variable called 'Placement Setting' (randomly either 1 or 2) I'm choosing which direction I want to place my teams incrementally (I didn't show the backwards way cause it would be a larger picture). Here's what's happening for how I wanted to place teams: 1 vs 1 team matches players will always be straight across the map from each other (local integer variable 'Place to Populate' equals 1 then equals 2). The other two teams (or single team) will randomly be placed in the last two spots on the map. Note: Going 'backwards' as I called it worked like this. 'Place to Populate' first equals 4 then equals 3, and again the last two teams randomly end up in the other two spots.
Setting up an Action Definition for each Team:
Here's an 'action definition' that I'm using to place units. It works like a trigger, only you can use it as a fuction in other triggers, using a variable from another trigger (great to use in a loop). I made one for each team on the map. Once made, I created a player group 'parameter' that I put any team into to create units and set variables. I also included an if statement that checked for a second player on a team (because I made my map to where a single player team would still be equal to a two player one.) I'm not going to cover my team balancing because it's too proprietary to my map to bother with. Make your own based on your map.
Setting up a final Action Definition to use the others:
Here I created one last action definition to deside which of the other action definitions to use. I used two perameters, one for the team and the other for where to put the selected team. Pretty straight forward, just continue the chain for each place to put teams.
Finally placing units:
Here I'm incrementally placing each teams units. Using the final action definition I'm able to easily put each team into a random place.
I'm still working on this at the moment, but this works perfectly fine and gets the job done. If there are any errors that pop-up, please leave a comment so I know and I may return to help you and myself. I may update this as I continue to work on my map and see that one is needed.
Update: I added a map to the tutorial which has better documentation. Do whatever with it as you like. Note that you may want to add a global boolean variable and call it "Map Started". If you're using any triggers that need to see if a player has units, have a condition for the trigger and have it see if "Map Started" is set to true.
Lastly the uploaded map was customized via request. I don't intend to do too many more unless it's something I could improve the code with.
hello,
thanks for the tutorial, but when i load the map to see the actual triggers, this is the error it gives.
@darkdemondd: Go
I'll look into that.
EDIT: It's nothing to worry about, just ignore it. The map still works. I think it might be corruption from the copy/paste and then editing it without exiting the editor from start to finish. Just opening the editor cleans the code in the map so it's nothing to worry about. So saving the map again should prevent those messages from showing up a second time.
@DrakenStark: Go
it removes the code so all the triggers are gone basically. your map had tons of comments but no triggers. maybe has to do with the 1.1 patch?
@darkdemondd: Go
The map has been updated and should no longer show the messages.
no more errors, but this looks very complex, gonna take me some time to figure this out..
@darkdemondd: Go
I tried to leave enough info to get anyone started on modifing it to their needs.
@DJSplendid: Go
That wouldn't allow players to team up as they wish.
I havn't read the entire first post but umm... guys... u do realise this has been fixed in 1.1? colour assignment should work fine right off the bat unless you've forced it in your map, works perfectly for me anyway and has since day 1
lobbies are assigned very easily. You ready for it?
For each integer I in 1 to 8 Player - make all players in Players on Team i treat each other as ally with shared vision
Colours and teams matched, GG
@Millenium7: Go
Sweet, I can use that to optimize the tutorial later when I get around to making another map that needs this.
@DrakenStark: Go
I guess what i'm saying is theres no need for a tutorial
The above snipped of code will set all players within any lobby teams as allies. Colours will also match up according to who chooses what in the lobby Starting positions can be done with only a fraction more work. I'll assume a 2v2v2v2 map Place 8 starting locations wherever u want, presumably in pairs of 2 Open trigger editor, create a global variable called PlayerLocations as an array of 4,2 (since theres 4 teams of 2 players) and type as point Create 8 'set variable' commands pointing PlayerLocation[1,1] to team1's 1st standing position, PlayerLocation[1,2] to team1's 2nd starting position etc for all of them
Then underneath that
For each integer 'team' from 1 to 4
for each integer 'player' from 1 to 2
pan camera to position PlayerLocation[team,player] for player (player in player group team) over 0.0 seconds
create 1 unit *whatever you use* for player (player in player group team) at position PlayerLocation[team,player]
doneskies, i've just written it in text not copied from the editor so I might have a minor layout error, but thats basically all you want. In combination with the above snippet (which sets all lobby allies as allies in game) will also center that players camera on his starting location, and create a unit/units at their starting locations
edit: /rant seriously whats up with the page layout on this site? why do I have to hit enter twice just to put something on the next line. It's annoying and messy... /endrant
@Millenium7: Go
Freaken awesome. Thanks for that info.
In reply to Millenium7: