Skip to content

Commit 45e8bc0

Browse files
authored
Merge pull request #1913 from Flamefire/soldier-cancel
2 parents 7b5704a + 9563197 commit 45e8bc0

18 files changed

Lines changed: 134 additions & 179 deletions

external/languages

libs/s25main/buildings/nobBaseMilitary.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,8 @@ bool nobBaseMilitary::CallDefender(nofAttacker& attacker)
224224
// Stop attacking soldiers (including aggressive defenders) from leaving this building
225225
for(auto it = leave_house.begin(); it != leave_house.end();)
226226
{
227-
if(!dynamic_cast<nofActiveSoldier*>(it->get()))
228-
++it;
229-
else
227+
const auto* sldPtr = dynamic_cast<nofActiveSoldier*>(it->get());
228+
if(sldPtr && helpers::contains(troops_on_mission, sldPtr))
230229
{
231230
auto soldier = boost::static_pointer_cast<nofActiveSoldier>(std::move(*it));
232231
// At this point there shouldn't be a defender leaving as we are just requesting one
@@ -236,6 +235,12 @@ bool nobBaseMilitary::CallDefender(nofAttacker& attacker)
236235

237236
soldier->InformTargetsAboutCancelling();
238237
AddActiveSoldier(std::move(soldier));
238+
} else
239+
{
240+
// If a leaving active soldier is not on a mission he doesn't belong to this building.
241+
// E.g. soldiers in harbors could be about to go home.
242+
RTTR_Assert(!sldPtr || sldPtr->GetHomeBld() != this);
243+
++it;
239244
}
240245
}
241246
// Use existing defender (e.g. just going back in) if possible

libs/s25main/buildings/nobBaseWarehouse.cpp

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -676,15 +676,7 @@ void nobBaseWarehouse::FigureLeft(const noFigure& fig)
676676
// Adapt inventory for non-warehouse workers
677677
if(fig.MemberOfWarehouse())
678678
return;
679-
if(fig.GetJobType() == Job::BoatCarrier)
680-
{
681-
// Remove helper and boat separately
682-
inventory.visual.Remove(Job::Helper);
683-
inventory.visual.Remove(GoodType::Boat);
684-
} else
685-
inventory.visual.Remove(fig.GetJobType());
686-
687-
RemoveArmoredFigurFromVisualInventory(fig);
679+
RemoveFromVisualInventory(fig);
688680

