From d4b71058a4f5c7e5847eefa737fb1d03a53b3671 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff <timfelgentreff@gmail.com> Date: Tue, 15 Mar 2022 23:21:47 +0100 Subject: [PATCH] fix and document player team assignement via presets --- src/game/game.cpp | 10 +++++++--- src/game/replay.cpp | 7 +++++++ src/network/network.cpp | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index d8dd1695a..97b0d21ed 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -865,10 +865,14 @@ void CreateGame(const std::string &filename, CMap *map) } CreatePlayer(playertype); if (GameSettings.Presets[i].Team != SettingsPresetMapDefault) { - int presetTeam = GameSettings.Presets[i].Team; + // why this calculation? Well. The CreatePlayer function assigns some + // default team values, starting from up to PlayerMax + some constant (2 at the time + // of this writing). So to not accidentally interfere with those teams, we assign the team + // offset by 2 * PlayerMax. + Players[i].Team = GameSettings.Presets[i].Team + 2 * PlayerMax; for (int j = 0; j < i; j++) { - if (Players[j].Team != SettingsPresetMapDefault) { - if (Players[j].Team != presetTeam) { + if (GameSettings.Presets[j].Team != SettingsPresetMapDefault) { + if (GameSettings.Presets[j].Team != GameSettings.Presets[i].Team) { Players[i].SetDiplomacyEnemyWith(Players[j]); Players[j].SetDiplomacyEnemyWith(Players[i]); } else { diff --git a/src/game/replay.cpp b/src/game/replay.cpp index 7c52ccde5..29c093df6 100644 --- a/src/game/replay.cpp +++ b/src/game/replay.cpp @@ -172,6 +172,13 @@ static FullReplay *StartReplay() // Players array. For replay, we want to store these, // generally. However, this is not true for teams, since there is // automatic handling of alliance flags for rescueable players. + // Additionally, teams are automatically created in CPlayer::Init. + // The presets team is actually not used verbatim, but instead used + // as the basis of further calculation for the actual player's team + // (see game.cpp CreateGame right after the CreatePlayer call where + // we check GameSettings.Presets[i].Team != SettingsPresetMapDefault) + // So in order for the replay to work, we must not save the actual player + // teams, but instead the preset teams. replay->ReplaySettings.Presets[i].AIScript = Players[i].AiName; // GameSettings.Presets[i].AIScript; replay->ReplaySettings.Presets[i].Race = Players[i].Race; // GameSettings.Presets[i].Race; replay->ReplaySettings.Presets[i].Team = GameSettings.Presets[i].Team; // Players[i].Team; diff --git a/src/network/network.cpp b/src/network/network.cpp index 5afe278ca..c8f253d77 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -614,6 +614,9 @@ void NetworkSendSelection(CUnit **units, int count) // Check if we have any teammates to send to bool hasteammates = false; for (int i = 0; i < NetPlayers; ++i) { + if (ThisPlayer->Index == Hosts[i].PlyNr) { + continue; // skip self + } if (Hosts[i].IsValid() && Players[Hosts[i].PlyNr].Team == ThisPlayer->Team) { hasteammates = true; break; @@ -1211,6 +1214,9 @@ void NetworkRecover() return; } for (int i = 0; i < NetPlayers; ++i) { + if (ThisPlayer->Index == Hosts[i].PlyNr) { + continue; // skip self + } CheckPlayerThatTimeOut(i); } NetworkResendCommands();