From 4add0a0c8b7ec3d8e4053e3b755231b0f87cbd75 Mon Sep 17 00:00:00 2001 From: Starkku Date: Wed, 22 May 2024 09:39:02 +0300 Subject: [PATCH] Improve Phobos warhead effect CellSpread behaviour (#1267) * Improve Phobos warhead effect CellSpread behaviour * YEET --- YRpp | 2 +- docs/Whats-New.md | 2 ++ src/Utilities/Helpers.Alex.h | 41 +++++++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/YRpp b/YRpp index 19aa8decac..7e09d81767 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 19aa8decac255e44364b395ae7ce787d9b85c7e1 +Subproject commit 7e09d81767fa915c8250fd467f64daf2e3cb206b diff --git a/docs/Whats-New.md b/docs/Whats-New.md index dcf1022835..2f15cc38a8 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -20,6 +20,7 @@ You can use the migration utility (can be found on [Phobos supplementaries repo] #### From post-0.3 devbuilds +- Phobos Warhead effects combined with `CellSpread` now correctly apply to buildings if any of the foundation cells are hit instead of only the top-left most cell (cell #0). - `ExtraWarheads.DamageOverrides` now falls back to last listed value if list is shorter than `ExtraWarheads` for all Warhead detonations exceeding the length. - Air and Top layer contents are no longer sorted, animations in these layers no longer respect `YSortAdjust`. Animations attached to flying units now get their layer updated immediately after parent unit, if they are on same layer they will draw above the parent unit. - `AnimList.ShowOnZeroDamage` has been renamed to `CreateAnimsOnZeroDamage` to make it more clear it applies to both `AnimList` and splash animations. @@ -501,6 +502,7 @@ Phobos fixes: - Fixed heal / repair weapons being unable to remove parasites from shielded targets if they were unable to heal / repair the parent unit (by Starkku) - Fixed `Inviso=true` interceptor projectiles applying damage on interceptable, armor type-having projectiles twice (by Starkku) - Fixed `AutoDeath` causing crashes when used to kill a parasite unit inside an another unit (by Starkku) +- Phobos Warhead effects combined with `CellSpread` now correctly apply to buildings if any of the foundation cells are hit (by Starkku) Fixes / interactions with other extensions: - All forms of type conversion (including Ares') now correctly update `OpenTopped` state of passengers in transport that is converted (by Starkku) diff --git a/src/Utilities/Helpers.Alex.h b/src/Utilities/Helpers.Alex.h index 439604c864..8abc10ce73 100644 --- a/src/Utilities/Helpers.Alex.h +++ b/src/Utilities/Helpers.Alex.h @@ -34,9 +34,11 @@ #include "Debug.h" +#include #include #include #include +#include #include #include @@ -174,6 +176,9 @@ namespace Helpers { \author AlexB \date 2010-06-28 + + \modifications by Starkku + \date 2024-05-20 */ inline std::vector getCellSpreadItems( CoordStruct const& coords, double const spread, @@ -181,6 +186,7 @@ namespace Helpers { { // set of possibly affected objects. every object can be here only once. DistinctCollector set; + double const spreadMult = spread * Unsorted::LeptonsPerCell; // the quick way. only look at stuff residing on the very cells we are affecting. auto const cellCoords = MapClass::Instance->GetCellAt(coords)->MapCoords; @@ -188,19 +194,35 @@ namespace Helpers { for (CellSpreadEnumerator it(range); it; ++it) { auto const pCell = MapClass::Instance->GetCellAt(*it + cellCoords); for (NextObject obj(pCell->GetContent()); obj; ++obj) { - if (auto const pTechno = abstract_cast(*obj)) { + if (auto const pTechno = abstract_cast(*obj)) + { + // Starkku: Buildings need their distance from the origin coords checked at cell level. + if (pTechno->WhatAmI() == AbstractType::Building) + { + auto const dist = pCell->GetCenterCoords().DistanceFrom(coords); + + if (dist > spreadMult) + continue; + } + set.insert(pTechno); } } } // flying objects are not included normally - if (includeInAir) { - // the not quite so fast way. skip everything not in the air. - for (auto const& pTechno : *TechnoClass::Array) { - if (pTechno->GetHeight() > 0) { - // rough estimation - if (pTechno->Location.DistanceFrom(coords) <= spread * Unsorted::LeptonsPerCell) { + // Starkku: Reimplemented using AircraftTrackerClass. + if (includeInAir) + { + auto const airTracker = &AircraftTrackerClass::Instance.get(); + airTracker->SetArea(MapClass::Instance->GetCellAt(coords), Game::F2I(spread)); + + for (auto pTechno = airTracker->Get(); pTechno; pTechno = airTracker->Get()) + { + if (pTechno->IsAlive && pTechno->IsOnMap && pTechno->Health > 0) + { + if (pTechno->Location.DistanceFrom(coords) <= spreadMult) + { set.insert(pTechno); } } @@ -213,6 +235,7 @@ namespace Helpers { for (auto const& pTechno : set) { auto const abs = pTechno->WhatAmI(); + bool isBuilding = false; // ignore buildings that are not visible, like ambient light posts if (abs == AbstractType::Building) { @@ -220,6 +243,7 @@ namespace Helpers { if (pBuilding->Type->InvisibleInGame) { continue; } + isBuilding = true; } // get distance from impact site @@ -232,7 +256,8 @@ namespace Helpers { } // this is good - if (dist <= spread * Unsorted::LeptonsPerCell) { + // Starkku: Building distance is checked prior on cell level, skip here. + if (isBuilding || dist <= spreadMult) { ret.push_back(pTechno); } }