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:
parent
ce7c47ee12
commit
b67e18329e
@ -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)
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user