From e01f1ea5a0f48dd003b0853320eec8d5ddd3a5b5 Mon Sep 17 00:00:00 2001 From: Saurtron Date: Tue, 17 Dec 2024 16:18:16 +0100 Subject: [PATCH 1/4] Call selectedUnitsHandler.RemoveUnit when a unit is killed. --- rts/Sim/Units/Unit.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rts/Sim/Units/Unit.cpp b/rts/Sim/Units/Unit.cpp index 9f1ec62fbd..bbf4f1c79c 100644 --- a/rts/Sim/Units/Unit.cpp +++ b/rts/Sim/Units/Unit.cpp @@ -480,6 +480,10 @@ void CUnit::ForcedKillUnit(CUnit* attacker, bool selfDestruct, bool reclaimed, i // release attached units ReleaseTransportees(attacker, selfDestruct, reclaimed); + // release from selection + if (isSelected) + selectedUnitsHandler.RemoveUnit(this); + // pre-destruction event; unit may be kept around for its death sequence eventHandler.UnitDestroyed(this, attacker, weaponDefID); eoh->UnitDestroyed(*this, attacker, weaponDefID); From f22e9f9d3edaf4ea4730ee28d2db7e12125a5efa Mon Sep 17 00:00:00 2001 From: Saurtron Date: Fri, 20 Dec 2024 12:49:56 +0100 Subject: [PATCH 2/4] Don't allow selecting if dead. --- rts/Game/SelectedUnitsHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rts/Game/SelectedUnitsHandler.cpp b/rts/Game/SelectedUnitsHandler.cpp index 473da42b76..55428f32e6 100644 --- a/rts/Game/SelectedUnitsHandler.cpp +++ b/rts/Game/SelectedUnitsHandler.cpp @@ -397,7 +397,7 @@ void CSelectedUnitsHandler::AddUnit(CUnit* unit) if (trans != nullptr && trans->unitDef->IsTransportUnit() && !trans->unitDef->isFirePlatform) return; - if (unit->noSelect) + if (unit->noSelect || unit->isDead) return; if (selectedUnits.insert(unit->id).second) @@ -475,7 +475,7 @@ void CSelectedUnitsHandler::SelectGroup(int num) for (const int unitID: group->units) { CUnit* u = unitHandler.GetUnit(unitID); - if (!u->noSelect) { + if (!u->noSelect && !u->isDead) { u->isSelected = true; selectedUnits.insert(u->id); AddDeathDependence(u, DEPENDENCE_SELECTED); From b97bf6ff1ea8c1fcdc753568de90560411aefb9a Mon Sep 17 00:00:00 2001 From: Saurtron Date: Fri, 20 Dec 2024 13:04:32 +0100 Subject: [PATCH 3/4] Set noSelect to true instead of hardcoding check for isDead inside SelectedUnitsHandler. --- rts/Game/SelectedUnitsHandler.cpp | 4 ++-- rts/Sim/Units/Unit.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rts/Game/SelectedUnitsHandler.cpp b/rts/Game/SelectedUnitsHandler.cpp index 55428f32e6..473da42b76 100644 --- a/rts/Game/SelectedUnitsHandler.cpp +++ b/rts/Game/SelectedUnitsHandler.cpp @@ -397,7 +397,7 @@ void CSelectedUnitsHandler::AddUnit(CUnit* unit) if (trans != nullptr && trans->unitDef->IsTransportUnit() && !trans->unitDef->isFirePlatform) return; - if (unit->noSelect || unit->isDead) + if (unit->noSelect) return; if (selectedUnits.insert(unit->id).second) @@ -475,7 +475,7 @@ void CSelectedUnitsHandler::SelectGroup(int num) for (const int unitID: group->units) { CUnit* u = unitHandler.GetUnit(unitID); - if (!u->noSelect && !u->isDead) { + if (!u->noSelect) { u->isSelected = true; selectedUnits.insert(u->id); AddDeathDependence(u, DEPENDENCE_SELECTED); diff --git a/rts/Sim/Units/Unit.cpp b/rts/Sim/Units/Unit.cpp index bbf4f1c79c..6c23cf6051 100644 --- a/rts/Sim/Units/Unit.cpp +++ b/rts/Sim/Units/Unit.cpp @@ -481,6 +481,7 @@ void CUnit::ForcedKillUnit(CUnit* attacker, bool selfDestruct, bool reclaimed, i ReleaseTransportees(attacker, selfDestruct, reclaimed); // release from selection + noSelect = true; if (isSelected) selectedUnitsHandler.RemoveUnit(this); From a2552c8c80e6a44fccd6c7c72fff29548ce30c44 Mon Sep 17 00:00:00 2001 From: Saurtron Date: Fri, 20 Dec 2024 13:12:59 +0100 Subject: [PATCH 4/4] Add selectableKilled modrule to control whether dead units can be selected (defaults to true for backwards compatibility). --- rts/Sim/Misc/ModInfo.cpp | 7 +++++++ rts/Sim/Misc/ModInfo.h | 3 +++ rts/Sim/Units/Unit.cpp | 8 +++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/rts/Sim/Misc/ModInfo.cpp b/rts/Sim/Misc/ModInfo.cpp index 08aade523c..4e7723b5dc 100644 --- a/rts/Sim/Misc/ModInfo.cpp +++ b/rts/Sim/Misc/ModInfo.cpp @@ -131,6 +131,9 @@ void CModInfo::ResetState() // make windChangeReportPeriod equal to EnvResourceHandler::WIND_UPDATE_RATE = 15 * GAME_SPEED; windChangeReportPeriod = 15 * GAME_SPEED; } + { + selectableKilled = true; + } } void CModInfo::Init(const std::string& modFileName) @@ -341,6 +344,10 @@ void CModInfo::Init(const std::string& modFileName) windChangeReportPeriod = static_cast(math::roundf(misc.GetFloat("windChangeReportPeriod", static_cast(windChangeReportPeriod) / GAME_SPEED) * GAME_SPEED)); } + { + //selection + selectableKilled = root.GetBool("selectableKilled", selectableKilled); + } if (!std::has_single_bit (quadFieldQuadSizeInElmos)) throw content_error("quadFieldQuadSizeInElmos modrule has to be a power of 2"); diff --git a/rts/Sim/Misc/ModInfo.h b/rts/Sim/Misc/ModInfo.h index 825c8d223a..e91b77900b 100644 --- a/rts/Sim/Misc/ModInfo.h +++ b/rts/Sim/Misc/ModInfo.h @@ -237,6 +237,9 @@ class CModInfo // how often to report wind speed/direction to wind gens int windChangeReportPeriod; + + // selection behaviour + bool selectableKilled; }; extern CModInfo modInfo; diff --git a/rts/Sim/Units/Unit.cpp b/rts/Sim/Units/Unit.cpp index 6c23cf6051..c90746f56d 100644 --- a/rts/Sim/Units/Unit.cpp +++ b/rts/Sim/Units/Unit.cpp @@ -481,9 +481,11 @@ void CUnit::ForcedKillUnit(CUnit* attacker, bool selfDestruct, bool reclaimed, i ReleaseTransportees(attacker, selfDestruct, reclaimed); // release from selection - noSelect = true; - if (isSelected) - selectedUnitsHandler.RemoveUnit(this); + if (!modInfo.selectableKilled) { + noSelect = true; + if (isSelected) + selectedUnitsHandler.RemoveUnit(this); + } // pre-destruction event; unit may be kept around for its death sequence eventHandler.UnitDestroyed(this, attacker, weaponDefID);