Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
053f634
Rework partial GameModeMap and GameLobby codes
SadPencil May 16, 2025
629a5df
Update AutoAllyingTextNoPlayerV2
SadPencil May 16, 2025
c3dd0fb
Update PlayerExtraOptionsPanel.cs
SadPencil May 16, 2025
f926d0e
Update MultiplayerGameLobby.cs
SadPencil May 16, 2025
31bfca1
Merge branch 'develop' into rework-gamemodemap-gamelobby
SadPencil May 29, 2025
e7fd6ca
random -> pseudoRandom
SadPencil May 29, 2025
dd4ca90
random -> pseudoRandom
SadPencil May 29, 2025
50a0d01
Fix rework gamemodemap
SadPencil Jun 27, 2025
0890c43
Update migration documents
SadPencil May 28, 2025
0aea75a
Update migration documents for recent changes
SadPencil May 28, 2025
3d0aecc
Replace doc URLs with relative ones
SadPencil May 28, 2025
871438b
Remove unnecessary migration document items
SadPencil May 28, 2025
0374a0d
Improve `ChatListBox` link handling (#734)
MahBoiDeveloper May 29, 2025
dcd73d1
Add AssemblyTitle to the main client executable (#739)
SadPencil May 29, 2025
662e8af
Fix bug when YR client shows missing required files text for like Are…
MahBoiDeveloper May 31, 2025
c486f9d
Fix UTF-8 with BOM is introduced in the generated `spawnmap.ini` file…
SadPencil May 31, 2025
c0ef06e
Add `discord.gg` as trusted domain (#745)
MahBoiDeveloper Jun 4, 2025
fb8e3cf
Refactor the ranks in `GameLobbyBase` class (#713)
MahBoiDeveloper Jun 4, 2025
78b8c8c
Merge YR branch changes (add inactive host check, fix disallowed side…
MahBoiDeveloper Jun 11, 2025
722f080
Fix broken screenshot processing for Ares (#747)
SadPencil Jun 11, 2025
b6336ad
Update XNAUI to 2.7.10 version (#746)
MahBoiDeveloper Jun 11, 2025
4d97ac1
Add issue templates (#722)
MahBoiDeveloper Jun 11, 2025
28c4480
Fix `LoadOrSaveGameOptionPresetWindow` cannot be customized via an in…
SadPencil Jun 18, 2025
c5d7ca6
Implement `GetStringListValue` and rework get list values from `IniFi…
MahBoiDeveloper Jun 18, 2025
2e94ed6
Merge branch 'develop' into rework-gamemodemap-gamelobby
SadPencil Jun 28, 2025
4cd232b
RampastringToolsExtensions -> IniFileExtensions
SadPencil Jun 28, 2025
37c83b6
Increase CurrentCustomMapCacheVersion
SadPencil Jun 28, 2025
2a8d049
Merge branch 'develop' into rework-gamemodemap-gamelobby
SadPencil Jul 19, 2025
1d9a0dc
Fix unexpected random location on AllowedStartingLocations
SadPencil Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions ClientCore/Extensions/IniFileExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

using Rampastring.Tools;

Expand All @@ -26,7 +28,7 @@ public static void RemoveAllKeys(this IniSection iniSection)
iniSection.RemoveKey(iniSectionKey.Key);
}

public static string[] GetStringListValue(this IniFile iniFile, string section, string key, string defaultValue, char[] separators = null)
public static string[] GetStringListValue(this IniFile iniFile, string section, string key, string defaultValue, char[]? separators = null)
{
separators ??= [','];
IniSection iniSection = iniFile.GetSection(section);
Expand All @@ -38,5 +40,18 @@ public static string[] GetStringListValue(this IniFile iniFile, string section,
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
}

public static string? GetStringValueOrNull(this IniSection section, string key) =>
section.KeyExists(key) ? section.GetStringValue(key, string.Empty) : null;

public static int? GetIntValueOrNull(this IniSection section, string key) =>
section.KeyExists(key) ? section.GetIntValue(key, 0) : null;

public static bool? GetBooleanValueOrNull(this IniSection section, string key) =>
section.KeyExists(key) ? section.GetBooleanValue(key, false) : null;

public static List<T>? GetListValueOrNull<T>(this IniSection section, string key, char separator, Func<string, T> converter) =>
section.KeyExists(key) ? section.GetListValue<T>(key, separator, converter) : null;

}
}
8 changes: 4 additions & 4 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -791,16 +791,16 @@ private void HandleOptionsRequest(string playerName, int options)
if (0 < side && side < SideCount && disallowedSides[side])
return;

if (Map?.CoopInfo != null)
if (GameModeMap?.CoopInfo != null)
{
if (Map.CoopInfo.DisallowedPlayerSides.Contains(side - 1) || side == SideCount + RandomSelectorCount)
if (GameModeMap.CoopInfo.DisallowedPlayerSides.Contains(side - 1) || side == SideCount + RandomSelectorCount)
return;

if (Map.CoopInfo.DisallowedPlayerColors.Contains(color - 1))
if (GameModeMap.CoopInfo.DisallowedPlayerColors.Contains(color - 1))
return;
}

if (start < 0 || start > Map?.MaxPlayers)
if (!(start == 0 || (GameModeMap?.AllowedStartingLocations?.Contains(start) ?? true)))
return;

if (team < 0 || team > 4)
Expand Down
193 changes: 129 additions & 64 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/GameLobbyBase.cs

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/LANGameLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -845,16 +845,16 @@ private void HandlePlayerOptionsRequest(string sender, string data)
if (side > 0 && side <= SideCount && disallowedSides[side - 1])
return;

if (Map.CoopInfo != null)
if (GameModeMap.CoopInfo != null)
{
if (Map.CoopInfo.DisallowedPlayerSides.Contains(side - 1) || side == SideCount + RandomSelectorCount)
if (GameModeMap.CoopInfo.DisallowedPlayerSides.Contains(side - 1) || side == SideCount + RandomSelectorCount)
return;

if (Map.CoopInfo.DisallowedPlayerColors.Contains(color - 1))
if (GameModeMap.CoopInfo.DisallowedPlayerColors.Contains(color - 1))
return;
}

if (start < 0 || start > Map.MaxPlayers)
if (!(start == 0 || (GameModeMap?.AllowedStartingLocations?.Contains(start) ?? true)))
return;

if (team < 0 || team > 4)
Expand Down
33 changes: 18 additions & 15 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/MapPreviewBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ private void ContextMenu_OptionSelected(int index)
{
SoundPlayer.Play(sndDropdownSound);

if (GameModeMap.Map.EnforceMaxPlayers)
if (GameModeMap.EnforceMaxPlayers)
{
foreach (PlayerInfo pInfo in players.Concat(aiPlayers))
{
Expand Down Expand Up @@ -301,7 +301,7 @@ private void Indicator_LeftClick(object sender, EventArgs e)

if (!EnableContextMenu)
{
if (GameModeMap.Map.EnforceMaxPlayers)
if (GameModeMap.EnforceMaxPlayers)
{
foreach (PlayerInfo pInfo in players.Concat(aiPlayers))
{
Expand Down Expand Up @@ -455,22 +455,25 @@ private void UpdateMap()

List<Point> startingLocations = GameModeMap.Map.GetStartingLocationPreviewCoords(new Point(previewTexture.Width, previewTexture.Height));

for (int i = 0; i < startingLocations.Count && i < GameModeMap.Map.MaxPlayers; i++)
for (int i = 0; i < MAX_STARTING_LOCATIONS; i++)
{
PlayerLocationIndicator indicator = startingLocationIndicators[i];
bool showLocation = i < startingLocations.Count && GameModeMap.AllowedStartingLocations.Contains(i + 1);
if (showLocation)
{
PlayerLocationIndicator indicator = startingLocationIndicators[i];

Point location = new Point(
texturePositionX + (int)(startingLocations[i].X * ratio),
texturePositionY + (int)(startingLocations[i].Y * ratio));
Point location = new Point(
texturePositionX + (int)(startingLocations[i].X * ratio),
texturePositionY + (int)(startingLocations[i].Y * ratio));

indicator.SetPosition(location);
indicator.Enabled = true;
indicator.Visible = true;
}

for (int i = startingLocations.Count; i < MAX_STARTING_LOCATIONS; i++)
{
startingLocationIndicators[i].Disable();
indicator.SetPosition(location);
indicator.Enabled = true;
indicator.Visible = true;
}
else
{
startingLocationIndicators[i].Disable();
}
}


Expand Down
35 changes: 17 additions & 18 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/MultiplayerGameLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.Xna.Framework.Graphics;
using ClientCore.Extensions;
using DTAClient.DXGUI.Multiplayer.CnCNet;
using System.Diagnostics;

namespace DTAClient.DXGUI.Multiplayer.GameLobby
{
Expand Down Expand Up @@ -801,7 +802,7 @@ protected override void BtnLaunchGame_LeftClick(object sender, EventArgs e)
return;
}

if (Map.EnforceMaxPlayers)
if (GameModeMap.EnforceMaxPlayers)
{
foreach (PlayerInfo pInfo in Players)
{
Expand Down Expand Up @@ -836,14 +837,14 @@ protected override void BtnLaunchGame_LeftClick(object sender, EventArgs e)
int totalPlayerCount = Players.Count(p => p.SideId < ddPlayerSides[0].Items.Count - 1)
+ AIPlayers.Count;

int minPlayers = GameMode.MinPlayersOverride > -1 ? GameMode.MinPlayersOverride : Map.MinPlayers;
int minPlayers = GameModeMap.MinPlayers;
if (totalPlayerCount < minPlayers)
{
InsufficientPlayersNotification();
return;
}

if (Map.EnforceMaxPlayers && totalPlayerCount > Map.MaxPlayers)
if (GameModeMap.EnforceMaxPlayers && totalPlayerCount > GameModeMap.MaxPlayers)
{
TooManyPlayersNotification();
return;
Expand Down Expand Up @@ -895,7 +896,7 @@ protected override void BtnLaunchGame_LeftClick(object sender, EventArgs e)
GetReadyNotification();
return;
}

}

HostLaunchGame();
Expand Down Expand Up @@ -937,19 +938,16 @@ protected virtual void GetReadyNotification()

protected virtual void InsufficientPlayersNotification()
{
if (GameMode != null && GameMode.MinPlayersOverride > -1)
AddNotice(String.Format("Unable to launch game: {0} cannot be played with fewer than {1} players".L10N("Client:Main:InsufficientPlayersNotification1"),
GameMode.UIName, GameMode.MinPlayersOverride));
else if (Map != null)
AddNotice(String.Format("Unable to launch game: this map cannot be played with fewer than {0} players.".L10N("Client:Main:InsufficientPlayersNotification2"),
Map.MinPlayers));
Debug.Assert(GameModeMap != null, "GameModeMap should not be null");
AddNotice(string.Format("Unable to launch game: {0} cannot be played with fewer than {1} players".L10N("Client:Main:InsufficientPlayersNotification1"),
GameModeMap.ToString(), GameModeMap.MinPlayers));
}

protected virtual void TooManyPlayersNotification()
{
if (Map != null)
AddNotice(String.Format("Unable to launch game: this map cannot be played with more than {0} players.".L10N("Client:Main:TooManyPlayersNotification"),
Map.MaxPlayers));
Debug.Assert(GameModeMap != null, "GameModeMap should not be null");
AddNotice(string.Format("Unable to launch game: {0} cannot be played with more than {1} players.".L10N("Client:Main:TooManyPlayersNotification1"),
GameModeMap.ToString(), GameModeMap.MaxPlayers));
}

public virtual void Clear()
Expand Down Expand Up @@ -1017,7 +1015,8 @@ protected override void CopyPlayerDataToUI()
{
StatusIndicators[pId].SwitchTexture("error");
}
else */ if (Players[pId].IsInGame) // If player is ingame
else */
if (Players[pId].IsInGame) // If player is ingame
{
StatusIndicators[pId].SwitchTexture(PlayerSlotState.InGame);
}
Expand Down Expand Up @@ -1152,10 +1151,10 @@ protected override void WriteSpawnIniAdditions(IniFile iniFile)

protected override int GetDefaultMapRankIndex(GameModeMap gameModeMap)
{
if (gameModeMap.Map.MaxPlayers > 3)
return StatisticsManager.Instance.GetCoopRankForDefaultMap(gameModeMap.Map.UntranslatedName, gameModeMap.Map.MaxPlayers);
if (gameModeMap.MaxPlayers > 3)
return StatisticsManager.Instance.GetCoopRankForDefaultMap(gameModeMap.Map.UntranslatedName, gameModeMap.MaxPlayers);

if (StatisticsManager.Instance.HasWonMapInPvP(gameModeMap.Map.UntranslatedName, gameModeMap.GameMode.UntranslatedUIName, gameModeMap.Map.MaxPlayers))
if (StatisticsManager.Instance.HasWonMapInPvP(gameModeMap.Map.UntranslatedName, gameModeMap.GameMode.UntranslatedUIName, gameModeMap.MaxPlayers))
return 2;

return -1;
Expand All @@ -1171,7 +1170,7 @@ protected override void UpdateMapPreviewBoxEnabledStatus()
{
if (Map != null && GameMode != null)
{
bool disablestartlocs = (Map.ForceRandomStartLocations || GameMode.ForceRandomStartLocations || GetPlayerExtraOptions().IsForceRandomStarts);
bool disablestartlocs = GameModeMap.ForceRandomStartLocations || GetPlayerExtraOptions().IsForceRandomStarts;
MapPreviewBox.EnableContextMenu = disablestartlocs ? false : IsHost;
MapPreviewBox.EnableStartLocationSelection = !disablestartlocs;
}
Expand Down
43 changes: 16 additions & 27 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,35 +109,24 @@ private string CheckGameValidity()
int totalPlayerCount = Players.Count(p => p.SideId < ddPlayerSides[0].Items.Count - 1)
+ AIPlayers.Count;

if (GameMode.MultiplayerOnly)
if (GameModeMap.MultiplayerOnly)
{
return String.Format("{0} can only be played on CnCNet and LAN.".L10N("Client:Main:GameModeMultiplayerOnly"),
GameMode.UIName);
return string.Format("{0} can only be played on CnCNet and LAN.".L10N("Client:Main:GameModeMultiplayerOnly"),
GameModeMap.ToString());
}

if (GameMode.MinPlayersOverride > -1 && totalPlayerCount < GameMode.MinPlayersOverride)
if (totalPlayerCount < GameModeMap.MinPlayers)
{
return String.Format("{0} cannot be played with less than {1} players.".L10N("Client:Main:GameModeInsufficientPlayers"),
GameMode.UIName, GameMode.MinPlayersOverride);
return string.Format("{0} cannot be played with less than {1} players.".L10N("Client:Main:GameModeInsufficientPlayers"),
GameModeMap.ToString(), GameModeMap.MinPlayers);
}

if (Map.MultiplayerOnly)
if (GameModeMap.EnforceMaxPlayers)
{
return "The selected map can only be played on CnCNet and LAN.".L10N("Client:Main:MapMultiplayerOnly");
}

if (totalPlayerCount < Map.MinPlayers)
{
return String.Format("The selected map cannot be played with less than {0} players.".L10N("Client:Main:MapInsufficientPlayers"),
Map.MinPlayers);
}

if (Map.EnforceMaxPlayers)
{
if (totalPlayerCount > Map.MaxPlayers)
if (totalPlayerCount > GameModeMap.MaxPlayers)
{
return String.Format("The selected map cannot be played with more than {0} players.".L10N("Client:Main:MapTooManyPlayers"),
Map.MaxPlayers);
return string.Format("{0} cannot be played with more than {1} players.".L10N("Client:Main:TooManyPlayers"),
GameModeMap.ToString(), GameModeMap.MaxPlayers);
}

IEnumerable<PlayerInfo> concatList = Players.Concat(AIPlayers);
Expand All @@ -154,7 +143,7 @@ private string CheckGameValidity()
}
}

if (Map.IsCoop && Players[0].SideId == ddPlayerSides[0].Items.Count - 1)
if (GameModeMap.IsCoop && Players[0].SideId == ddPlayerSides[0].Items.Count - 1)
{
return "Co-op missions cannot be spectated. You'll have to show a bit more effort to cheat here.".L10N("Client:Main:CoOpMissionSpectatorPrompt");
}
Expand Down Expand Up @@ -223,7 +212,7 @@ protected override bool AllowPlayerOptionsChange()

protected override int GetDefaultMapRankIndex(GameModeMap gameModeMap)
{
return StatisticsManager.Instance.GetSkirmishRankForDefaultMap(gameModeMap.Map.UntranslatedName, gameModeMap.Map.MaxPlayers);
return StatisticsManager.Instance.GetSkirmishRankForDefaultMap(gameModeMap.Map.UntranslatedName, gameModeMap.MaxPlayers);
}

protected override void GameProcessExited()
Expand Down Expand Up @@ -369,7 +358,7 @@ private void LoadSettings()
//return;
}

bool AIAllowed = !(Map.HumanPlayersOnly || GameMode.HumanPlayersOnly);
bool AIAllowed = !GameModeMap.HumanPlayersOnly;
foreach (string key in keys)
{
if (!AIAllowed) break;
Expand Down Expand Up @@ -469,13 +458,13 @@ private void CheckLoadedPlayerVariableBounds(PlayerInfo pInfo, bool isAIPlayer =
}

if (pInfo.TeamId < 0 || pInfo.TeamId >= ddPlayerTeams[0].Items.Count ||
!Map.IsCoop && (Map.ForceNoTeams || GameMode.ForceNoTeams))
!GameModeMap.IsCoop && GameModeMap.ForceNoTeams)
{
pInfo.TeamId = 0;
}

if (pInfo.StartingLocation < 0 || pInfo.StartingLocation > MAX_PLAYER_COUNT ||
!Map.IsCoop && (Map.ForceRandomStartLocations || GameMode.ForceRandomStartLocations))
GameModeMap.ForceRandomStartLocations)
{
pInfo.StartingLocation = 0;
}
Expand All @@ -497,7 +486,7 @@ private void InitDefaultSettings()

protected override void UpdateMapPreviewBoxEnabledStatus()
{
MapPreviewBox.EnableContextMenu = !((Map != null && Map.ForceRandomStartLocations) || (GameMode != null && GameMode.ForceRandomStartLocations) || GetPlayerExtraOptions().IsForceRandomStarts);
MapPreviewBox.EnableContextMenu = !(GameModeMap.ForceRandomStartLocations || GetPlayerExtraOptions().IsForceRandomStarts);
MapPreviewBox.EnableStartLocationSelection = MapPreviewBox.EnableContextMenu;
}

Expand Down
Loading
Loading