From 36c4e56528873ce438c1b9dba7f9b9658c1be05e Mon Sep 17 00:00:00 2001 From: TomGoodIdea <108272452+TomGoodIdea@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:46:52 +0200 Subject: [PATCH] fix(mechanics): Improve handling of orders when the selected escort is destroyed (#10459) - After a player ship has finished exploding, it is no longer considered "selected" and so will no longer block orders to the wider fleet. - If orders are issued while all selected ships are exploding, a new message indicating that they cannot follow orders will be used, instead of the normal message indicating that orders have been issued. --- source/AI.cpp | 25 +++++++++++++++++++++---- source/Engine.cpp | 3 +++ source/PlayerInfo.cpp | 12 ++++++++++++ source/PlayerInfo.h | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/source/AI.cpp b/source/AI.cpp index 34792689e473..9d6c45504943 100644 --- a/source/AI.cpp +++ b/source/AI.cpp @@ -4832,25 +4832,42 @@ void AI::IssueOrders(const Orders &newOrders, const string &description) // Figure out what ships we are giving orders to. vector ships; + size_t destroyedCount = 0; if(player.SelectedShips().empty()) { for(const shared_ptr &it : player.Ships()) if(it.get() != player.Flagship() && !it->IsParked()) - ships.push_back(it.get()); - who = ships.size() > 1 ? "Your fleet is " : "Your escort is "; + { + if(it->IsDestroyed()) + ++destroyedCount; + else + ships.push_back(it.get()); + } + who = (ships.empty() ? destroyedCount : ships.size()) > 1 + ? "Your fleet is " : "Your escort is "; } else { for(const weak_ptr &it : player.SelectedShips()) { shared_ptr ship = it.lock(); - if(ship) + if(!ship) + continue; + if(ship->IsDestroyed()) + ++destroyedCount; + else ships.push_back(ship.get()); } - who = ships.size() > 1 ? "The selected escorts are " : "The selected escort is "; + who = (ships.empty() ? destroyedCount : ships.size()) > 1 + ? "The selected escorts are " : "The selected escort is "; } if(ships.empty()) + { + if(destroyedCount) + Messages::Add(who + "destroyed and unable to execute your orders.", + Messages::Importance::High); return; + } Point centerOfGravity; bool isMoveOrder = (newOrders.HasMoveTo()); diff --git a/source/Engine.cpp b/source/Engine.cpp index 4be71637fd01..ed061cb53720 100644 --- a/source/Engine.cpp +++ b/source/Engine.cpp @@ -1700,6 +1700,9 @@ void Engine::MoveShip(const shared_ptr &ship) for(const auto &bay : ship->Bays()) if(bay.ship) eventQueue.emplace_back(nullptr, bay.ship, ShipEvent::DESTROY); + // If this is a player ship, make sure it's no longer selected. + if(ship->IsYours()) + player.DeselectShip(ship.get()); } return; } diff --git a/source/PlayerInfo.cpp b/source/PlayerInfo.cpp index 51095570592a..4aabbe9bae82 100644 --- a/source/PlayerInfo.cpp +++ b/source/PlayerInfo.cpp @@ -2777,6 +2777,18 @@ void PlayerInfo::SelectShip(const Ship *ship, bool hasShift) +void PlayerInfo::DeselectShip(const Ship *ship) +{ + for(auto it = selectedShips.begin(); it != selectedShips.end(); ++it) + if(it->lock().get() == ship) + { + selectedShips.erase(it); + return; + } +} + + + void PlayerInfo::SelectGroup(int group, bool hasShift) { int bit = (1 << group); diff --git a/source/PlayerInfo.h b/source/PlayerInfo.h index c71198cd33ea..9392ad7daf38 100644 --- a/source/PlayerInfo.h +++ b/source/PlayerInfo.h @@ -307,6 +307,7 @@ class PlayerInfo { bool SelectShips(const Rectangle &box, bool hasShift); bool SelectShips(const std::vector &stack, bool hasShift); void SelectShip(const Ship *ship, bool hasShift); + void DeselectShip(const Ship *ship); void SelectGroup(int group, bool hasShift); void SetGroup(int group, const std::set *newShips = nullptr); std::set GetGroup(int group);