# 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 #include "unit.h" #include @@ -2576,7 +2577,12 @@ UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater(); const AttackBoost *attackBoost = currSkill->getAttackBoost(); vector candidates = unitUpdater->findUnitsInRange(this, attackBoost->radius); - vector candidateValidIdList; - candidateValidIdList.reserve(candidates.size()); + std::unordered_set candidateValidIdSet; + candidateValidIdSet.reserve(candidates.size()); + + // Build hash set of currently boosted unit IDs for O(1) membership test + std::unordered_set 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::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::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);