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);