diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 283b5d2b2..4d87637a5 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -309,6 +309,12 @@ namespace MWMechanics void Actors::updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor, MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance) { + if (!actor.getRefData().getBaseNode()) + return; + + if (targetActor.getClass().getCreatureStats(targetActor).isDead()) + return; + static const float fMaxHeadTrackDistance = MWBase::Environment::get().getWorld()->getStore().get() .find("fMaxHeadTrackDistance")->mValue.getFloat(); static const float fInteriorHeadTrackMult = MWBase::Environment::get().getWorld()->getStore().get() @@ -318,22 +324,16 @@ namespace MWMechanics if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx)) maxDistance *= fInteriorHeadTrackMult; - const ESM::Position& actor1Pos = actor.getRefData().getPosition(); - const ESM::Position& actor2Pos = targetActor.getRefData().getPosition(); - float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2(); + const osg::Vec3f actor1Pos(actor.getRefData().getPosition().asVec3()); + const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3()); + float sqrDist = (actor1Pos - actor2Pos).length2(); if (sqrDist > maxDistance*maxDistance) return; - if (targetActor.getClass().getCreatureStats(targetActor).isDead()) - return; - - if (!actor.getRefData().getBaseNode()) - return; - // stop tracking when target is behind the actor osg::Vec3f actorDirection = actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0); - osg::Vec3f targetDirection (actor2Pos.asVec3() - actor1Pos.asVec3()); + osg::Vec3f targetDirection(actor2Pos - actor1Pos); actorDirection.z() = 0; targetDirection.z() = 0; actorDirection.normalize(); @@ -350,25 +350,25 @@ namespace MWMechanics void Actors::engageCombat (const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map >& cachedAllies, bool againstPlayer) { + // No combat for totally static creatures + if (!actor1.getClass().isMobile(actor1)) + return; + CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1); - if (creatureStats1.getAiSequence().isInCombat(actor2)) + if (creatureStats1.isDead() || creatureStats1.getAiSequence().isInCombat(actor2)) return; const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2); - if (creatureStats1.isDead() || creatureStats2.isDead()) + if (creatureStats2.isDead()) return; - const ESM::Position& actor1Pos = actor1.getRefData().getPosition(); - const ESM::Position& actor2Pos = actor2.getRefData().getPosition(); - float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2(); + const osg::Vec3f actor1Pos(actor1.getRefData().getPosition().asVec3()); + const osg::Vec3f actor2Pos(actor2.getRefData().getPosition().asVec3()); + float sqrDist = (actor1Pos - actor2Pos).length2(); if (sqrDist > mActorsProcessingRange*mActorsProcessingRange) return; - // No combat for totally static creatures - if (!actor1.getClass().isMobile(actor1)) - return; - // If this is set to true, actor1 will start combat with actor2 if the awareness check at the end of the method returns true bool aggressive = false; @@ -379,22 +379,22 @@ namespace MWMechanics getActorsSidingWith(actor1, allies1, cachedAllies); // If an ally of actor1 has been attacked by actor2 or has attacked actor2, start combat between actor1 and actor2 - for (std::set::const_iterator it = allies1.begin(); it != allies1.end(); ++it) + for (const MWWorld::Ptr &ally : allies1) { - if (creatureStats1.getAiSequence().isInCombat(*it)) + if (creatureStats1.getAiSequence().isInCombat(ally)) continue; - if (creatureStats2.matchesActorId(it->getClass().getCreatureStats(*it).getHitAttemptActorId())) + if (creatureStats2.matchesActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId())) { MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2); // Also set the same hit attempt actor. Otherwise, if fighting the player, they may stop combat // if the player gets out of reach, while the ally would continue combat with the player - creatureStats1.setHitAttemptActorId(it->getClass().getCreatureStats(*it).getHitAttemptActorId()); - return; + creatureStats1.setHitAttemptActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId()); + return; } // If there's been no attack attempt yet but an ally of actor1 is in combat with actor2, become aggressive to actor2 - if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2)) + if (ally.getClass().getCreatureStats(ally).getAiSequence().isInCombat(actor2)) aggressive = true; } @@ -415,20 +415,24 @@ namespace MWMechanics getActorsSidingWith(actor2, allies2, cachedAllies); // Check that an ally of actor2 is also in combat with actor1 - for (std::set::const_iterator it = allies2.begin(); it != allies2.end(); ++it) + for (const MWWorld::Ptr &ally2 : allies2) { - if ((it)->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor1)) + if (ally2.getClass().getCreatureStats(ally2).getAiSequence().isInCombat(actor1)) { MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2); // Also have actor1's allies start combat - for (std::set::const_iterator it2 = allies1.begin(); it2 != allies1.end(); ++it2) - MWBase::Environment::get().getMechanicsManager()->startCombat(*it2, actor2); + for (const MWWorld::Ptr ally1 : allies1) + MWBase::Environment::get().getMechanicsManager()->startCombat(ally1, actor2); return; } } } } + // Stop here if target is unreachable + if (!canFight(actor1, actor2)) + return; + // If set in the settings file, player followers and escorters will become aggressive toward enemies in combat with them or the player static const bool followersAttackOnSight = Settings::Manager::getBool("followers attack on sight", "Game"); if (!aggressive && isPlayerFollowerOrEscorter && followersAttackOnSight) @@ -437,9 +441,9 @@ namespace MWMechanics aggressive = true; else { - for (std::set::const_iterator it = allies1.begin(); it != allies1.end(); ++it) + for (const MWWorld::Ptr &ally : allies1) { - if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(*it)) + if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(ally)) { aggressive = true; break; @@ -448,10 +452,6 @@ namespace MWMechanics } } - // Stop here if target is unreachable - if (!MWMechanics::canFight(actor1, actor2)) - return; - // Do aggression check if actor2 is the player or a player follower or escorter if (!aggressive) { @@ -465,7 +465,7 @@ namespace MWMechanics } // Make guards go aggressive with creatures that are in combat, unless the creature is a follower or escorter - if (actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc()) + if (!aggressive && actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc() && creatureStats2.getAiSequence().isInCombat()) { // Check if the creature is too far static const float fAlarmRadius = MWBase::Environment::get().getWorld()->getStore().get().find("fAlarmRadius")->mValue.getFloat(); @@ -473,18 +473,18 @@ namespace MWMechanics return; bool followerOrEscorter = false; - for (std::list::const_iterator it = creatureStats2.getAiSequence().begin(); it != creatureStats2.getAiSequence().end(); ++it) + for (const AiPackage* package : creatureStats2.getAiSequence()) { // The follow package must be first or have nothing but combat before it - if ((*it)->sideWithTarget()) + if (package->sideWithTarget()) { followerOrEscorter = true; break; } - else if ((*it)->getTypeId() != MWMechanics::AiPackage::TypeIdCombat) + else if (package->getTypeId() != MWMechanics::AiPackage::TypeIdCombat) break; } - if (!followerOrEscorter && creatureStats2.getAiSequence().isInCombat()) + if (!followerOrEscorter) aggressive = true; } @@ -927,14 +927,11 @@ namespace MWMechanics if (stats.getTimeToStartDrowning() == -1.f) stats.setTimeToStartDrowning(fHoldBreathTime); - if (stats.getTimeToStartDrowning() < fHoldBreathTime / 2) + if (!isPlayer && stats.getTimeToStartDrowning() < fHoldBreathTime / 2) { - if(!isPlayer) - { - MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence(); - if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdBreathe) //Only add it once - seq.stack(MWMechanics::AiBreathe(), ptr); - } + AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence(); + if (seq.getTypeId() != AiPackage::TypeIdBreathe) //Only add it once + seq.stack(AiBreathe(), ptr); } MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -1200,17 +1197,16 @@ namespace MWMechanics } // Otherwise check if any actor in AI processing range sees the target actor - std::vector actors; + std::vector neighbors; osg::Vec3f position (actor.getRefData().getPosition().asVec3()); - getObjectsInRange(position, mActorsProcessingRange, actors); - for(std::vector::iterator it = actors.begin(); it != actors.end(); ++it) + getObjectsInRange(position, mActorsProcessingRange, neighbors); + for (const MWWorld::Ptr &neighbor : neighbors) { - if (*it == actor) + if (neighbor == actor) continue; - bool result = - MWBase::Environment::get().getWorld()->getLOS(*it, actor) && - MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, *it); + bool result = MWBase::Environment::get().getWorld()->getLOS(neighbor, actor); + result &= MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, neighbor); if (result) return true; @@ -1830,21 +1826,21 @@ namespace MWMechanics // An actor counts as siding with this actor if Follow or Escort is the current AI package, or there are only Combat and Wander packages before the Follow/Escort package // Actors that are targeted by this actor's Follow or Escort packages also side with them - for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package) + for (const AiPackage* package : stats.getAiSequence()) { - if ((*package)->sideWithTarget() && !(*package)->getTarget().isEmpty()) + if (package->sideWithTarget() && !package->getTarget().isEmpty()) { if (sameActor) { - list.push_back((*package)->getTarget()); + list.push_back(package->getTarget()); } - else if ((*package)->getTarget() == actor) + else if (package->getTarget() == actor) { list.push_back(iteratedActor); } break; } - else if ((*package)->getTypeId() != AiPackage::TypeIdCombat && (*package)->getTypeId() != AiPackage::TypeIdWander) + else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) break; } } @@ -1866,11 +1862,11 @@ namespace MWMechanics // An actor counts as following if AiFollow is the current AiPackage, // or there are only Combat and Wander packages before the AiFollow package - for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package) + for (const AiPackage* package : stats.getAiSequence()) { - if ((*package)->followTargetThroughDoors() && (*package)->getTarget() == actor) + if (package->followTargetThroughDoors() && package->getTarget() == actor) list.push_back(iteratedActor); - else if ((*package)->getTypeId() != AiPackage::TypeIdCombat && (*package)->getTypeId() != AiPackage::TypeIdWander) + else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) break; } } @@ -1879,16 +1875,16 @@ namespace MWMechanics void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) { std::list followers = getActorsFollowing(actor); - for(std::list::iterator it = followers.begin();it != followers.end();++it) - if (out.insert(*it).second) - getActorsFollowing(*it, out); + for(const MWWorld::Ptr &follower : followers) + if (out.insert(follower).second) + getActorsFollowing(follower, out); } void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out) { std::list followers = getActorsSidingWith(actor); - for(std::list::iterator it = followers.begin();it != followers.end();++it) - if (out.insert(*it).second) - getActorsSidingWith(*it, out); + for(const MWWorld::Ptr &follower : followers) + if (out.insert(follower).second) + getActorsSidingWith(follower, out); } void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, std::map >& cachedAllies) { @@ -1899,17 +1895,17 @@ namespace MWMechanics else { std::list followers = getActorsSidingWith(actor); - for (std::list::iterator it = followers.begin(); it != followers.end(); ++it) - if (out.insert(*it).second) - getActorsSidingWith(*it, out, cachedAllies); + for (const MWWorld::Ptr &follower : followers) + if (out.insert(follower).second) + getActorsSidingWith(follower, out, cachedAllies); // Cache ptrs and their sets of allies cachedAllies.insert(std::make_pair(actor, out)); - for (std::set::const_iterator it = out.begin(); it != out.end(); ++it) + for (const MWWorld::Ptr &iter : out) { - search = cachedAllies.find(*it); + search = cachedAllies.find(iter); if (search == cachedAllies.end()) - cachedAllies.insert(std::make_pair(*it, out)); + cachedAllies.insert(std::make_pair(iter, out)); } } } @@ -1929,14 +1925,14 @@ namespace MWMechanics // An actor counts as following if AiFollow is the current AiPackage, // or there are only Combat and Wander packages before the AiFollow package - for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package) + for (AiPackage* package : stats.getAiSequence()) { - if ((*package)->followTargetThroughDoors() && (*package)->getTarget() == actor) + if (package->followTargetThroughDoors() && package->getTarget() == actor) { - list.push_back(static_cast(*package)->getFollowIndex()); + list.push_back(static_cast(package)->getFollowIndex()); break; } - else if ((*package)->getTypeId() != AiPackage::TypeIdCombat && (*package)->getTypeId() != AiPackage::TypeIdWander) + else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) break; } } @@ -1948,17 +1944,17 @@ namespace MWMechanics std::vector neighbors; osg::Vec3f position (actor.getRefData().getPosition().asVec3()); getObjectsInRange(position, mActorsProcessingRange, neighbors); - for(auto neighbor = neighbors.begin(); neighbor != neighbors.end(); ++neighbor) + for(const MWWorld::Ptr neighbor : neighbors) { - if (*neighbor == actor) + if (neighbor == actor) continue; - const CreatureStats &stats = neighbor->getClass().getCreatureStats(*neighbor); + const CreatureStats &stats = neighbor.getClass().getCreatureStats(neighbor); if (stats.isDead()) continue; if (stats.getAiSequence().isInCombat(actor)) - list.push_front(*neighbor); + list.push_front(neighbor); } return list; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3c540a9d4..224321383 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -129,10 +129,9 @@ namespace MWMechanics npcStats.getSkill (i).setBase (5 + bonus); } - for (std::vector::const_iterator iter (race->mPowers.mList.begin()); - iter!=race->mPowers.mList.end(); ++iter) + for (const std::string power : race->mPowers.mList) { - creatureStats.getSpells().add (*iter); + creatureStats.getSpells().add(power); } } @@ -145,10 +144,9 @@ namespace MWMechanics const ESM::BirthSign *sign = esmStore.get().find(signId); - for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); - iter!=sign->mPowers.mList.end(); ++iter) + for (const std::string power : sign->mPowers.mList) { - creatureStats.getSpells().add (*iter); + creatureStats.getSpells().add(power); } } @@ -218,8 +216,8 @@ namespace MWMechanics std::vector selectedSpells = autoCalcPlayerSpells(skills, attributes, race); - for (std::vector::iterator it = selectedSpells.begin(); it != selectedSpells.end(); ++it) - creatureStats.getSpells().add(*it); + for (const std::string spell : selectedSpells) + creatureStats.getSpells().add(spell); // forced update and current value adjustments mActors.updateActor (ptr, 0); @@ -887,9 +885,8 @@ namespace MWMechanics // Build a list of known bound item ID's const MWWorld::Store &gameSettings = MWBase::Environment::get().getWorld()->getStore().get(); - for (MWWorld::Store::iterator currentIteration = gameSettings.begin(); currentIteration != gameSettings.end(); ++currentIteration) + for (const ESM::GameSetting ¤tSetting : gameSettings) { - const ESM::GameSetting ¤tSetting = *currentIteration; std::string currentGMSTID = currentSetting.mId; Misc::StringUtils::lowerCaseInPlace(currentGMSTID); @@ -1209,36 +1206,20 @@ namespace MWMechanics // Did anyone see it? bool crimeSeen = false; - for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) + for (const MWWorld::Ptr &neighbor : neighbors) { - if (*it == player) - continue; // skip player - if (it->getClass().getCreatureStats(*it).isDead()) + if (!canReportCrime(neighbor, victim, playerFollowers)) continue; - // Unconsious actor can not report about crime - if (it->getClass().getCreatureStats(*it).getKnockedDown()) - continue; - - if ((*it == victim && victimAware) - || (MWBase::Environment::get().getWorld()->getLOS(player, *it) && awarenessCheck(player, *it) ) + if ((neighbor == victim && victimAware) // Murder crime can be reported even if no one saw it (hearing is enough, I guess). // TODO: Add mod support for stealth executions! - || (type == OT_Murder && *it != victim)) + || (type == OT_Murder && neighbor != victim) + || (MWBase::Environment::get().getWorld()->getLOS(player, neighbor) && awarenessCheck(player, neighbor))) { - // Crime reporting only applies to NPCs - if (!it->getClass().isNpc()) - continue; - - if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(victim)) - continue; - - if (playerFollowers.find(*it) != playerFollowers.end()) - continue; - // NPC will complain about theft even if he will do nothing about it if (type == OT_Theft || type == OT_Pickpocket) - MWBase::Environment::get().getDialogueManager()->say(*it, "thief"); + MWBase::Environment::get().getDialogueManager()->say(neighbor, "thief"); crimeSeen = true; } @@ -1361,66 +1342,66 @@ namespace MWMechanics getActorsSidingWith(player, playerFollowers); // Tell everyone (including the original reporter) in alarm range - for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) + for (const MWWorld::Ptr &actor : neighbors) { - if (!canReportCrime(*it, victim, playerFollowers)) + if (!canReportCrime(actor, victim, playerFollowers)) continue; // Will the witness report the crime? - if (it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase() >= 100) + if (actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Alarm).getBase() >= 100) { reported = true; if (type == OT_Trespassing) - MWBase::Environment::get().getDialogueManager()->say(*it, "intruder"); + MWBase::Environment::get().getDialogueManager()->say(actor, "intruder"); } } - for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) + for (const MWWorld::Ptr &actor : neighbors) { - if (!canReportCrime(*it, victim, playerFollowers)) + if (!canReportCrime(actor, victim, playerFollowers)) continue; - if (it->getClass().isClass(*it, "guard") && reported) + if (reported && actor.getClass().isClass(actor, "guard")) { // Mark as Alarmed for dialogue - it->getClass().getCreatureStats(*it).setAlarmed(true); + actor.getClass().getCreatureStats(actor).setAlarmed(true); // Set the crime ID, which we will use to calm down participants // once the bounty has been paid. - it->getClass().getNpcStats(*it).setCrimeId(id); + actor.getClass().getNpcStats(actor).setCrimeId(id); - if (!it->getClass().getCreatureStats(*it).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) + if (!actor.getClass().getCreatureStats(actor).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) { - it->getClass().getCreatureStats(*it).getAiSequence().stack(AiPursue(player), *it); + actor.getClass().getCreatureStats(actor).getAiSequence().stack(AiPursue(player), actor); } } else { - float dispTerm = (*it == victim) ? dispVictim : disp; + float dispTerm = (actor == victim) ? dispVictim : disp; - float alarmTerm = 0.01f * it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase(); + float alarmTerm = 0.01f * actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Alarm).getBase(); if (type == OT_Pickpocket && alarmTerm <= 0) alarmTerm = 1.0; - if (*it != victim) + if (actor != victim) dispTerm *= alarmTerm; - float fightTerm = static_cast((*it == victim) ? fightVictim : fight); + float fightTerm = static_cast((actor == victim) ? fightVictim : fight); fightTerm += getFightDispositionBias(dispTerm); - fightTerm += getFightDistanceBias(*it, player); + fightTerm += getFightDistanceBias(actor, player); fightTerm *= alarmTerm; - int observerFightRating = it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Fight).getBase(); + int observerFightRating = actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Fight).getBase(); if (observerFightRating + fightTerm > 100) fightTerm = static_cast(100 - observerFightRating); fightTerm = std::max(0.f, fightTerm); if (observerFightRating + fightTerm >= 100) { - startCombat(*it, player); + startCombat(actor, player); - NpcStats& observerStats = it->getClass().getNpcStats(*it); + NpcStats& observerStats = actor.getClass().getNpcStats(actor); // Apply aggression value to the base Fight rating, so that the actor can continue fighting // after a Calm spell wears off observerStats.setAiSetting(CreatureStats::AI_Fight, observerFightRating + static_cast(fightTerm)); @@ -1527,7 +1508,7 @@ namespace MWMechanics bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker) { - MWMechanics::AiSequence seq = target.getClass().getCreatureStats(target).getAiSequence(); + const MWMechanics::AiSequence& seq = target.getClass().getCreatureStats(target).getAiSequence(); return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) && !isAggressive(target, attacker) && !seq.isEngagedWithActor() && !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue); @@ -1871,23 +1852,25 @@ namespace MWMechanics windowManager->setWerewolfOverlay(werewolf); // Witnesses of the player's transformation will make them a globally known werewolf - std::vector closeActors; + std::vector neighbors; const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), closeActors); + getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), neighbors); bool detected = false, reported = false; - for (std::vector::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it) + for (const MWWorld::Ptr& neighbor : neighbors) { - if (*it == actor) + if (neighbor == actor || !neighbor.getClass().isNpc()) continue; - if (!it->getClass().isNpc()) - continue; - - if (MWBase::Environment::get().getWorld()->getLOS(*it, actor) && awarenessCheck(actor, *it)) + if (MWBase::Environment::get().getWorld()->getLOS(neighbor, actor) && awarenessCheck(actor, neighbor)) + { detected = true; - if (it->getClass().getCreatureStats(*it).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0) - reported = true; + if (neighbor.getClass().getCreatureStats(neighbor).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0) + { + reported = true; + break; + } + } } if (detected)