java-topology/defects/warzone2100-0001/patch/warzone2100-0001.patch

86 lines
3.2 KiB
Diff

# UNDF: UNDF-2026-000000975
--- a/src/projectiledef.h
+++ b/src/projectiledef.h
@@ -22,7 +22,7 @@
#ifndef __INCLUDED_PROJECTILEDEF_H__
#define __INCLUDED_PROJECTILEDEF_H__
-#include "basedef.h"
+#include "basedef.h" // SIMPLE_OBJECT, BASE_OBJECT, OBJ_PROJECTILE
#include "lib/gamelib/gtime.h"
-#include <vector>
+#include <unordered_set>
enum PROJ_STATE
@@ -49,7 +49,7 @@
WEAPON_STATS *psWStats; ///< firing weapon stats
BASE_OBJECT *psSource; ///< what fired the projectile
BASE_OBJECT *psDest; ///< target of this projectile
- std::vector<BASE_OBJECT *> psDamaged; ///< the targets that have already been dealt damage to (don't damage the same target twice)
+ std::unordered_set<BASE_OBJECT *> psDamaged; ///< the targets that have already been dealt damage to (O(1) lookup instead of O(N) linear scan)
Vector3i src = Vector3i(0, 0, 0); ///< Where projectile started
Vector3i dst = Vector3i(0, 0, 0); ///< The target coordinates
--- a/src/projectile.cpp
+++ b/src/projectile.cpp
@@ -376,7 +376,7 @@
psProj->rot.direction, psProj->rot.pitch, psProj->rot.roll,
psProj->state,
(int)psProj->expectedDamageCaused,
- (int)psProj->psDamaged.size(),
+ (int)psProj->psDamaged.size(), // unchanged: .size() works on unordered_set
};
_syncDebugIntList(function, "%c projectile = p%d;pos(%d,%d,%d),rot(%d,%d,%d),state%d,expectedDamageCaused%d,numberDamaged%u", list, ARRAY_SIZE(list));
}
@@ -869,7 +869,7 @@
BASE_OBJECT *psTempObj = *gi;
CHECK_OBJECT(psTempObj);
- if (std::find(psProj->psDamaged.begin(), psProj->psDamaged.end(), psTempObj) != psProj->psDamaged.end())
+ if (psProj->psDamaged.count(psTempObj) != 0)
{
// Dont damage one target twice
continue;
@@ -950,7 +950,7 @@
asWeap.nStat = psStats - asWeaponStats.data();
// Assume we damaged the chosen target
- psProj->psDamaged.push_back(closestCollisionObject);
+ psProj->psDamaged.insert(closestCollisionObject);
spawnedProjectile = proj_SendProjectileInternal(&asWeap, psProj, psProj->player, psProj->dst, nullptr, true, -1);
}
@@ -1290,7 +1290,7 @@
if (relativeDamage >= 0) // So long as the target wasn't killed
{
- psObj->psDamaged.push_back(psObj->psDest);
+ psObj->psDamaged.insert(psObj->psDest);
}
}
}
@@ -1396,7 +1396,10 @@
setProjectileDestination(psObj, nullptr);
}
// Remove dead objects from psDamaged.
- psDamaged.erase(std::remove_if(psDamaged.begin(), psDamaged.end(), [](const BASE_OBJECT *psObj) { return ::isDead(psObj); }), psDamaged.end());
+ for (auto it = psDamaged.begin(); it != psDamaged.end(); )
+ {
+ it = ::isDead(*it) ? psDamaged.erase(it) : std::next(it);
+ }
// This extra check fixes a crash in cam2, mission1
if (worldOnMap(psObj->pos.x, psObj->pos.y) == false)
@@ -1954,9 +1957,9 @@
checkObject(psProjectile->psSource, location_description, function, recurse - 1);
}
- for (unsigned n = 0; n != psProjectile->psDamaged.size(); ++n)
+ for (const auto *psObj : psProjectile->psDamaged)
{
- checkObject(psProjectile->psDamaged[n], location_description, function, recurse - 1);
+ checkObject(psObj, location_description, function, recurse - 1);
}
}