1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00

Store AI packages as unique_ptr

This commit is contained in:
elsid 2020-05-17 00:29:21 +02:00
parent ce7c47ee12
commit b67e18329e
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
4 changed files with 58 additions and 72 deletions

View File

@ -112,11 +112,11 @@ void adjustCommandedActor (const MWWorld::Ptr& actor)
bool hasCommandPackage = false; bool hasCommandPackage = false;
std::list<MWMechanics::AiPackage*>::const_iterator it; auto it = stats.getAiSequence().begin();
for (it = stats.getAiSequence().begin(); it != stats.getAiSequence().end(); ++it) for (; it != stats.getAiSequence().end(); ++it)
{ {
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow && if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow &&
static_cast<MWMechanics::AiFollow*>(*it)->isCommanded()) static_cast<const MWMechanics::AiFollow*>(it->get())->isCommanded())
{ {
hasCommandPackage = true; hasCommandPackage = true;
break; break;
@ -419,7 +419,7 @@ namespace MWMechanics
if (world->isSwimming(actor) || (playerPos - actorPos).length2() >= 3000 * 3000) if (world->isSwimming(actor) || (playerPos - actorPos).length2() >= 3000 * 3000)
return; return;
// Our implementation is not FPS-dependent unlike Morrowind's so it needs to be recalibrated. // Our implementation is not FPS-dependent unlike Morrowind's so it needs to be recalibrated.
// We chose to use the chance MW would have when run at 60 FPS with the default value of the GMST. // We chose to use the chance MW would have when run at 60 FPS with the default value of the GMST.
const float delta = MWBase::Environment::get().getFrameDuration() * 6.f; const float delta = MWBase::Environment::get().getFrameDuration() * 6.f;
static const float fVoiceIdleOdds = world->getStore().get<ESM::GameSetting>().find("fVoiceIdleOdds")->mValue.getFloat(); static const float fVoiceIdleOdds = world->getStore().get<ESM::GameSetting>().find("fVoiceIdleOdds")->mValue.getFloat();
@ -435,9 +435,9 @@ namespace MWMechanics
CreatureStats &stats = actor.getClass().getCreatureStats(actor); CreatureStats &stats = actor.getClass().getCreatureStats(actor);
MWMechanics::AiSequence& seq = stats.getAiSequence(); MWMechanics::AiSequence& seq = stats.getAiSequence();
if (!seq.isEmpty() && seq.getActivePackage()->useVariableSpeed()) if (!seq.isEmpty() && seq.getActivePackage().useVariableSpeed())
{ {
osg::Vec3f targetPos = seq.getActivePackage()->getDestination(); osg::Vec3f targetPos = seq.getActivePackage().getDestination();
osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3();
float distance = (targetPos - actorPos).length(); float distance = (targetPos - actorPos).length();
if (distance < DECELERATE_DISTANCE) if (distance < DECELERATE_DISTANCE)
@ -604,7 +604,7 @@ namespace MWMechanics
bool isPlayerFollowerOrEscorter = playerAllies.find(actor1) != playerAllies.end(); bool isPlayerFollowerOrEscorter = playerAllies.find(actor1) != playerAllies.end();
// If actor2 and at least one actor2 are in combat with actor1, actor1 and its allies start combat with them // If actor2 and at least one actor2 are in combat with actor1, actor1 and its allies start combat with them
// Doesn't apply for player followers/escorters // Doesn't apply for player followers/escorters
if (!aggressive && !isPlayerFollowerOrEscorter) if (!aggressive && !isPlayerFollowerOrEscorter)
{ {
// Check that actor2 is in combat with actor1 // Check that actor2 is in combat with actor1
@ -673,7 +673,7 @@ namespace MWMechanics
return; return;
bool followerOrEscorter = false; bool followerOrEscorter = false;
for (const AiPackage* package : creatureStats2.getAiSequence()) for (const auto& package : creatureStats2.getAiSequence())
{ {
// The follow package must be first or have nothing but combat before it // The follow package must be first or have nothing but combat before it
if (package->sideWithTarget()) if (package->sideWithTarget())
@ -1738,7 +1738,7 @@ namespace MWMechanics
if (!isPlayer && isConscious(iter->first) && !stats.isParalyzed()) if (!isPlayer && isConscious(iter->first) && !stats.isParalyzed())
{ {
MWMechanics::AiSequence& seq = stats.getAiSequence(); MWMechanics::AiSequence& seq = stats.getAiSequence();
alwaysActive = !seq.isEmpty() && seq.getActivePackage()->alwaysActive(); alwaysActive = !seq.isEmpty() && seq.getActivePackage().alwaysActive();
} }
bool inRange = isPlayer || dist <= mActorsProcessingRange || alwaysActive; bool inRange = isPlayer || dist <= mActorsProcessingRange || alwaysActive;
int activeFlag = 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower) int activeFlag = 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower)
@ -2158,7 +2158,7 @@ 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 // 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 // Actors that are targeted by this actor's Follow or Escort packages also side with them
for (const AiPackage* package : stats.getAiSequence()) for (const auto& package : stats.getAiSequence())
{ {
if (package->sideWithTarget() && !package->getTarget().isEmpty()) if (package->sideWithTarget() && !package->getTarget().isEmpty())
{ {
@ -2192,9 +2192,9 @@ namespace MWMechanics
if (stats.isDead()) if (stats.isDead())
continue; continue;
// An actor counts as following if AiFollow is the current AiPackage, // An actor counts as following if AiFollow is the current AiPackage,
// or there are only Combat and Wander packages before the AiFollow package // or there are only Combat and Wander packages before the AiFollow package
for (const AiPackage* package : stats.getAiSequence()) for (const auto& package : stats.getAiSequence())
{ {
if (package->followTargetThroughDoors() && package->getTarget() == actor) if (package->followTargetThroughDoors() && package->getTarget() == actor)
list.push_back(iteratedActor); list.push_back(iteratedActor);
@ -2257,11 +2257,11 @@ namespace MWMechanics
// An actor counts as following if AiFollow is the current AiPackage, // An actor counts as following if AiFollow is the current AiPackage,
// or there are only Combat and Wander packages before the AiFollow package // or there are only Combat and Wander packages before the AiFollow package
for (AiPackage* package : stats.getAiSequence()) for (const auto& package : stats.getAiSequence())
{ {
if (package->followTargetThroughDoors() && package->getTarget() == actor) if (package->followTargetThroughDoors() && package->getTarget() == actor)
{ {
list.push_back(static_cast<AiFollow*>(package)->getFollowIndex()); list.push_back(static_cast<const AiFollow*>(package.get())->getFollowIndex());
break; break;
} }
else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander)

View File

@ -25,9 +25,8 @@ namespace MWMechanics
void AiSequence::copy (const AiSequence& sequence) void AiSequence::copy (const AiSequence& sequence)
{ {
for (std::list<AiPackage *>::const_iterator iter (sequence.mPackages.begin()); for (const auto& package : sequence.mPackages)
iter!=sequence.mPackages.end(); ++iter) mPackages.push_back(package->clone());
mPackages.push_back ((*iter)->clone().release());
// We need to keep an AiWander storage, if present - it has a state machine. // We need to keep an AiWander storage, if present - it has a state machine.
// Not sure about another temporary storages // Not sure about another temporary storages
@ -74,7 +73,7 @@ bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const
{ {
if (getTypeId() != AiPackage::TypeIdCombat) if (getTypeId() != AiPackage::TypeIdCombat)
return false; return false;
targetActor = mPackages.front()->getTarget(); targetActor = mPackages.front()->getTarget();
return !targetActor.isEmpty(); return !targetActor.isEmpty();
@ -82,7 +81,7 @@ bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const
bool AiSequence::getCombatTargets(std::vector<MWWorld::Ptr> &targetActors) const bool AiSequence::getCombatTargets(std::vector<MWWorld::Ptr> &targetActors) const
{ {
for (std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdCombat) if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdCombat)
targetActors.push_back((*it)->getTarget()); targetActors.push_back((*it)->getTarget());
@ -91,24 +90,23 @@ bool AiSequence::getCombatTargets(std::vector<MWWorld::Ptr> &targetActors) const
return !targetActors.empty(); return !targetActors.empty();
} }
std::list<AiPackage*>::const_iterator AiSequence::begin() const std::list<std::unique_ptr<AiPackage>>::const_iterator AiSequence::begin() const
{ {
return mPackages.begin(); return mPackages.begin();
} }
std::list<AiPackage*>::const_iterator AiSequence::end() const std::list<std::unique_ptr<AiPackage>>::const_iterator AiSequence::end() const
{ {
return mPackages.end(); return mPackages.end();
} }
void AiSequence::erase(std::list<AiPackage*>::const_iterator package) void AiSequence::erase(std::list<std::unique_ptr<AiPackage>>::const_iterator package)
{ {
// Not sure if manually terminated packages should trigger mDone, probably not? // Not sure if manually terminated packages should trigger mDone, probably not?
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ++it) for(auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if (package == it) if (package == it)
{ {
delete *it;
mPackages.erase(it); mPackages.erase(it);
return; return;
} }
@ -118,7 +116,7 @@ void AiSequence::erase(std::list<AiPackage*>::const_iterator package)
bool AiSequence::isInCombat() const bool AiSequence::isInCombat() const
{ {
for(std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
return true; return true;
@ -128,7 +126,7 @@ bool AiSequence::isInCombat() const
bool AiSequence::isEngagedWithActor() const bool AiSequence::isEngagedWithActor() const
{ {
for (std::list<AiPackage *>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
{ {
@ -142,7 +140,7 @@ bool AiSequence::isEngagedWithActor() const
bool AiSequence::hasPackage(int typeId) const bool AiSequence::hasPackage(int typeId) const
{ {
for (std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == typeId) if ((*it)->getTypeId() == typeId)
return true; return true;
@ -152,7 +150,7 @@ bool AiSequence::hasPackage(int typeId) const
bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const
{ {
for(std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
{ {
@ -165,11 +163,10 @@ bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const
void AiSequence::stopCombat() void AiSequence::stopCombat()
{ {
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ) for(auto it = mPackages.begin(); it != mPackages.end(); )
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
{ {
delete *it;
it = mPackages.erase(it); it = mPackages.erase(it);
} }
else else
@ -179,11 +176,10 @@ void AiSequence::stopCombat()
void AiSequence::stopPursuit() void AiSequence::stopPursuit()
{ {
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ) for(auto it = mPackages.begin(); it != mPackages.end(); )
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdPursue) if ((*it)->getTypeId() == AiPackage::TypeIdPursue)
{ {
delete *it;
it = mPackages.erase(it); it = mPackages.erase(it);
} }
else else
@ -213,7 +209,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
} }
auto packageIt = mPackages.begin(); auto packageIt = mPackages.begin();
MWMechanics::AiPackage* package = *packageIt; MWMechanics::AiPackage* package = packageIt->get();
if (!package->alwaysActive() && outOfRange) if (!package->alwaysActive() && outOfRange)
return; return;
@ -231,7 +227,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
float bestRating = 0.f; float bestRating = 0.f;
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end();) for (auto it = mPackages.begin(); it != mPackages.end();)
{ {
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break; if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break;
@ -240,7 +236,6 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
// target disappeared (e.g. summoned creatures) // target disappeared (e.g. summoned creatures)
if (target.isEmpty()) if (target.isEmpty())
{ {
delete *it;
it = mPackages.erase(it); it = mPackages.erase(it);
} }
else else
@ -276,24 +271,23 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
} }
packageIt = mPackages.begin(); packageIt = mPackages.begin();
package = *packageIt; package = packageIt->get();
packageTypeId = package->getTypeId(); packageTypeId = package->getTypeId();
} }
try try
{ {
if (package->execute (actor, characterController, mAiState, duration)) if (package->execute(actor, characterController, mAiState, duration))
{ {
// Put repeating noncombat AI packages on the end of the stack so they can be used again // Put repeating noncombat AI packages on the end of the stack so they can be used again
if (isActualAiPackage(packageTypeId) && (mRepeat || package->getRepeat())) if (isActualAiPackage(packageTypeId) && (mRepeat || package->getRepeat()))
{ {
package->reset(); package->reset();
mPackages.push_back(package->clone().release()); mPackages.push_back(package->clone());
} }
// To account for the rare case where AiPackage::execute() queued another AI package // To account for the rare case where AiPackage::execute() queued another AI package
// (e.g. AiPursue executing a dialogue script that uses startCombat) // (e.g. AiPursue executing a dialogue script that uses startCombat)
mPackages.erase(packageIt); mPackages.erase(packageIt);
delete package;
if (isActualAiPackage(packageTypeId)) if (isActualAiPackage(packageTypeId))
mDone = true; mDone = true;
} }
@ -311,9 +305,6 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
void AiSequence::clear() void AiSequence::clear()
{ {
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
delete *iter;
mPackages.clear(); mPackages.clear();
} }
@ -340,8 +331,7 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
osg::Vec3f dest; osg::Vec3f dest;
if (currentTypeId == MWMechanics::AiPackage::TypeIdWander) if (currentTypeId == MWMechanics::AiPackage::TypeIdWander)
{ {
AiPackage* activePackage = getActivePackage(); dest = getActivePackage().getDestination(actor);
dest = activePackage->getDestination(actor);
} }
else else
{ {
@ -355,11 +345,10 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
// remove previous packages if required // remove previous packages if required
if (cancelOther && package.shouldCancelPreviousAi()) if (cancelOther && package.shouldCancelPreviousAi())
{ {
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end();) for (auto it = mPackages.begin(); it != mPackages.end();)
{ {
if((*it)->canCancel()) if((*it)->canCancel())
{ {
delete *it;
it = mPackages.erase(it); it = mPackages.erase(it);
} }
else else
@ -369,7 +358,7 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
} }
// insert new package in correct place depending on priority // insert new package in correct place depending on priority
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
// We should keep current AiCast package, if we try to add a new one. // We should keep current AiCast package, if we try to add a new one.
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdCast && if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdCast &&
@ -380,12 +369,12 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
if((*it)->getPriority() <= package.getPriority()) if((*it)->getPriority() <= package.getPriority())
{ {
mPackages.insert(it,package.clone().release()); mPackages.insert(it, package.clone());
return; return;
} }
} }
mPackages.push_back (package.clone().release()); mPackages.push_back(package.clone());
// Make sure that temporary storage is empty // Make sure that temporary storage is empty
if (cancelOther) if (cancelOther)
@ -401,12 +390,11 @@ bool MWMechanics::AiSequence::isEmpty() const
return mPackages.empty(); return mPackages.empty();
} }
AiPackage* MWMechanics::AiSequence::getActivePackage() const AiPackage& MWMechanics::AiSequence::getActivePackage()
{ {
if(mPackages.empty()) if(mPackages.empty())
throw std::runtime_error(std::string("No AI Package!")); throw std::runtime_error(std::string("No AI Package!"));
else return *mPackages.front();
return mPackages.front();
} }
void AiSequence::fill(const ESM::AIPackageList &list) void AiSequence::fill(const ESM::AIPackageList &list)
@ -417,7 +405,7 @@ void AiSequence::fill(const ESM::AIPackageList &list)
for (std::vector<ESM::AIPackage>::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) for (std::vector<ESM::AIPackage>::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it)
{ {
MWMechanics::AiPackage* package; std::unique_ptr<MWMechanics::AiPackage> package;
if (it->mType == ESM::AI_Wander) if (it->mType == ESM::AI_Wander)
{ {
ESM::AIWander data = it->mWander; ESM::AIWander data = it->mWander;
@ -425,38 +413,36 @@ void AiSequence::fill(const ESM::AIPackageList &list)
idles.reserve(8); idles.reserve(8);
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
idles.push_back(data.mIdle[i]); idles.push_back(data.mIdle[i]);
package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat != 0); package = std::make_unique<MWMechanics::AiWander>(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat != 0);
} }
else if (it->mType == ESM::AI_Escort) else if (it->mType == ESM::AI_Escort)
{ {
ESM::AITarget data = it->mTarget; ESM::AITarget data = it->mTarget;
package = new MWMechanics::AiEscort(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ); package = std::make_unique<MWMechanics::AiEscort>(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ);
} }
else if (it->mType == ESM::AI_Travel) else if (it->mType == ESM::AI_Travel)
{ {
ESM::AITravel data = it->mTravel; ESM::AITravel data = it->mTravel;
package = new MWMechanics::AiTravel(data.mX, data.mY, data.mZ); package = std::make_unique<MWMechanics::AiTravel>(data.mX, data.mY, data.mZ);
} }
else if (it->mType == ESM::AI_Activate) else if (it->mType == ESM::AI_Activate)
{ {
ESM::AIActivate data = it->mActivate; ESM::AIActivate data = it->mActivate;
package = new MWMechanics::AiActivate(data.mName.toString()); package = std::make_unique<MWMechanics::AiActivate>(data.mName.toString());
} }
else //if (it->mType == ESM::AI_Follow) else //if (it->mType == ESM::AI_Follow)
{ {
ESM::AITarget data = it->mTarget; ESM::AITarget data = it->mTarget;
package = new MWMechanics::AiFollow(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ); package = std::make_unique<MWMechanics::AiFollow>(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ);
} }
mPackages.push_back(package); mPackages.push_back(std::move(package));
} }
} }
void AiSequence::writeState(ESM::AiSequence::AiSequence &sequence) const void AiSequence::writeState(ESM::AiSequence::AiSequence &sequence) const
{ {
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter) for (const auto& package : mPackages)
{ package->writeState(sequence);
(*iter)->writeState(sequence);
}
sequence.mLastAiPackage = mLastAiPackage; sequence.mLastAiPackage = mLastAiPackage;
} }
@ -527,7 +513,7 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
if (!package.get()) if (!package.get())
continue; continue;
mPackages.push_back(package.release()); mPackages.push_back(std::move(package));
} }
mLastAiPackage = sequence.mLastAiPackage; mLastAiPackage = sequence.mLastAiPackage;
@ -537,8 +523,7 @@ void AiSequence::fastForward(const MWWorld::Ptr& actor)
{ {
if (!mPackages.empty()) if (!mPackages.empty())
{ {
MWMechanics::AiPackage* package = mPackages.front(); mPackages.front()->fastForward(actor, mAiState);
package->fastForward(actor, mAiState);
} }
} }

View File

@ -2,6 +2,7 @@
#define GAME_MWMECHANICS_AISEQUENCE_H #define GAME_MWMECHANICS_AISEQUENCE_H
#include <list> #include <list>
#include <memory>
#include "aistate.hpp" #include "aistate.hpp"
@ -36,7 +37,7 @@ namespace MWMechanics
class AiSequence class AiSequence
{ {
///AiPackages to run though ///AiPackages to run though
std::list<AiPackage *> mPackages; std::list<std::unique_ptr<AiPackage>> mPackages;
///Finished with top AIPackage, set for one frame ///Finished with top AIPackage, set for one frame
bool mDone; bool mDone;
@ -64,10 +65,10 @@ namespace MWMechanics
virtual ~AiSequence(); virtual ~AiSequence();
/// Iterator may be invalidated by any function calls other than begin() or end(). /// Iterator may be invalidated by any function calls other than begin() or end().
std::list<AiPackage*>::const_iterator begin() const; std::list<std::unique_ptr<AiPackage>>::const_iterator begin() const;
std::list<AiPackage*>::const_iterator end() const; std::list<std::unique_ptr<AiPackage>>::const_iterator end() const;
void erase (std::list<AiPackage*>::const_iterator package); void erase(std::list<std::unique_ptr<AiPackage>>::const_iterator package);
/// Returns currently executing AiPackage type /// Returns currently executing AiPackage type
/** \see enum AiPackage::TypeId **/ /** \see enum AiPackage::TypeId **/
@ -125,7 +126,7 @@ namespace MWMechanics
/// Return the current active package. /// Return the current active package.
/** If there is no active package, it will throw an exception **/ /** If there is no active package, it will throw an exception **/
AiPackage* getActivePackage(); const AiPackage& getActivePackage();
/// Fills the AiSequence with packages /// Fills the AiSequence with packages
/** Typically used for loading from the ESM /** Typically used for loading from the ESM

View File

@ -3063,7 +3063,7 @@ namespace MWWorld
{ {
if (actor != MWMechanics::getPlayer()) if (actor != MWMechanics::getPlayer())
{ {
for (const MWMechanics::AiPackage* package : stats.getAiSequence()) for (const auto& package : stats.getAiSequence())
{ {
if (package->getTypeId() == MWMechanics::AiPackage::TypeIdCast) if (package->getTypeId() == MWMechanics::AiPackage::TypeIdCast)
{ {