mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:23:53 +00:00
Merge pull request #2886 from elsid/ai_package_unique_ptr
Store AIPackages as unique_ptr
This commit is contained in:
commit
998f4f73f4
6 changed files with 62 additions and 74 deletions
|
@ -112,11 +112,11 @@ void adjustCommandedActor (const MWWorld::Ptr& actor)
|
|||
|
||||
bool hasCommandPackage = false;
|
||||
|
||||
std::list<MWMechanics::AiPackage*>::const_iterator it;
|
||||
for (it = stats.getAiSequence().begin(); it != stats.getAiSequence().end(); ++it)
|
||||
auto it = stats.getAiSequence().begin();
|
||||
for (; it != stats.getAiSequence().end(); ++it)
|
||||
{
|
||||
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow &&
|
||||
static_cast<MWMechanics::AiFollow*>(*it)->isCommanded())
|
||||
static_cast<const MWMechanics::AiFollow*>(it->get())->isCommanded())
|
||||
{
|
||||
hasCommandPackage = true;
|
||||
break;
|
||||
|
@ -419,7 +419,7 @@ namespace MWMechanics
|
|||
if (world->isSwimming(actor) || (playerPos - actorPos).length2() >= 3000 * 3000)
|
||||
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.
|
||||
const float delta = MWBase::Environment::get().getFrameDuration() * 6.f;
|
||||
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);
|
||||
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();
|
||||
float distance = (targetPos - actorPos).length();
|
||||
if (distance < DECELERATE_DISTANCE)
|
||||
|
@ -604,7 +604,7 @@ namespace MWMechanics
|
|||
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
|
||||
// Doesn't apply for player followers/escorters
|
||||
// Doesn't apply for player followers/escorters
|
||||
if (!aggressive && !isPlayerFollowerOrEscorter)
|
||||
{
|
||||
// Check that actor2 is in combat with actor1
|
||||
|
@ -673,7 +673,7 @@ namespace MWMechanics
|
|||
return;
|
||||
|
||||
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
|
||||
if (package->sideWithTarget())
|
||||
|
@ -1738,7 +1738,7 @@ namespace MWMechanics
|
|||
if (!isPlayer && isConscious(iter->first) && !stats.isParalyzed())
|
||||
{
|
||||
MWMechanics::AiSequence& seq = stats.getAiSequence();
|
||||
alwaysActive = !seq.isEmpty() && seq.getActivePackage()->alwaysActive();
|
||||
alwaysActive = !seq.isEmpty() && seq.getActivePackage().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)
|
||||
|
@ -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
|
||||
// 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())
|
||||
{
|
||||
|
@ -2192,9 +2192,9 @@ namespace MWMechanics
|
|||
if (stats.isDead())
|
||||
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
|
||||
for (const AiPackage* package : stats.getAiSequence())
|
||||
for (const auto& package : stats.getAiSequence())
|
||||
{
|
||||
if (package->followTargetThroughDoors() && package->getTarget() == actor)
|
||||
list.push_back(iteratedActor);
|
||||
|
@ -2257,11 +2257,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 (AiPackage* package : stats.getAiSequence())
|
||||
for (const auto& package : stats.getAiSequence())
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef GAME_MWMECHANICS_AIPACKAGE_H
|
||||
#define GAME_MWMECHANICS_AIPACKAGE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
#include "pathfinding.hpp"
|
||||
|
@ -59,7 +61,7 @@ namespace MWMechanics
|
|||
virtual ~AiPackage() = default;
|
||||
|
||||
///Clones the package
|
||||
virtual AiPackage *clone() const = 0;
|
||||
virtual std::unique_ptr<AiPackage> clone() const = 0;
|
||||
|
||||
/// Updates and runs the package (Should run every frame)
|
||||
/// \return Package completed?
|
||||
|
|
|
@ -25,9 +25,8 @@ namespace MWMechanics
|
|||
|
||||
void AiSequence::copy (const AiSequence& sequence)
|
||||
{
|
||||
for (std::list<AiPackage *>::const_iterator iter (sequence.mPackages.begin());
|
||||
iter!=sequence.mPackages.end(); ++iter)
|
||||
mPackages.push_back ((*iter)->clone());
|
||||
for (const auto& package : sequence.mPackages)
|
||||
mPackages.push_back(package->clone());
|
||||
|
||||
// We need to keep an AiWander storage, if present - it has a state machine.
|
||||
// Not sure about another temporary storages
|
||||
|
@ -74,7 +73,7 @@ bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const
|
|||
{
|
||||
if (getTypeId() != AiPackage::TypeIdCombat)
|
||||
return false;
|
||||
|
||||
|
||||
targetActor = mPackages.front()->getTarget();
|
||||
|
||||
return !targetActor.isEmpty();
|
||||
|
@ -82,7 +81,7 @@ bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) 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)
|
||||
targetActors.push_back((*it)->getTarget());
|
||||
|
@ -91,24 +90,23 @@ bool AiSequence::getCombatTargets(std::vector<MWWorld::Ptr> &targetActors) const
|
|||
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();
|
||||
}
|
||||
|
||||
std::list<AiPackage*>::const_iterator AiSequence::end() const
|
||||
std::list<std::unique_ptr<AiPackage>>::const_iterator AiSequence::end() const
|
||||
{
|
||||
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?
|
||||
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||
for(auto it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||
{
|
||||
if (package == it)
|
||||
{
|
||||
delete *it;
|
||||
mPackages.erase(it);
|
||||
return;
|
||||
}
|
||||
|
@ -118,7 +116,7 @@ void AiSequence::erase(std::list<AiPackage*>::const_iterator package)
|
|||
|
||||
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)
|
||||
return true;
|
||||
|
@ -128,7 +126,7 @@ bool AiSequence::isInCombat() 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)
|
||||
{
|
||||
|
@ -142,7 +140,7 @@ bool AiSequence::isEngagedWithActor() 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)
|
||||
return true;
|
||||
|
@ -152,7 +150,7 @@ bool AiSequence::hasPackage(int typeId) 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)
|
||||
{
|
||||
|
@ -165,11 +163,10 @@ bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const
|
|||
|
||||
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)
|
||||
{
|
||||
delete *it;
|
||||
it = mPackages.erase(it);
|
||||
}
|
||||
else
|
||||
|
@ -179,11 +176,10 @@ void AiSequence::stopCombat()
|
|||
|
||||
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)
|
||||
{
|
||||
delete *it;
|
||||
it = mPackages.erase(it);
|
||||
}
|
||||
else
|
||||
|
@ -213,7 +209,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
}
|
||||
|
||||
auto packageIt = mPackages.begin();
|
||||
MWMechanics::AiPackage* package = *packageIt;
|
||||
MWMechanics::AiPackage* package = packageIt->get();
|
||||
if (!package->alwaysActive() && outOfRange)
|
||||
return;
|
||||
|
||||
|
@ -231,7 +227,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
|
||||
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;
|
||||
|
||||
|
@ -240,7 +236,6 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
// target disappeared (e.g. summoned creatures)
|
||||
if (target.isEmpty())
|
||||
{
|
||||
delete *it;
|
||||
it = mPackages.erase(it);
|
||||
}
|
||||
else
|
||||
|
@ -276,13 +271,13 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
}
|
||||
|
||||
packageIt = mPackages.begin();
|
||||
package = *packageIt;
|
||||
package = packageIt->get();
|
||||
packageTypeId = package->getTypeId();
|
||||
}
|
||||
|
||||
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
|
||||
if (isActualAiPackage(packageTypeId) && (mRepeat || package->getRepeat()))
|
||||
|
@ -293,7 +288,6 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
// To account for the rare case where AiPackage::execute() queued another AI package
|
||||
// (e.g. AiPursue executing a dialogue script that uses startCombat)
|
||||
mPackages.erase(packageIt);
|
||||
delete package;
|
||||
if (isActualAiPackage(packageTypeId))
|
||||
mDone = true;
|
||||
}
|
||||
|
@ -311,9 +305,6 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||
|
||||
void AiSequence::clear()
|
||||
{
|
||||
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
|
||||
delete *iter;
|
||||
|
||||
mPackages.clear();
|
||||
}
|
||||
|
||||
|
@ -340,8 +331,7 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
|
|||
osg::Vec3f dest;
|
||||
if (currentTypeId == MWMechanics::AiPackage::TypeIdWander)
|
||||
{
|
||||
AiPackage* activePackage = getActivePackage();
|
||||
dest = activePackage->getDestination(actor);
|
||||
dest = getActivePackage().getDestination(actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -355,11 +345,10 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
|
|||
// remove previous packages if required
|
||||
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())
|
||||
{
|
||||
delete *it;
|
||||
it = mPackages.erase(it);
|
||||
}
|
||||
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
|
||||
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.
|
||||
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())
|
||||
{
|
||||
mPackages.insert(it,package.clone());
|
||||
mPackages.insert(it, package.clone());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mPackages.push_back (package.clone());
|
||||
mPackages.push_back(package.clone());
|
||||
|
||||
// Make sure that temporary storage is empty
|
||||
if (cancelOther)
|
||||
|
@ -401,12 +390,11 @@ bool MWMechanics::AiSequence::isEmpty() const
|
|||
return mPackages.empty();
|
||||
}
|
||||
|
||||
AiPackage* MWMechanics::AiSequence::getActivePackage()
|
||||
const AiPackage& MWMechanics::AiSequence::getActivePackage()
|
||||
{
|
||||
if(mPackages.empty())
|
||||
throw std::runtime_error(std::string("No AI Package!"));
|
||||
else
|
||||
return mPackages.front();
|
||||
return *mPackages.front();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MWMechanics::AiPackage* package;
|
||||
std::unique_ptr<MWMechanics::AiPackage> package;
|
||||
if (it->mType == ESM::AI_Wander)
|
||||
{
|
||||
ESM::AIWander data = it->mWander;
|
||||
|
@ -425,38 +413,36 @@ void AiSequence::fill(const ESM::AIPackageList &list)
|
|||
idles.reserve(8);
|
||||
for (int i=0; i<8; ++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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
|
||||
{
|
||||
(*iter)->writeState(sequence);
|
||||
}
|
||||
for (const auto& package : mPackages)
|
||||
package->writeState(sequence);
|
||||
|
||||
sequence.mLastAiPackage = mLastAiPackage;
|
||||
}
|
||||
|
@ -527,7 +513,7 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
|
|||
if (!package.get())
|
||||
continue;
|
||||
|
||||
mPackages.push_back(package.release());
|
||||
mPackages.push_back(std::move(package));
|
||||
}
|
||||
|
||||
mLastAiPackage = sequence.mLastAiPackage;
|
||||
|
@ -537,8 +523,7 @@ void AiSequence::fastForward(const MWWorld::Ptr& actor)
|
|||
{
|
||||
if (!mPackages.empty())
|
||||
{
|
||||
MWMechanics::AiPackage* package = mPackages.front();
|
||||
package->fastForward(actor, mAiState);
|
||||
mPackages.front()->fastForward(actor, mAiState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define GAME_MWMECHANICS_AISEQUENCE_H
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "aistate.hpp"
|
||||
|
||||
|
@ -36,7 +37,7 @@ namespace MWMechanics
|
|||
class AiSequence
|
||||
{
|
||||
///AiPackages to run though
|
||||
std::list<AiPackage *> mPackages;
|
||||
std::list<std::unique_ptr<AiPackage>> mPackages;
|
||||
|
||||
///Finished with top AIPackage, set for one frame
|
||||
bool mDone;
|
||||
|
@ -64,10 +65,10 @@ namespace MWMechanics
|
|||
virtual ~AiSequence();
|
||||
|
||||
/// Iterator may be invalidated by any function calls other than begin() or end().
|
||||
std::list<AiPackage*>::const_iterator begin() const;
|
||||
std::list<AiPackage*>::const_iterator end() const;
|
||||
std::list<std::unique_ptr<AiPackage>>::const_iterator begin() 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
|
||||
/** \see enum AiPackage::TypeId **/
|
||||
|
@ -125,7 +126,7 @@ namespace MWMechanics
|
|||
|
||||
/// Return the current active package.
|
||||
/** If there is no active package, it will throw an exception **/
|
||||
AiPackage* getActivePackage();
|
||||
const AiPackage& getActivePackage();
|
||||
|
||||
/// Fills the AiSequence with packages
|
||||
/** Typically used for loading from the ESM
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace MWMechanics
|
|||
template <class T>
|
||||
struct TypedAiPackage : public AiPackage
|
||||
{
|
||||
virtual TypedAiPackage<T> *clone() const override
|
||||
virtual std::unique_ptr<AiPackage> clone() const override
|
||||
{
|
||||
return new T(*static_cast<const T*>(this));
|
||||
return std::make_unique<T>(*static_cast<const T*>(this));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3063,7 +3063,7 @@ namespace MWWorld
|
|||
{
|
||||
if (actor != MWMechanics::getPlayer())
|
||||
{
|
||||
for (const MWMechanics::AiPackage* package : stats.getAiSequence())
|
||||
for (const auto& package : stats.getAiSequence())
|
||||
{
|
||||
if (package->getTypeId() == MWMechanics::AiPackage::TypeIdCast)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue