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

71 lines
4.2 KiB
Diff

# UNDF: UNDF-2026-000000982
--- a/source/glest_game/type_instances/unit.cpp
+++ b/source/glest_game/type_instances/unit.cpp
@@ -2,6 +2,7 @@
// unit.cpp
//
+#include <unordered_set>
#include "unit.h"
#include <cassert>
@@ -2576,7 +2577,12 @@
UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater();
const AttackBoost *attackBoost = currSkill->getAttackBoost();
vector<Unit *> candidates = unitUpdater->findUnitsInRange(this, attackBoost->radius);
- vector<int> candidateValidIdList;
- candidateValidIdList.reserve(candidates.size());
+ std::unordered_set<int> candidateValidIdSet;
+ candidateValidIdSet.reserve(candidates.size());
+
+ // Build hash set of currently boosted unit IDs for O(1) membership test
+ std::unordered_set<int> boostedIdSet(
+ currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(),
+ currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end());
if (debugBoost)
printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER " attackBoost: %s\n", __LINE__, candidates.size(),
@@ -2585,9 +2591,9 @@
for (unsigned int i = 0; i < candidates.size(); ++i) {
Unit *affectedUnit = candidates[i];
- candidateValidIdList.push_back(affectedUnit->getId());
+ candidateValidIdSet.insert(affectedUnit->getId());
- std::vector<int>::iterator iterFound = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(),
- currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit->getId());
+ bool alreadyBoosted = boostedIdSet.count(affectedUnit->getId()) > 0;
if (attackBoost->isAffected(this, affectedUnit) == true) {
- if (iterFound == currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
+ if (!alreadyBoosted) {
if (affectedUnit->applyAttackBoost(attackBoost, this) == true) {
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit->getId());
+ boostedIdSet.insert(affectedUnit->getId());
}
}
} else {
- if (iterFound != currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
+ if (alreadyBoosted) {
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
- currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase(iterFound);
+ auto eraseIt = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(),
+ currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit->getId());
+ if (eraseIt != currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
+ currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase(eraseIt);
+ }
+ boostedIdSet.erase(affectedUnit->getId());
}
}
}
@@ -2616,7 +2622,7 @@
if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false) {
for (int i = (int)currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() - 1; i >= 0; --i) {
int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
- std::vector<int>::iterator iterFound = std::find(candidateValidIdList.begin(), candidateValidIdList.end(), findUnitId);
- if (iterFound == candidateValidIdList.end()) {
+ if (candidateValidIdSet.count(findUnitId) == 0) {
Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId);
if (affectedUnit != NULL) {
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);