689681
if(fig.GetGOT() == GO_Type::NofTradedonkey)
690682
{
@@ -839,38 +831,9 @@ void nobBaseWarehouse::AddFigure(std::unique_ptr<noFigure> figure, const bool in
839831
// Warenhausarbeiter werden nicht gezählt!
840832
if(!figure->MemberOfWarehouse())
841833
{
842-
// War das ein Boot-Träger?
843-
if(figure->GetJobType() == Job::BoatCarrier)
844-
{
845-
if(increase_visual_counts)
846-
{
847-
inventory.Add(Job::Helper);
848-
inventory.Add(GoodType::Boat);
849-
} else
850-
{
851-
inventory.real.Add(Job::Helper);
852-
inventory.real.Add(GoodType::Boat);
853-
}
854-
} else if(isSoldier(figure->GetJobType()))
855-
{
856-
if(increase_visual_counts)
857-
{
858-
inventory.Add(figure->GetJobType());
859-
if(figure->HasArmor())
860-
inventory.Add(jobEnumToAmoredSoldierEnum(figure->GetJobType()));
861-
} else
862-
{
863-
inventory.real.Add(figure->GetJobType());
864-
if(figure->HasArmor())
865-
inventory.real.Add(jobEnumToAmoredSoldierEnum(figure->GetJobType()));
866-
}
867-
} else
868-
{
869-
if(increase_visual_counts)
870-
inventory.Add(figure->GetJobType());
871-
else
872-
inventory.real.Add(figure->GetJobType());
873-
}
834+
AddToRealInventory(*figure);
835+
if(increase_visual_counts)
836+
AddToVisualInventory(*figure);
874837
}
875838

876839
// Check if we were actually waiting for this figure or if it was just added (e.g. builder that constructed it) to
@@ -882,19 +845,45 @@ void nobBaseWarehouse::AddFigure(std::unique_ptr<noFigure> figure, const bool in
882845
GetEvMgr().AddToKillList(std::move(figure));
883846
}
884847

885-
void nobBaseWarehouse::RemoveArmoredFigurFromVisualInventory(const noFigure& figure)
848+
void nobBaseWarehouse::RemoveFromVisualInventory(const noFigure& figure)
886849
{
887-
if(isSoldier(figure.GetJobType()) && figure.HasArmor())
850+
const auto job = figure.GetJobType();
851+
if(job == Job::BoatCarrier)
888852
{
889-
RTTR_Assert(inventory.visual[jobEnumToAmoredSoldierEnum(figure.GetJobType())] > 0);
890-
inventory.visual.Remove(jobEnumToAmoredSoldierEnum(figure.GetJobType()));
853+
// Remove helper and boat separately
854+
inventory.visual.Remove(Job::Helper);
855+
inventory.visual.Remove(GoodType::Boat);
856+
} else
857+
{
858+
inventory.visual.Remove(job);
859+
if(isSoldier(job) && figure.HasArmor())
860+
inventory.visual.Remove(jobEnumToAmoredSoldierEnum(job));
891861
}
892862
}
893863

894-
void nobBaseWarehouse::AddArmoredFigurToVisualInventory(const noFigure& figure)
864+
static void addToInventory(Inventory& inventory, const noFigure& figure)
865+
{
866+
const auto job = figure.GetJobType();
867+
if(job == Job::BoatCarrier)
868+
{
869+
inventory.Add(Job::Helper);
870+
inventory.Add(GoodType::Boat);
871+
} else
872+
{
873+
inventory.Add(job);
874+
if(isSoldier(job) && figure.HasArmor())
875+
inventory.Add(jobEnumToAmoredSoldierEnum(job));
876+
}
877+
}
878+
879+
void nobBaseWarehouse::AddToVisualInventory(const noFigure& figure)
880+
{
881+
addToInventory(inventory.visual, figure);
882+
}
883+
884+
void nobBaseWarehouse::AddToRealInventory(const noFigure& figure)
895885
{
896-
if(isSoldier(figure.GetJobType()) && figure.HasArmor())
897-
inventory.visual.Add(jobEnumToAmoredSoldierEnum(figure.GetJobType()));
886+
addToInventory(inventory.real, figure);
898887
}
899888

900889
void nobBaseWarehouse::FetchWare()

libs/s25main/buildings/nobBaseWarehouse.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ class nobBaseWarehouse : public nobBaseMilitary, public DataChangedObservable
125125
/// Recruts a worker of the given job if possible
126126
bool TryRecruitJob(Job job);
127127

128-
void RemoveArmoredFigurFromVisualInventory(const noFigure& figure);
129-
void AddArmoredFigurToVisualInventory(const noFigure& figure);
128+
void RemoveFromVisualInventory(const noFigure& figure);
129+
void AddToVisualInventory(const noFigure& figure);
130+
void AddToRealInventory(const noFigure& figure);
130131

131132
nobBaseWarehouse(BuildingType type, MapPoint pos, unsigned char player, Nation nation);
132133
nobBaseWarehouse(SerializedGameData& sgd, unsigned obj_id);

libs/s25main/buildings/nobHarborBuilding.cpp

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ void nobHarborBuilding::DestroyBuilding()
128128

129129
soldier.CancelSeaAttack();
130130
RTTR_Assert(!soldier.GetAttackedGoal());
131-
RTTR_Assert(soldier.HasNoHome());
132-
RTTR_Assert(soldier.HasNoGoal());
131+
RTTR_Assert(!soldier.GetHomeBld());
132+
RTTR_Assert(!soldier.GetGoal());
133133
soldier.StartWandering();
134134
soldier.StartWalking(RANDOM_ENUM(Direction));
135135
}
@@ -515,8 +515,7 @@ void nobHarborBuilding::ShipArrived(noShip& ship)
515515
{
516516
if(it->dest == ship_dest)
517517
{
518-
inventory.visual.Remove(it->attacker->GetJobType());
519-
RemoveArmoredFigurFromVisualInventory(*it->attacker);
518+
RemoveFromVisualInventory(*it->attacker);
520519
attackers.push_back(std::move(it->attacker));
521520
it = soldiers_for_ships.erase(it);
522521
} else
@@ -589,15 +588,7 @@ void nobHarborBuilding::ShipArrived(noShip& ship)
589588
if(it->dest == dest)
590589
{
591590
it->fig->StartShipJourney();
592-
if(it->fig->GetJobType() != Job::BoatCarrier)
593-
{
594-
inventory.visual.Remove(it->fig->GetJobType());
595-
RemoveArmoredFigurFromVisualInventory(*it->fig);
596-
} else
597-
{
598-
inventory.visual.Remove(Job::Helper);
599-
inventory.visual.Remove(GoodType::Boat);
600-
}
591+
RemoveFromVisualInventory(*it->fig);
601592
figures.push_back(std::move(it->fig));
602593
it = figures_for_ships.erase(it);
603594
} else
@@ -867,16 +858,7 @@ std::vector<nobHarborBuilding::ShipConnection> nobHarborBuilding::GetShipConnect
867858
void nobHarborBuilding::AddFigureForShip(std::unique_ptr<noFigure> fig, MapPoint dest)
868859
{
869860
RTTR_Assert(!world->HasFigureAt(fig->GetPos(), *fig)); // Figure is in the harbor, so it cannot be outside
870-
// Anzahl visuell erhöhen
871-
if(fig->GetJobType() != Job::BoatCarrier)
872-
{
873-
inventory.visual.Add(fig->GetJobType());
874-
AddArmoredFigurToVisualInventory(*fig);
875-
} else
876-
{
877-
inventory.visual.Add(Job::Helper);
878-
inventory.visual.Add(GoodType::Boat);
879-
}
861+
AddToVisualInventory(*fig);
880862
figures_for_ships.emplace_back(FigureForShip{std::move(fig), dest});
881863
OrderShip();
882864
}
@@ -1027,15 +1009,7 @@ bool nobHarborBuilding::UseFigureAtOnce(std::unique_ptr<noFigure>& fig, noRoadNo
10271009
{
10281010
// Reduce figure count because figures don't go through the house leaving process
10291011
// And therefore the visual count reducement
1030-
if(fig->GetJobType() != Job::BoatCarrier)
1031-
{
1032-
inventory.visual.Remove(fig->GetJobType());
1033-
RemoveArmoredFigurFromVisualInventory(*fig);
1034-
} else
1035-
{
1036-
inventory.visual.Remove(Job::Helper);
1037-
inventory.visual.Remove(GoodType::Boat);
1038-
}
1012+
RemoveFromVisualInventory(*fig);
10391013
// Dann fügen wir die mal bei uns hinzu
10401014
AddFigureForShip(std::move(fig), next_harbor);
10411015
return true;
@@ -1058,7 +1032,7 @@ void nobHarborBuilding::ReceiveGoodsFromShip(std::list<std::unique_ptr<noFigure>
10581032
{
10591033
figure->SetGoalTonullptr();
10601034
AddFigure(std::move(figure), true);
1061-
} else if(figure->HasNoGoal())
1035+
} else if(!figure->GetGoal())
10621036
{
10631037
AddDependentFigure(*figure); // No goal? We take it
10641038
AddFigure(std::move(figure), true);
@@ -1069,16 +1043,7 @@ void nobHarborBuilding::ReceiveGoodsFromShip(std::list<std::unique_ptr<noFigure>
10691043

10701044
if(nextDir == RoadPathDirection::SouthEast)
10711045
{
1072-
// Increase visual count
1073-
if(figure->GetJobType() == Job::BoatCarrier)
1074-
{
1075-
inventory.visual.Add(Job::Helper);
1076-
inventory.visual.Add(GoodType::Boat);
1077-
} else
1078-
{
1079-
inventory.visual.Add(figure->GetJobType());
1080-
AddArmoredFigurToVisualInventory(*figure);
1081-
}
1046+
AddToVisualInventory(*figure);
10821047
AddLeavingFigure(std::move(figure));
10831048
} else if(nextDir == RoadPathDirection::Ship)
10841049
{
@@ -1247,8 +1212,8 @@ void nobHarborBuilding::AddSeaAttacker(std::unique_ptr<nofAttacker> attacker)
12471212
// notify target about noShow, notify home that soldier wont return, add to inventory
12481213
attacker->SeaAttackFailedBeforeLaunch(); // set state, remove target & home
12491214
RTTR_Assert(!attacker->GetAttackedGoal());
1250-
RTTR_Assert(attacker->HasNoHome());
1251-
RTTR_Assert(attacker->HasNoGoal());
1215+
RTTR_Assert(!attacker->GetHomeBld());
1216+
RTTR_Assert(!attacker->GetGoal());
12521217
AddFigure(std::move(attacker), true);
12531218
return;
12541219
}
@@ -1267,7 +1232,7 @@ void nobHarborBuilding::CancelSeaAttacker(nofAttacker* attacker)
12671232
helpers::find_if(soldiers_for_ships, [attacker](const auto& it) { return it.attacker.get() == attacker; });
12681233

12691234
RTTR_Assert(it != soldiers_for_ships.end());
1270-
if(attacker->HasNoGoal())
1235+
if(!attacker->GetGoal())
12711236
{
12721237
// No goal? We take it
12731238
AddDependentFigure(*attacker);
@@ -1339,6 +1304,7 @@ std::unique_ptr<nofDefender> nobHarborBuilding::ProvideDefender(nofAttacker& att
13391304
std::unique_ptr<nofAttacker> defender_attacker = std::move(soldiers_for_ships.begin()->attacker);
13401305
soldiers_for_ships.pop_front();
13411306
defender = std::make_unique<nofDefender>(pos, player, *this, defender_attacker->GetRank(), attacker);
1307+
defender->SetArmor(defender_attacker->HasArmor());
13421308
defender_attacker->CancelSeaAttack();
13431309
defender_attacker->Destroy();
13441310
}

libs/s25main/figures/noFigure.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ noFigure::noFigure(const Job job, const MapPoint pos, const unsigned char player
6767

6868
void noFigure::Destroy()
6969
{
70-
RTTR_Assert(HasNoGoal());
70+
RTTR_Assert(!goal_);
7171
RTTR_Assert(!cur_rs);
7272
noMovable::Destroy();
7373

@@ -455,7 +455,7 @@ void noFigure::GoHome(noRoadNode* goal)
455455

456456
void noFigure::StartWandering(const unsigned burned_wh_id)
457457
{
458-
RTTR_Assert(HasNoGoal());
458+
RTTR_Assert(!goal_);
459459
fs = FigureState::Wander;
460460
cur_rs = nullptr;
461461
rs_pos = 0;

libs/s25main/figures/noFigure.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,6 @@ class noFigure : public noMovable
235235
void StartShipJourney();
236236
/// Tells the figure it arrived at a harbor at the given position
237237
void ArrivedByShip(MapPoint harborPos);
238-
/// Gibt zurück, ob die Figur kein Ziel mehr hat und damit nach einer Schifffahrt im
239-
/// Lagerhaus interniert werden muss
240-
bool HasNoGoal() const { return (goal_ == nullptr); }
241238
/// Gibt zurück, ob die Figur auf Straßen läuft zu ihrem Arbeitsplatz o.Ä.
242239
bool IsWalkingOnRoad() const
243240
{

libs/s25main/figures/nofActiveSoldier.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ void nofActiveSoldier::GoalReached()
4343
{
4444
// We reached the military building
4545
// Add myself to the building
46-
if(!building)
46+
if(!homeBld)
4747
{
4848
RTTR_Assert(false);
49-
building = world->GetSpecObj<nobMilitary>(this->GetPos());
50-
if(building)
49+
homeBld = world->GetSpecObj<nobMilitary>(this->GetPos());
50+
if(homeBld)
5151
LOG.write("nofActiveSoldier::GoalRoached() - no valid 'building' but found one at soldier's position "
5252
"(%i,%i) (gf: %u)\n")
5353
% pos.x % pos.y % GetEvMgr().GetCurrentGF();
@@ -59,7 +59,7 @@ void nofActiveSoldier::GoalReached()
5959
throw std::runtime_error("No building found for soldier");
6060
}
6161
}
62-
building->AddActiveSoldier(world->RemoveFigure(pos, *this));
62+
homeBld->AddActiveSoldier(world->RemoveFigure(pos, *this));
6363
}
6464

6565
void nofActiveSoldier::ReturnHome()
@@ -71,7 +71,7 @@ void nofActiveSoldier::ReturnHome()
7171
void nofActiveSoldier::WalkingHome()
7272
{
7373
// Is our home military building destroyed?
74-
if(!building)
74+
if(!homeBld)
7575
{
7676
// Start wandering around
7777
state = SoldierState::FigureWork;
@@ -83,13 +83,13 @@ void nofActiveSoldier::WalkingHome()
8383

8484
// Walking home to our military building
8585

86-
if(GetPos() == building->GetFlagPos()) // Are we already at the flag?
86+
if(GetPos() == homeBld->GetFlagPos()) // Are we already at the flag?
8787
StartWalking(Direction::NorthWest); // Enter via the door
88-
else if(GetPos() == building->GetPos()) // or are we at the building
89-
building->AddActiveSoldier(world->RemoveFigure(pos, *this));
88+
else if(GetPos() == homeBld->GetPos()) // or are we at the building
89+
homeBld->AddActiveSoldier(world->RemoveFigure(pos, *this));
9090
else
9191
{
92-
const auto dir = world->FindHumanPath(pos, building->GetFlagPos(), 100);
92+
const auto dir = world->FindHumanPath(pos, homeBld->GetFlagPos(), 100);
9393

9494
if(dir)
9595
{

libs/s25main/figures/nofActiveSoldier.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class nofActiveSoldier : public nofSoldier
133133
SoldierState GetState() const { return state; }
134134
/// Set the home (building) to nullptr
135135
/// e.g. after the soldier was removed from the homes list but it was not destroyed
136-
void ResetHome() { building = nullptr; }
136+
void ResetHome() { homeBld = nullptr; }
137137
void FightVsDefenderStarted() { state = SoldierState::AttackingFightingVsDefender; }
138138

139139
// For debugging

0 commit comments

Comments
 (0)