forked from mirror/openmw-tes3mp
Avoid directly iterating the actor map (Fixes #3173)
This commit is contained in:
parent
50ed061154
commit
59d2de118f
1 changed files with 18 additions and 19 deletions
|
@ -982,8 +982,11 @@ namespace MWMechanics
|
||||||
|
|
||||||
/// \todo move update logic to Actor class where appropriate
|
/// \todo move update logic to Actor class where appropriate
|
||||||
|
|
||||||
|
// make a copy of the map to avoid invalidated iterators when an actor moves during the update
|
||||||
|
PtrActorMap actors = mActors;
|
||||||
|
|
||||||
// AI and magic effects update
|
// AI and magic effects update
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
{
|
{
|
||||||
bool inProcessingRange = (player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
bool inProcessingRange = (player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
<= sqrProcessingDistance;
|
<= sqrProcessingDistance;
|
||||||
|
@ -996,6 +999,11 @@ namespace MWMechanics
|
||||||
if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
|
if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
|
||||||
{
|
{
|
||||||
updateActor(iter->first, duration);
|
updateActor(iter->first, duration);
|
||||||
|
if (MWBase::Environment::get().getWorld()->hasCellChanged())
|
||||||
|
{
|
||||||
|
return; // for now abort update of the old cell when cell changes by teleportation magic effect
|
||||||
|
// a better solution might be to apply cell changes at the end of the frame
|
||||||
|
}
|
||||||
if (MWBase::Environment::get().getMechanicsManager()->isAIActive() && inProcessingRange)
|
if (MWBase::Environment::get().getMechanicsManager()->isAIActive() && inProcessingRange)
|
||||||
{
|
{
|
||||||
if (timerUpdateAITargets == 0)
|
if (timerUpdateAITargets == 0)
|
||||||
|
@ -1003,7 +1011,7 @@ namespace MWMechanics
|
||||||
if (iter->first != player)
|
if (iter->first != player)
|
||||||
adjustCommandedActor(iter->first);
|
adjustCommandedActor(iter->first);
|
||||||
|
|
||||||
for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
|
for(PtrActorMap::iterator it(actors.begin()); it != actors.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
|
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
|
||||||
continue;
|
continue;
|
||||||
|
@ -1015,7 +1023,7 @@ namespace MWMechanics
|
||||||
float sqrHeadTrackDistance = std::numeric_limits<float>::max();
|
float sqrHeadTrackDistance = std::numeric_limits<float>::max();
|
||||||
MWWorld::Ptr headTrackTarget;
|
MWWorld::Ptr headTrackTarget;
|
||||||
|
|
||||||
for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
|
for(PtrActorMap::iterator it(actors.begin()); it != actors.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->first == iter->first)
|
if (it->first == iter->first)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1050,12 +1058,12 @@ namespace MWMechanics
|
||||||
// Reaching the text keys may trigger Hit / Spellcast (and as such, particles),
|
// Reaching the text keys may trigger Hit / Spellcast (and as such, particles),
|
||||||
// so updating VFX immediately after that would just remove the particle effects instantly.
|
// so updating VFX immediately after that would just remove the particle effects instantly.
|
||||||
// There needs to be a magic effect update in between.
|
// There needs to be a magic effect update in between.
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
iter->second->getCharacterController()->updateContinuousVfx();
|
iter->second->getCharacterController()->updateContinuousVfx();
|
||||||
|
|
||||||
// Animation/movement update
|
// Animation/movement update
|
||||||
CharacterController* playerCharacter = NULL;
|
CharacterController* playerCharacter = NULL;
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->first != player &&
|
if (iter->first != player &&
|
||||||
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
|
@ -1065,20 +1073,10 @@ namespace MWMechanics
|
||||||
if (iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
if (iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
||||||
iter->second->getCharacterController()->skipAnim();
|
iter->second->getCharacterController()->skipAnim();
|
||||||
|
|
||||||
// Handle player last, in case a cell transition occurs by casting a teleportation spell
|
|
||||||
// (would invalidate the iterator)
|
|
||||||
if (iter->first == getPlayer())
|
|
||||||
{
|
|
||||||
playerCharacter = iter->second->getCharacterController();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
iter->second->getCharacterController()->update(duration);
|
iter->second->getCharacterController()->update(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerCharacter)
|
for(PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
playerCharacter->update(duration);
|
|
||||||
|
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
const MWWorld::Class &cls = iter->first.getClass();
|
const MWWorld::Class &cls = iter->first.getClass();
|
||||||
CreatureStats &stats = cls.getCreatureStats(iter->first);
|
CreatureStats &stats = cls.getCreatureStats(iter->first);
|
||||||
|
@ -1136,7 +1134,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool detected = false;
|
bool detected = false;
|
||||||
|
|
||||||
for (PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for (PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->first == player) // not the player
|
if (iter->first == player) // not the player
|
||||||
continue;
|
continue;
|
||||||
|
@ -1179,7 +1177,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
void Actors::killDeadActors()
|
void Actors::killDeadActors()
|
||||||
{
|
{
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
PtrActorMap actors = mActors;
|
||||||
|
for(PtrActorMap::iterator iter(actors.begin()); iter != actors.end(); ++iter)
|
||||||
{
|
{
|
||||||
const MWWorld::Class &cls = iter->first.getClass();
|
const MWWorld::Class &cls = iter->first.getClass();
|
||||||
CreatureStats &stats = cls.getCreatureStats(iter->first);
|
CreatureStats &stats = cls.getCreatureStats(iter->first);
|
||||||
|
@ -1210,7 +1209,7 @@ namespace MWMechanics
|
||||||
++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())];
|
++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())];
|
||||||
|
|
||||||
// Make sure spell effects are removed
|
// Make sure spell effects are removed
|
||||||
for (PtrActorMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2)
|
for (PtrActorMap::iterator iter2(actors.begin());iter2 != actors.end();++iter2)
|
||||||
{
|
{
|
||||||
MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells();
|
MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells();
|
||||||
spells.purge(stats.getActorId());
|
spells.purge(stats.getActorId());
|
||||||
|
|
Loading…
Reference in a new issue