Skip to content

Commit

Permalink
Improve Phobos warhead effect CellSpread behaviour (Phobos-developers…
Browse files Browse the repository at this point in the history
…#1267)

* Improve Phobos warhead effect CellSpread behaviour

* YEET
  • Loading branch information
Starkku authored May 22, 2024
1 parent fab37f1 commit 4add0a0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
2 changes: 1 addition & 1 deletion YRpp
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
41 changes: 33 additions & 8 deletions src/Utilities/Helpers.Alex.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@

#include "Debug.h"

#include <AircraftTrackerClass.h>
#include <BuildingClass.h>
#include <BuildingTypeClass.h>
#include <CellSpread.h>
#include <Unsorted.h>
#include <Helpers/Iterators.h>
#include <Helpers/Enumerators.h>

Expand Down Expand Up @@ -174,33 +176,53 @@ namespace Helpers {
\author AlexB
\date 2010-06-28
\modifications by Starkku
\date 2024-05-20
*/
inline std::vector<TechnoClass*> getCellSpreadItems(
CoordStruct const& coords, double const spread,
bool const includeInAir = false)
{
// set of possibly affected objects. every object can be here only once.
DistinctCollector<TechnoClass*> 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;
auto const range = static_cast<size_t>(spread + 0.99);
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<TechnoClass*>(*obj)) {
if (auto const pTechno = abstract_cast<TechnoClass*>(*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);
}
}
Expand All @@ -213,13 +235,15 @@ 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) {
auto const pBuilding = static_cast<BuildingClass*>(pTechno);
if (pBuilding->Type->InvisibleInGame) {
continue;
}
isBuilding = true;
}

// get distance from impact site
Expand All @@ -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);
}
}
Expand Down

0 comments on commit 4add0a0

Please sign in to comment.