Skip to content

Commit 5aef739

Browse files
authored
Merge pull request #1961 from tost11/feature/fix-emergency-protocol
fixed emergency protocol by removing sheduled wares requested before ...
2 parents 5e064ee + 1fd8fe0 commit 5aef739

21 files changed

Lines changed: 185 additions & 47 deletions

extras/ai-battle/HeadlessGame.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ void HeadlessGame::RecordReplay(const bfs::path& path, unsigned random_init)
157157
mapInfo.luaData.CompressFromFile(luaPath_, &mapInfo.luaChecksum);
158158
}
159159

160-
for(unsigned playerId = 0; playerId < world_.GetNumPlayers(); ++playerId)
161-
replay_.AddPlayer(world_.GetPlayer(playerId));
160+
for(auto& player : world_.getPlayers())
161+
replay_.AddPlayer(player);
162162
replay_.ggs = game_.ggs_;
163163
if(!replay_.StartRecording(path, mapInfo, random_init))
164164
throw std::runtime_error("Replayfile could not be opened!");
@@ -170,8 +170,8 @@ void HeadlessGame::SaveGame(const bfs::path& path) const
170170
bfs::remove(path);
171171

172172
Savegame save;
173-
for(unsigned playerId = 0; playerId < world_.GetNumPlayers(); ++playerId)
174-
save.AddPlayer(world_.GetPlayer(playerId));
173+
for(auto& player : world_.getPlayers())
174+
save.AddPlayer(player);
175175
save.ggs = game_.ggs_;
176176
save.ggs.exploration = Exploration::Disabled; // no FOW
177177
save.start_gf = em_.GetCurrentGF();
@@ -220,9 +220,8 @@ void HeadlessGame::PrintState()
220220
printConsole("┌────────────────────────┬─────────────────┬─────────────┬───────────┬───────────┐\n");
221221
printConsole("│ Player │ Country │ Buildings │ Military │ Gold │\n");
222222
printConsole("├────────────────────────┼─────────────────┼─────────────┼───────────┼───────────┤\n");
223-
for(unsigned playerId = 0; playerId < world_.GetNumPlayers(); ++playerId)
223+
for(const auto& player : world_.getPlayers())
224224
{
225-
const GamePlayer& player = world_.GetPlayer(playerId);
226225
printConsole("│ %s%-22s%s │ %15s │ %11s │ %9s │ %9s │\n", player.IsDefeated() ? "\x1b[9m" : "",
227226
player.name.c_str(), player.IsDefeated() ? "\x1b[29m" : "",
228227
HumanReadableNumber(player.GetStatisticCurrentValue(StatisticType::Country)).c_str(),

libs/s25main/Game.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ namespace {
6161
unsigned getNumAlivePlayers(const GameWorldBase& world)
6262
{
6363
unsigned numPlayersAlive = 0;
64-
for(unsigned i = 0; i < world.GetNumPlayers(); ++i)
64+
for(const auto& player : world.getPlayers())
6565
{
66-
if(!world.GetPlayer(i).IsDefeated())
66+
if(!player.IsDefeated())
6767
++numPlayersAlive;
6868
}
6969
return numPlayersAlive;
@@ -76,9 +76,8 @@ void Game::RunGF()
7676
// EventManager Bescheid sagen
7777
em_->ExecuteNextGF();
7878
// Notfallprogramm durchlaufen lassen
79-
for(unsigned i = 0; i < world_.GetNumPlayers(); ++i)
79+
for(GamePlayer& player : world_.getPlayers())
8080
{
81-
GamePlayer& player = world_.GetPlayer(i);
8281
if(player.isUsed())
8382
{
8483
// Auf Notfall testen (Wenige Bretter/Steine und keine Holzindustrie)
@@ -100,8 +99,8 @@ void Game::RunGF()
10099

101100
void Game::StatisticStep()
102101
{
103-
for(unsigned i = 0; i < world_.GetNumPlayers(); ++i)
104-
world_.GetPlayer(i).StatisticStep();
102+
for(auto& player : world_.getPlayers())
103+
player.StatisticStep();
105104

106105
CheckObjective();
107106
}

libs/s25main/GamePlayer.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,12 @@ void GamePlayer::FindWarehouseForAllJobs(const Job job)
889889
}
890890
}
891891

892+
static bool IsWareFineWithEmergencyProtocol(GoodType goodType, const noBaseBuilding& goal)
893+
{
894+
return (goodType != GoodType::Boards && goodType != GoodType::Stones)
895+
|| goal.GetBuildingType() == BuildingType::Woodcutter || goal.GetBuildingType() == BuildingType::Sawmill;
896+
}
897+
892898
Ware* GamePlayer::OrderWare(const GoodType ware, noBaseBuilding& goal)
893899
{
894900
/// Gibt es ein Lagerhaus mit dieser Ware?
@@ -902,8 +908,7 @@ Ware* GamePlayer::OrderWare(const GoodType ware, noBaseBuilding& goal)
902908
else
903909
{
904910
// Wenn Notfallprogramm aktiv nur an Holzfäller und Sägewerke Bretter/Steine liefern
905-
if((ware != GoodType::Boards && ware != GoodType::Stones)
906-
|| goal.GetBuildingType() == BuildingType::Woodcutter || goal.GetBuildingType() == BuildingType::Sawmill)
911+
if(IsWareFineWithEmergencyProtocol(ware, goal))
907912
return wh->OrderWare(ware, goal);
908913
else
909914
return nullptr;
@@ -2089,6 +2094,23 @@ bool GamePlayer::FindHarborForUnloading(noShip* ship, const MapPoint start, Harb
20892094
return false;
20902095
}
20912096

2097+
void GamePlayer::CancelWaresForEmergencyProtocol()
2098+
{
2099+
for(auto it = ware_list.begin(); it != ware_list.end();)
2100+
{
2101+
Ware* ware = *it;
2102+
if(ware->IsWaitingInWarehouse() && ware->GetGoal()
2103+
&& !IsWareFineWithEmergencyProtocol(ware->type, *ware->GetGoal()))
2104+
{
2105+
ware->NotifyGoalAboutLostWare();
2106+
static_cast<nobBaseWarehouse*>(ware->GetLocation())->CancelWare(ware);
2107+
it = ware_list.erase(it);
2108+
continue;
2109+
}
2110+
it++;
2111+
}
2112+
}
2113+
20922114
void GamePlayer::TestForEmergencyProgramm()
20932115
{
20942116
// we are already defeated, do not even think about an emergency program - it's too late :-(
@@ -2118,6 +2140,9 @@ void GamePlayer::TestForEmergencyProgramm()
21182140
emergency = true;
21192141
SendPostMessage(std::make_unique<PostMsg>(
21202142
world.GetEvMgr().GetCurrentGF(), _("The emergency program has been activated."), PostCategory::Economy));
2143+
2144+
// Handle wares already ordered
2145+
CancelWaresForEmergencyProtocol();
21212146
}
21222147
} else
21232148
{

libs/s25main/GamePlayer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ class GamePlayer : public GamePlayerInfo
331331
const Statistic& GetStatistic(StatisticTime time) const { return statistic[time]; };
332332
unsigned GetStatisticCurrentValue(StatisticType idx) const { return statisticCurrentData[idx]; }
333333

334+
// Stop wares restricted in emergency mode that are waiting in warehouse to be transported already
335+
void CancelWaresForEmergencyProtocol();
334336
// Testet ob Notfallprogramm aktiviert werden muss und tut dies dann
335337
void TestForEmergencyProgramm();
336338
bool hasEmergency() const { return emergency; }

libs/s25main/SerializedGameData.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,13 @@ void SerializedGameData::MakeSnapshot(const Game& game)
258258
PushObject(gw.getEconHandler(), true);
259259
}
260260
// Spieler serialisieren
261-
for(unsigned i = 0; i < gw.GetNumPlayers(); ++i)
261+
for(const auto& player : gw.getPlayers())
262262
{
263263
if(debugMode)
264-
LOG.write("Start serializing player %1% at %2%\n") % i % GetLength();
265-
gw.GetPlayer(i).Serialize(*this);
264+
LOG.write("Start serializing player %1% at %2%\n") % player.GetPlayerId() % GetLength();
265+
player.Serialize(*this);
266266
if(debugMode)
267-
LOG.write("Done serializing player %1% at %2%\n") % i % GetLength();
267+
LOG.write("Done serializing player %1% at %2%\n") % player.GetPlayerId() % GetLength();
268268
}
269269

270270
if(writtenEventIds.size() != writeEm->GetNumActiveEvents())
@@ -301,8 +301,8 @@ void SerializedGameData::ReadSnapshot(Game& game, ILocalGameState& localGameStat
301301
std::unique_ptr<EconomyModeHandler>(PopObject<EconomyModeHandler>(GO_Type::Economymodehandler)));
302302
}
303303

304-
for(unsigned i = 0; i < gw.GetNumPlayers(); ++i)
305-
gw.GetPlayer(i).Deserialize(*this);
304+
for(auto& player : gw.getPlayers())
305+
player.Deserialize(*this);
306306

307307
// If this check fails, we did not serialize all objects or there was an async
308308
if(readEvents.size() != em->GetNumActiveEvents())

libs/s25main/ingameWindows/iwStatistics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ iwStatistics::iwStatistics(const GameWorldViewer& gwv)
8282
// Count active players
8383
numPlayingPlayers = 0;
8484
const GameWorldBase& world = gwv.GetWorld();
85-
for(const auto i : helpers::range(world.GetNumPlayers()))
85+
for(const auto& player : world.getPlayers())
8686
{
87-
if(world.GetPlayer(i).isUsed())
87+
if(player.isUsed())
8888
numPlayingPlayers++;
8989
}
9090

libs/s25main/network/GameClient.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ void GameClient::StartGame(const unsigned random_init)
327327
{
328328
RTTR_Assert(mapinfo.type != MapType::Savegame);
329329
/// Startbündnisse setzen
330-
for(unsigned i = 0; i < gameWorld.GetNumPlayers(); ++i)
331-
gameWorld.GetPlayer(i).MakeStartPacts();
330+
for(auto& player : gameWorld.getPlayers())
331+
player.MakeStartPacts();
332332

333333
MapLoader loader(gameWorld);
334334
if(!loader.Load(mapinfo.filepath)
@@ -1580,8 +1580,8 @@ bool GameClient::StartReplay(const boost::filesystem::path& path)
15801580
idx++;
15811581
}
15821582

1583-
for(unsigned i = 0; i < game->world_.GetNumPlayers(); i++)
1584-
game->world_.GetPlayer(i).ChangeDistribution(newDistributions);
1583+
for(auto& player : game->world_.getPlayers())
1584+
player.ChangeDistribution(newDistributions);
15851585
}
15861586

15871587
replayinfo->next_gf = replayinfo->replay.ReadGF();

libs/s25main/world/GameWorldBase.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ unsigned GameWorldBase::GetNumPlayers() const
6666
return players.size();
6767
}
6868

69+
s25util::span<GamePlayer> GameWorldBase::getPlayers()
70+
{
71+
return players;
72+
}
73+
74+
s25util::span<const GamePlayer> GameWorldBase::getPlayers() const
75+
{
76+
return players;
77+
}
78+
6979
bool GameWorldBase::IsSinglePlayer() const
7080
{
7181
bool foundPlayer = false;

libs/s25main/world/GameWorldBase.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
22
//
33
// SPDX-License-Identifier: GPL-2.0-or-later
44

@@ -12,6 +12,7 @@
1212
#include "notifications/NotificationManager.h"
1313
#include "postSystem/PostManager.h"
1414
#include "world/World.h"
15+
#include "s25util/span.hpp"
1516
#include <memory>
1617
#include <set>
1718
#include <vector>
@@ -158,6 +159,8 @@ class GameWorldBase : public World
158159
GamePlayer& GetPlayer(unsigned id);
159160
const GamePlayer& GetPlayer(unsigned id) const;
160161
unsigned GetNumPlayers() const;
162+
s25util::span<GamePlayer> getPlayers();
163+
s25util::span<const GamePlayer> getPlayers() const;
161164
bool IsSinglePlayer() const;
162165
/// Return the game settings
163166
const GlobalGameSettings& GetGGS() const { return gameSettings; }

0 commit comments

Comments
 (0)