diff --git a/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs b/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs
index 169f9b95d..9d24a8e1e 100644
--- a/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs
+++ b/DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs
@@ -1068,11 +1068,12 @@ protected GameModeMapFilter GetDefaultGameModeMapFilter()
///
/// Applies disallowed side indexes to the side option drop-downs
- /// and player options.
+ /// and player options for human or computer players.
///
- protected void CheckDisallowedSides()
+ protected void CheckDisallowedSidesForGroup(bool forHumanPlayers)
{
- var disallowedSideArray = GetDisallowedSides();
+ var disallowedSideArray = GetDisallowedSidesForGroup(forHumanPlayers);
+ var playerInfos = forHumanPlayers ? Players : AIPlayers;
int defaultSide = 0;
int allowedSideCount = disallowedSideArray.Count(b => b == false);
@@ -1086,28 +1087,25 @@ protected void CheckDisallowedSides()
defaultSide = i + RandomSelectorCount;
}
- foreach (XNADropDown dd in ddPlayerSides)
+ foreach (PlayerInfo pInfo in playerInfos)
{
- //dd.Items[0].Selectable = false;
+ var dd = ddPlayerSides[pInfo.Index];
for (int i = 0; i < RandomSelectorCount; i++)
dd.Items[i].Selectable = false;
}
}
else
{
- foreach (XNADropDown dd in ddPlayerSides)
+ foreach (PlayerInfo pInfo in playerInfos)
{
- //dd.Items[0].Selectable = true;
+ var dd = ddPlayerSides[pInfo.Index];
for (int i = 0; i < RandomSelectorCount; i++)
dd.Items[i].Selectable = true;
}
}
- var concatPlayerList = Players.Concat(AIPlayers);
-
// Disable custom random groups if all or all except one of included sides are unavailable.
int c = 0;
- var playerInfos = concatPlayerList.ToList();
foreach (int[] randomSides in RandomSelectors)
{
int disableCount = 0;
@@ -1120,11 +1118,11 @@ protected void CheckDisallowedSides()
bool disabled = disableCount >= randomSides.Length - 1;
- foreach (XNADropDown dd in ddPlayerSides)
- dd.Items[1 + c].Selectable = !disabled;
-
foreach (PlayerInfo pInfo in playerInfos)
{
+ var dd = ddPlayerSides[pInfo.Index];
+ dd.Items[1 + c].Selectable = !disabled;
+
if (pInfo.SideId == 1 + c && disabled)
pInfo.SideId = defaultSide;
}
@@ -1140,21 +1138,24 @@ protected void CheckDisallowedSides()
if (disabled)
{
- foreach (XNADropDown dd in ddPlayerSides)
- dd.Items[i + RandomSelectorCount].Selectable = false;
-
// Change the sides of players that use the disabled
// side to the default side
foreach (PlayerInfo pInfo in playerInfos)
{
+ var dd = ddPlayerSides[pInfo.Index];
+ dd.Items[i + RandomSelectorCount].Selectable = false;
+
if (pInfo.SideId == i + RandomSelectorCount)
pInfo.SideId = defaultSide;
}
}
else
{
- foreach (XNADropDown dd in ddPlayerSides)
+ foreach (PlayerInfo pInfo in playerInfos)
+ {
+ var dd = ddPlayerSides[pInfo.Index];
dd.Items[i + RandomSelectorCount].Selectable = true;
+ }
}
}
@@ -1178,22 +1179,51 @@ protected void CheckDisallowedSides()
pInfo.SideId = defaultSide;
}
- foreach (XNADropDown dd in ddPlayerSides)
+ foreach (PlayerInfo pInfo in playerInfos)
{
+ var dd = ddPlayerSides[pInfo.Index];
if (dd.Items.Count > GetSpectatorSideIndex())
dd.Items[SideCount + RandomSelectorCount].Selectable = false;
}
}
else
{
- foreach (XNADropDown dd in ddPlayerSides)
+ foreach (PlayerInfo pInfo in playerInfos)
{
+ var dd = ddPlayerSides[pInfo.Index];
if (dd.Items.Count > SideCount + RandomSelectorCount)
dd.Items[SideCount + RandomSelectorCount].Selectable = true;
}
}
}
+ ///
+ /// Applies disallowed side indexes to the side option drop-downs
+ /// and player options.
+ ///
+ protected void CheckDisallowedSides()
+ {
+ CheckDisallowedSidesForGroup(forHumanPlayers:false);
+ CheckDisallowedSidesForGroup(forHumanPlayers:true);
+ }
+
+ ///
+ /// Gets a list of side indexes that are disallowed for human or computer players.
+ ///
+ /// A list of disallowed side indexes.
+ protected bool[] GetDisallowedSidesForGroup(bool forHumanPlayers)
+ {
+ var returnValue = GetDisallowedSides();
+ var sides = forHumanPlayers ? GameMode?.DisallowedHumanPlayerSides : GameMode?.DisallowedComputerPlayerSides;
+ if (sides != null)
+ {
+ foreach (int i in sides)
+ returnValue[i] = true;
+ }
+
+ return returnValue;
+ }
+
///
/// Gets a list of side indexes that are disallowed.
///
@@ -1292,13 +1322,20 @@ protected virtual PlayerHouseInfo[] Randomize(List teamStartMa
{
PlayerInfo pInfo;
PlayerHouseInfo pHouseInfo = houseInfos[i];
+ bool[] disallowedSides;
if (i < Players.Count)
+ {
pInfo = Players[i];
+ disallowedSides = GetDisallowedSidesForGroup(forHumanPlayers:true);
+ }
else
+ {
pInfo = AIPlayers[i - Players.Count];
+ disallowedSides = GetDisallowedSidesForGroup(forHumanPlayers:false);
+ }
- pHouseInfo.RandomizeSide(pInfo, SideCount, random, GetDisallowedSides(), RandomSelectors, RandomSelectorCount);
+ pHouseInfo.RandomizeSide(pInfo, SideCount, random, disallowedSides, RandomSelectors, RandomSelectorCount);
pHouseInfo.RandomizeColor(pInfo, freeColors, MPColors, random);
pHouseInfo.RandomizeStart(pInfo, random, freeStartingLocations, takenStartingLocations, teamStartMappings.Any());
@@ -2058,6 +2095,8 @@ protected virtual void CopyPlayerDataToUI()
MapPreviewBox.UpdateStartingLocationTexts();
UpdateMapPreviewBoxEnabledStatus();
+ CheckDisallowedSides();
+
PlayerUpdatingInProgress = false;
}
@@ -2197,8 +2236,6 @@ protected virtual void ChangeMap(GameModeMap gameModeMap)
pInfo.TeamId = 0;
}
- CheckDisallowedSides();
-
if (Map.CoopInfo != null)
{
diff --git a/DXMainClient/DXGUI/Multiplayer/GameLobby/LANGameLobby.cs b/DXMainClient/DXGUI/Multiplayer/GameLobby/LANGameLobby.cs
index dda7e57d0..574ed73ba 100644
--- a/DXMainClient/DXGUI/Multiplayer/GameLobby/LANGameLobby.cs
+++ b/DXMainClient/DXGUI/Multiplayer/GameLobby/LANGameLobby.cs
@@ -836,6 +836,11 @@ private void HandlePlayerOptionsRequest(string sender, string data)
if (color < 0 || color > MPColors.Count)
return;
+ var disallowedSides = GetDisallowedSides();
+
+ if (side > 0 && side <= SideCount && disallowedSides[side - 1])
+ return;
+
if (Map.CoopInfo != null)
{
if (Map.CoopInfo.DisallowedPlayerSides.Contains(side - 1) || side == SideCount + RandomSelectorCount)
@@ -946,6 +951,7 @@ private void HandlePlayerOptionsBroadcast(string data)
}
CopyPlayerDataToUI();
+
localPlayer = FindLocalPlayer();
if (localPlayer != null && oldSideId != localPlayer.SideId)
UpdateDiscordPresence();
diff --git a/DXMainClient/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs b/DXMainClient/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs
index d654f8881..e615ef828 100644
--- a/DXMainClient/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs
+++ b/DXMainClient/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs
@@ -52,8 +52,6 @@ public override void Initialize()
LoadSettings();
- CheckDisallowedSides();
-
CopyPlayerDataToUI();
ProgramConstants.PlayerNameChanged += ProgramConstants_PlayerNameChanged;
diff --git a/DXMainClient/Domain/Multiplayer/GameMode.cs b/DXMainClient/Domain/Multiplayer/GameMode.cs
index bad2b5d69..60af545f9 100644
--- a/DXMainClient/Domain/Multiplayer/GameMode.cs
+++ b/DXMainClient/Domain/Multiplayer/GameMode.cs
@@ -60,6 +60,17 @@ public GameMode(string name)
///
public List DisallowedPlayerSides = new List();
+ ///
+ /// List of side indices human players cannot select in this game mode.
+ ///
+ public List DisallowedHumanPlayerSides = new List();
+
+ ///
+ /// List of side indices computer players cannot select in this game mode.
+ ///
+ public List DisallowedComputerPlayerSides = new List();
+
+
///
/// Override for minimum amount of players needed to play any map in this game mode.
///
@@ -100,6 +111,20 @@ public void Initialize()
foreach (string sideIndex in disallowedSides)
DisallowedPlayerSides.Add(int.Parse(sideIndex));
+ disallowedSides = forcedOptionsIni
+ .GetStringValue(Name, "DisallowedHumanPlayerSides", string.Empty)
+ .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string sideIndex in disallowedSides)
+ DisallowedHumanPlayerSides.Add(int.Parse(sideIndex));
+
+ disallowedSides = forcedOptionsIni
+ .GetStringValue(Name, "DisallowedComputerPlayerSides", string.Empty)
+ .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string sideIndex in disallowedSides)
+ DisallowedComputerPlayerSides.Add(int.Parse(sideIndex));
+
ParseForcedOptions(forcedOptionsIni);
ParseSpawnIniOptions(forcedOptionsIni);