1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-05-01 17:41:23 +00:00

Store package type id as enum except ESM

This commit is contained in:
elsid 2020-05-16 21:52:16 +02:00
parent e6231f67e6
commit 82893c30f4
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
21 changed files with 111 additions and 98 deletions

View file

@ -115,7 +115,7 @@ void adjustCommandedActor (const MWWorld::Ptr& actor)
auto it = stats.getAiSequence().begin(); auto it = stats.getAiSequence().begin();
for (; it != stats.getAiSequence().end(); ++it) for (; it != stats.getAiSequence().end(); ++it)
{ {
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow && if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Follow &&
static_cast<const MWMechanics::AiFollow*>(it->get())->isCommanded()) static_cast<const MWMechanics::AiFollow*>(it->get())->isCommanded())
{ {
hasCommandPackage = true; hasCommandPackage = true;
@ -453,7 +453,7 @@ namespace MWMechanics
return; return;
const MWMechanics::AiSequence& seq = stats.getAiSequence(); const MWMechanics::AiSequence& seq = stats.getAiSequence();
if (seq.isInCombat() || seq.hasPackage(AiPackage::TypeIdFollow) || seq.hasPackage(AiPackage::TypeIdEscort)) if (seq.isInCombat() || seq.hasPackage(AiPackageTypeId::Follow) || seq.hasPackage(AiPackageTypeId::Escort))
return; return;
const osg::Vec3f playerPos(getPlayer().getRefData().getPosition().asVec3()); const osg::Vec3f playerPos(getPlayer().getRefData().getPosition().asVec3());
@ -497,11 +497,11 @@ namespace MWMechanics
CreatureStats &stats = actor.getClass().getCreatureStats(actor); CreatureStats &stats = actor.getClass().getCreatureStats(actor);
const MWMechanics::AiSequence& seq = stats.getAiSequence(); const MWMechanics::AiSequence& seq = stats.getAiSequence();
int packageId = seq.getTypeId(); const auto packageId = seq.getTypeId();
if (seq.isInCombat() || if (seq.isInCombat() ||
MWBase::Environment::get().getWorld()->isSwimming(actor) || MWBase::Environment::get().getWorld()->isSwimming(actor) ||
(packageId != AiPackage::TypeIdWander && packageId != AiPackage::TypeIdTravel && packageId != -1)) (packageId != AiPackageTypeId::Wander && packageId != AiPackageTypeId::Travel && packageId != AiPackageTypeId::None))
{ {
actorState.setTurningToPlayer(false); actorState.setTurningToPlayer(false);
actorState.setGreetingTimer(0); actorState.setGreetingTimer(0);
@ -724,7 +724,7 @@ namespace MWMechanics
followerOrEscorter = true; followerOrEscorter = true;
break; break;
} }
else if (package->getTypeId() != MWMechanics::AiPackage::TypeIdCombat) else if (package->getTypeId() != MWMechanics::AiPackageTypeId::Combat)
break; break;
} }
if (!followerOrEscorter) if (!followerOrEscorter)
@ -1259,7 +1259,7 @@ namespace MWMechanics
if (!isPlayer && stats.getTimeToStartDrowning() < fHoldBreathTime / 2) if (!isPlayer && stats.getTimeToStartDrowning() < fHoldBreathTime / 2)
{ {
AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence(); AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
if (seq.getTypeId() != AiPackage::TypeIdBreathe) //Only add it once if (seq.getTypeId() != AiPackageTypeId::Breathe) //Only add it once
seq.stack(AiBreathe(), ptr); seq.stack(AiBreathe(), ptr);
} }
@ -1410,7 +1410,7 @@ namespace MWMechanics
if (player.getClass().getNpcStats(player).isWerewolf()) if (player.getClass().getNpcStats(player).isWerewolf())
return; return;
if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.getAiSequence().isInCombat() if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackageTypeId::Pursue && !creatureStats.getAiSequence().isInCombat()
&& creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) && creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0)
{ {
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
@ -1773,7 +1773,7 @@ namespace MWMechanics
// 3. Player character does not use headtracking in the 1st-person view // 3. Player character does not use headtracking in the 1st-person view
if (!stats.getKnockedDown() && if (!stats.getKnockedDown() &&
!stats.getAiSequence().isInCombat() && !stats.getAiSequence().isInCombat() &&
!stats.getAiSequence().hasPackage(AiPackage::TypeIdPursue) && !stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue) &&
!firstPersonPlayer) !firstPersonPlayer)
{ {
for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
@ -2276,7 +2276,7 @@ namespace MWMechanics
} }
break; break;
} }
else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander)
break; break;
} }
} }
@ -2302,7 +2302,7 @@ namespace MWMechanics
{ {
if (package->followTargetThroughDoors() && package->getTarget() == actor) if (package->followTargetThroughDoors() && package->getTarget() == actor)
list.push_back(iteratedActor); list.push_back(iteratedActor);
else if (package->getTypeId() != AiPackage::TypeIdCombat && package->getTypeId() != AiPackage::TypeIdWander) else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander)
break; break;
} }
} }
@ -2368,7 +2368,7 @@ namespace MWMechanics
list.push_back(static_cast<const AiFollow*>(package.get())->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() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander)
break; break;
} }
} }

View file

@ -30,7 +30,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdActivate; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; }
void writeState(ESM::AiSequence::AiSequence& sequence) const final; void writeState(ESM::AiSequence::AiSequence& sequence) const final;

View file

@ -63,7 +63,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterCont
for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) { for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) {
if(*it != getPlayer()) { //Not the player if(*it != getPlayer()) { //Not the player
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence(); MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) { //Only add it once if(seq.getTypeId() != MWMechanics::AiPackageTypeId::AvoidDoor) { //Only add it once
seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr),*it); seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr),*it);
} }
} }

View file

@ -24,7 +24,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdAvoidDoor; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::AvoidDoor; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -12,7 +12,7 @@ namespace MWMechanics
public: public:
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdBreathe; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Breathe; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -17,7 +17,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdCast; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Cast; }
MWWorld::Ptr getTarget() const final; MWWorld::Ptr getTarget() const final;

View file

@ -104,7 +104,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdCombat; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Combat; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -32,7 +32,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdEscort; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Escort; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -12,7 +12,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdFace; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Face; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -55,7 +55,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdFollow; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -24,7 +24,7 @@
#include <osg/Quat> #include <osg/Quat>
MWMechanics::AiPackage::AiPackage(TypeId typeId, const Options& options) : MWMechanics::AiPackage::AiPackage(AiPackageTypeId typeId, const Options& options) :
mTypeId(typeId), mTypeId(typeId),
mOptions(options), mOptions(options),
mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild
@ -216,7 +216,7 @@ namespace
void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
{ {
// note: AiWander currently does not open doors // note: AiWander currently does not open doors
if (getTypeId() == TypeIdWander) if (getTypeId() == AiPackageTypeId::Wander)
return; return;
if (mPathFinder.getPathSize() == 0) if (mPathFinder.getPathSize() == 0)
@ -391,13 +391,13 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
const MWWorld::Class& actorClass = actor.getClass(); const MWWorld::Class& actorClass = actor.getClass();
DetourNavigator::Flags result = DetourNavigator::Flag_none; DetourNavigator::Flags result = DetourNavigator::Flag_none;
if (actorClass.isPureWaterCreature(actor) || (getTypeId() != TypeIdWander && actorClass.canSwim(actor))) if (actorClass.isPureWaterCreature(actor) || (getTypeId() != AiPackageTypeId::Wander && actorClass.canSwim(actor)))
result |= DetourNavigator::Flag_swim; result |= DetourNavigator::Flag_swim;
if (actorClass.canWalk(actor)) if (actorClass.canWalk(actor))
result |= DetourNavigator::Flag_walk; result |= DetourNavigator::Flag_walk;
if (actorClass.isBipedal(actor) && getTypeId() != TypeIdWander) if (actorClass.isBipedal(actor) && getTypeId() != AiPackageTypeId::Wander)
result |= DetourNavigator::Flag_openDoor; result |= DetourNavigator::Flag_openDoor;
return result; return result;

View file

@ -8,6 +8,7 @@
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include "obstacle.hpp" #include "obstacle.hpp"
#include "aistate.hpp" #include "aistate.hpp"
#include "aipackagetypeid.hpp"
namespace MWWorld namespace MWWorld
{ {
@ -35,26 +36,6 @@ namespace MWMechanics
class AiPackage class AiPackage
{ {
public: public:
///Enumerates the various AITypes available
enum TypeId {
TypeIdNone = -1,
TypeIdWander = 0,
TypeIdTravel = 1,
TypeIdEscort = 2,
TypeIdFollow = 3,
TypeIdActivate = 4,
// These 5 are not really handled as Ai Packages in the MW engine
// For compatibility do *not* return these in the getCurrentAiPackage script function..
TypeIdCombat = 5,
TypeIdPursue = 6,
TypeIdAvoidDoor = 7,
TypeIdFace = 8,
TypeIdBreathe = 9,
TypeIdInternalTravel = 10,
TypeIdCast = 11
};
struct Options struct Options
{ {
unsigned int mPriority = 0; unsigned int mPriority = 0;
@ -79,7 +60,7 @@ namespace MWMechanics
} }
}; };
AiPackage(TypeId typeId, const Options& options); AiPackage(AiPackageTypeId typeId, const Options& options);
virtual ~AiPackage() = default; virtual ~AiPackage() = default;
@ -97,7 +78,7 @@ namespace MWMechanics
/// Returns the TypeID of the AiPackage /// Returns the TypeID of the AiPackage
/// \see enum TypeId /// \see enum TypeId
TypeId getTypeId() const { return mTypeId; } AiPackageTypeId getTypeId() const { return mTypeId; }
/// Higher number is higher priority (0 being the lowest) /// Higher number is higher priority (0 being the lowest)
unsigned int getPriority() const { return mOptions.mPriority; } unsigned int getPriority() const { return mOptions.mPriority; }
@ -167,7 +148,7 @@ namespace MWMechanics
DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const; DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const;
const TypeId mTypeId; const AiPackageTypeId mTypeId;
const Options mOptions; const Options mOptions;
// TODO: all this does not belong here, move into temporary storage // TODO: all this does not belong here, move into temporary storage

View file

@ -0,0 +1,28 @@
#ifndef GAME_MWMECHANICS_AIPACKAGETYPEID_H
#define GAME_MWMECHANICS_AIPACKAGETYPEID_H
namespace MWMechanics
{
///Enumerates the various AITypes available
enum class AiPackageTypeId
{
None = -1,
Wander = 0,
Travel = 1,
Escort = 2,
Follow = 3,
Activate = 4,
// These 5 are not really handled as Ai Packages in the MW engine
// For compatibility do *not* return these in the getCurrentAiPackage script function..
Combat = 5,
Pursue = 6,
AvoidDoor = 7,
Face = 8,
Breathe = 9,
InternalTravel = 10,
Cast = 11
};
}
#endif

View file

@ -28,7 +28,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdPursue; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Pursue; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -33,7 +33,7 @@ void AiSequence::copy (const AiSequence& sequence)
sequence.mAiState.copy<AiWanderStorage>(mAiState); sequence.mAiState.copy<AiWanderStorage>(mAiState);
} }
AiSequence::AiSequence() : mDone (false), mRepeat(false), mLastAiPackage(-1) {} AiSequence::AiSequence() : mDone (false), mRepeat(false), mLastAiPackage(AiPackageTypeId::None) {}
AiSequence::AiSequence (const AiSequence& sequence) AiSequence::AiSequence (const AiSequence& sequence)
{ {
@ -61,17 +61,17 @@ AiSequence::~AiSequence()
clear(); clear();
} }
int AiSequence::getTypeId() const AiPackageTypeId AiSequence::getTypeId() const
{ {
if (mPackages.empty()) if (mPackages.empty())
return -1; return AiPackageTypeId::None;
return mPackages.front()->getTypeId(); return mPackages.front()->getTypeId();
} }
bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const
{ {
if (getTypeId() != AiPackage::TypeIdCombat) if (getTypeId() != AiPackageTypeId::Combat)
return false; return false;
targetActor = mPackages.front()->getTarget(); targetActor = mPackages.front()->getTarget();
@ -83,7 +83,7 @@ bool AiSequence::getCombatTargets(std::vector<MWWorld::Ptr> &targetActors) const
{ {
for (auto 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::AiPackageTypeId::Combat)
targetActors.push_back((*it)->getTarget()); targetActors.push_back((*it)->getTarget());
} }
@ -118,7 +118,7 @@ bool AiSequence::isInCombat() const
{ {
for (auto it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackageTypeId::Combat)
return true; return true;
} }
return false; return false;
@ -128,7 +128,7 @@ bool AiSequence::isEngagedWithActor() const
{ {
for (auto it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackageTypeId::Combat)
{ {
MWWorld::Ptr target2 = (*it)->getTarget(); MWWorld::Ptr target2 = (*it)->getTarget();
if (!target2.isEmpty() && target2.getClass().isNpc()) if (!target2.isEmpty() && target2.getClass().isNpc())
@ -138,7 +138,7 @@ bool AiSequence::isEngagedWithActor() const
return false; return false;
} }
bool AiSequence::hasPackage(int typeId) const bool AiSequence::hasPackage(AiPackageTypeId typeId) const
{ {
for (auto it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
@ -152,7 +152,7 @@ bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const
{ {
for (auto it = mPackages.begin(); it != mPackages.end(); ++it) for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackageTypeId::Combat)
{ {
if ((*it)->getTarget() == actor) if ((*it)->getTarget() == actor)
return true; return true;
@ -165,7 +165,7 @@ void AiSequence::stopCombat()
{ {
for(auto it = mPackages.begin(); it != mPackages.end(); ) for(auto it = mPackages.begin(); it != mPackages.end(); )
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdCombat) if ((*it)->getTypeId() == AiPackageTypeId::Combat)
{ {
it = mPackages.erase(it); it = mPackages.erase(it);
} }
@ -178,7 +178,7 @@ void AiSequence::stopPursuit()
{ {
for(auto it = mPackages.begin(); it != mPackages.end(); ) for(auto it = mPackages.begin(); it != mPackages.end(); )
{ {
if ((*it)->getTypeId() == AiPackage::TypeIdPursue) if ((*it)->getTypeId() == AiPackageTypeId::Pursue)
{ {
it = mPackages.erase(it); it = mPackages.erase(it);
} }
@ -192,10 +192,13 @@ bool AiSequence::isPackageDone() const
return mDone; return mDone;
} }
bool isActualAiPackage(int packageTypeId) namespace
{ {
return (packageTypeId >= AiPackage::TypeIdWander && bool isActualAiPackage(AiPackageTypeId packageTypeId)
packageTypeId <= AiPackage::TypeIdActivate); {
return (packageTypeId >= AiPackageTypeId::Wander &&
packageTypeId <= AiPackageTypeId::Activate);
}
} }
void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange) void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange)
@ -204,7 +207,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
{ {
if (mPackages.empty()) if (mPackages.empty())
{ {
mLastAiPackage = -1; mLastAiPackage = AiPackageTypeId::None;
return; return;
} }
@ -213,12 +216,12 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
if (!package->alwaysActive() && outOfRange) if (!package->alwaysActive() && outOfRange)
return; return;
int packageTypeId = package->getTypeId(); auto packageTypeId = package->getTypeId();
// workaround ai packages not being handled as in the vanilla engine // workaround ai packages not being handled as in the vanilla engine
if (isActualAiPackage(packageTypeId)) if (isActualAiPackage(packageTypeId))
mLastAiPackage = packageTypeId; mLastAiPackage = packageTypeId;
// if active package is combat one, choose nearest target // if active package is combat one, choose nearest target
if (packageTypeId == AiPackage::TypeIdCombat) if (packageTypeId == AiPackageTypeId::Combat)
{ {
auto itActualCombat = mPackages.end(); auto itActualCombat = mPackages.end();
@ -229,7 +232,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
for (auto it = mPackages.begin(); it != mPackages.end();) for (auto it = mPackages.begin(); it != mPackages.end();)
{ {
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break; if ((*it)->getTypeId() != AiPackageTypeId::Combat) break;
MWWorld::Ptr target = (*it)->getTarget(); MWWorld::Ptr target = (*it)->getTarget();
@ -320,16 +323,16 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
// We should return a wandering actor back after combat, casting or pursuit. // We should return a wandering actor back after combat, casting or pursuit.
// The same thing for actors without AI packages. // The same thing for actors without AI packages.
// Also there is no point to stack return packages. // Also there is no point to stack return packages.
int currentTypeId = getTypeId(); const auto currentTypeId = getTypeId();
int newTypeId = package.getTypeId(); const auto newTypeId = package.getTypeId();
if (currentTypeId <= MWMechanics::AiPackage::TypeIdWander if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander
&& !hasPackage(MWMechanics::AiPackage::TypeIdInternalTravel) && !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel)
&& (newTypeId <= MWMechanics::AiPackage::TypeIdCombat && (newTypeId <= MWMechanics::AiPackageTypeId::Combat
|| newTypeId == MWMechanics::AiPackage::TypeIdPursue || newTypeId == MWMechanics::AiPackageTypeId::Pursue
|| newTypeId == MWMechanics::AiPackage::TypeIdCast)) || newTypeId == MWMechanics::AiPackageTypeId::Cast))
{ {
osg::Vec3f dest; osg::Vec3f dest;
if (currentTypeId == MWMechanics::AiPackage::TypeIdWander) if (currentTypeId == MWMechanics::AiPackageTypeId::Wander)
{ {
dest = getActivePackage().getDestination(actor); dest = getActivePackage().getDestination(actor);
} }
@ -361,8 +364,8 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, boo
for (auto 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::AiPackageTypeId::Cast &&
package.getTypeId() == MWMechanics::AiPackage::TypeIdCast) package.getTypeId() == MWMechanics::AiPackageTypeId::Cast)
{ {
continue; continue;
} }
@ -444,7 +447,7 @@ void AiSequence::writeState(ESM::AiSequence::AiSequence &sequence) const
for (const auto& package : mPackages) for (const auto& package : mPackages)
package->writeState(sequence); package->writeState(sequence);
sequence.mLastAiPackage = mLastAiPackage; sequence.mLastAiPackage = static_cast<int>(mLastAiPackage);
} }
void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence) void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
@ -457,7 +460,7 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
for (std::vector<ESM::AiSequence::AiPackageContainer>::const_iterator it = sequence.mPackages.begin(); for (std::vector<ESM::AiSequence::AiPackageContainer>::const_iterator it = sequence.mPackages.begin();
it != sequence.mPackages.end(); ++it) it != sequence.mPackages.end(); ++it)
{ {
if (isActualAiPackage(it->mType)) if (isActualAiPackage(static_cast<AiPackageTypeId>(it->mType)))
count++; count++;
} }
@ -520,7 +523,7 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence)
mPackages.push_back(std::move(package)); mPackages.push_back(std::move(package));
} }
mLastAiPackage = sequence.mLastAiPackage; mLastAiPackage = static_cast<AiPackageTypeId>(sequence.mLastAiPackage);
} }
void AiSequence::fastForward(const MWWorld::Ptr& actor) void AiSequence::fastForward(const MWWorld::Ptr& actor)

View file

@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include "aistate.hpp" #include "aistate.hpp"
#include "aipackagetypeid.hpp"
#include <components/esm/loadnpc.hpp> #include <components/esm/loadnpc.hpp>
@ -49,7 +50,7 @@ namespace MWMechanics
void copy (const AiSequence& sequence); void copy (const AiSequence& sequence);
/// The type of AI package that ran last /// The type of AI package that ran last
int mLastAiPackage; AiPackageTypeId mLastAiPackage;
AiState mAiState; AiState mAiState;
public: public:
@ -71,14 +72,14 @@ namespace MWMechanics
void erase(std::list<std::unique_ptr<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 class AiPackageTypeId **/
int getTypeId() const; AiPackageTypeId getTypeId() const;
/// Get the typeid of the Ai package that ran last /// Get the typeid of the Ai package that ran last
/** NOT the currently "active" Ai package that will be run in the next frame. /** NOT the currently "active" Ai package that will be run in the next frame.
This difference is important when an Ai package has just finished and been removed. This difference is important when an Ai package has just finished and been removed.
\see enum AiPackage::TypeId **/ \see enum class AiPackageTypeId **/
int getLastRunTypeId() const { return mLastAiPackage; } AiPackageTypeId getLastRunTypeId() const { return mLastAiPackage; }
/// Return true and assign target if combat package is currently active, return false otherwise /// Return true and assign target if combat package is currently active, return false otherwise
bool getCombatTarget (MWWorld::Ptr &targetActor) const; bool getCombatTarget (MWWorld::Ptr &targetActor) const;
@ -93,7 +94,7 @@ namespace MWMechanics
bool isEngagedWithActor () const; bool isEngagedWithActor () const;
/// Does this AI sequence have the given package type? /// Does this AI sequence have the given package type?
bool hasPackage(int typeId) const; bool hasPackage(AiPackageTypeId typeId) const;
/// Are we in combat with this particular actor? /// Are we in combat with this particular actor?
bool isInCombat (const MWWorld::Ptr& actor) const; bool isInCombat (const MWWorld::Ptr& actor) const;

View file

@ -34,7 +34,7 @@ namespace MWMechanics
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdTravel; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {
@ -60,7 +60,7 @@ namespace MWMechanics
explicit AiInternalTravel(const ESM::AiSequence::AiTravel* travel); explicit AiInternalTravel(const ESM::AiSequence::AiTravel* travel);
static constexpr TypeId getTypeId() { return TypeIdInternalTravel; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::InternalTravel; }
std::unique_ptr<AiPackage> clone() const final; std::unique_ptr<AiPackage> clone() const final;
}; };

View file

@ -93,7 +93,7 @@ namespace MWMechanics
bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
static constexpr TypeId getTypeId() { return TypeIdWander; } static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Wander; }
static constexpr Options makeDefaultOptions() static constexpr Options makeDefaultOptions()
{ {

View file

@ -1277,7 +1277,7 @@ namespace MWMechanics
{ {
bool reported = false; bool reported = false;
if (victim.getClass().isClass(victim, "guard") if (victim.getClass().isClass(victim, "guard")
&& !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) && !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackageTypeId::Pursue))
reported = reportCrime(player, victim, type, std::string(), arg); reported = reportCrime(player, victim, type, std::string(), arg);
if (!reported) if (!reported)
@ -1300,7 +1300,7 @@ namespace MWMechanics
return false; return false;
// Player's followers should not attack player, or try to arrest him // Player's followers should not attack player, or try to arrest him
if (actor.getClass().getCreatureStats(actor).getAiSequence().hasPackage(AiPackage::TypeIdFollow)) if (actor.getClass().getCreatureStats(actor).getAiSequence().hasPackage(AiPackageTypeId::Follow))
{ {
if (playerFollowers.find(actor) != playerFollowers.end()) if (playerFollowers.find(actor) != playerFollowers.end())
return false; return false;
@ -1417,7 +1417,7 @@ namespace MWMechanics
// once the bounty has been paid. // once the bounty has been paid.
actor.getClass().getNpcStats(actor).setCrimeId(id); actor.getClass().getNpcStats(actor).setCrimeId(id);
if (!actor.getClass().getCreatureStats(actor).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) if (!actor.getClass().getCreatureStats(actor).getAiSequence().hasPackage(AiPackageTypeId::Pursue))
{ {
actor.getClass().getCreatureStats(actor).getAiSequence().stack(AiPursue(player), actor); actor.getClass().getCreatureStats(actor).getAiSequence().stack(AiPursue(player), actor);
} }
@ -1495,7 +1495,7 @@ namespace MWMechanics
{ {
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back. // Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored. // Note: accidental or collateral damage attacks are ignored.
if (!victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) if (!victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackageTypeId::Pursue))
startCombat(victim, player); startCombat(victim, player);
// Set the crime ID, which we will use to calm down participants // Set the crime ID, which we will use to calm down participants
@ -1541,7 +1541,7 @@ namespace MWMechanics
{ {
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back. // Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored. // Note: accidental or collateral damage attacks are ignored.
if (!target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue)) if (!target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackageTypeId::Pursue))
{ {
// If an actor has OnPCHitMe declared in his script, his Fight = 0 and the attacker is player, // If an actor has OnPCHitMe declared in his script, his Fight = 0 and the attacker is player,
// he will attack the player only if we will force him (e.g. via StartCombat console command) // he will attack the player only if we will force him (e.g. via StartCombat console command)
@ -1566,7 +1566,7 @@ namespace MWMechanics
const 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) return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker)
&& !isAggressive(target, attacker) && !seq.isEngagedWithActor() && !isAggressive(target, attacker) && !seq.isEngagedWithActor()
&& !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackage::TypeIdPursue); && !target.getClass().getCreatureStats(target).getAiSequence().hasPackage(AiPackageTypeId::Pursue);
} }
void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker) void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker)
@ -1702,7 +1702,7 @@ namespace MWMechanics
if (iter->first.getClass().isClass(iter->first, "Guard")) if (iter->first.getClass().isClass(iter->first, "Guard"))
{ {
MWMechanics::AiSequence& aiSeq = iter->first.getClass().getCreatureStats(iter->first).getAiSequence(); MWMechanics::AiSequence& aiSeq = iter->first.getClass().getCreatureStats(iter->first).getAiSequence();
if (aiSeq.getTypeId() == MWMechanics::AiPackage::TypeIdPursue) if (aiSeq.getTypeId() == MWMechanics::AiPackageTypeId::Pursue)
{ {
aiSeq.stopPursuit(); aiSeq.stopPursuit();
aiSeq.stack(MWMechanics::AiCombat(target), ptr); aiSeq.stack(MWMechanics::AiCombat(target), ptr);

View file

@ -362,7 +362,7 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value = ptr.getClass().getCreatureStats (ptr).getAiSequence().getLastRunTypeId(); const auto value = static_cast<Interpreter::Type_Integer>(ptr.getClass().getCreatureStats (ptr).getAiSequence().getLastRunTypeId());
runtime.push (value); runtime.push (value);
} }

View file

@ -1559,7 +1559,7 @@ namespace MWWorld
if(ptr != getPlayerPtr() ) if(ptr != getPlayerPtr() )
{ {
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence(); MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) //Only add it once if(seq.getTypeId() != MWMechanics::AiPackageTypeId::AvoidDoor) //Only add it once
seq.stack(MWMechanics::AiAvoidDoor(door),ptr); seq.stack(MWMechanics::AiAvoidDoor(door),ptr);
} }
@ -2948,7 +2948,7 @@ namespace MWWorld
{ {
for (const auto& package : stats.getAiSequence()) for (const auto& package : stats.getAiSequence())
{ {
if (package->getTypeId() == MWMechanics::AiPackage::TypeIdCast) if (package->getTypeId() == MWMechanics::AiPackageTypeId::Cast)
{ {
target = package->getTarget(); target = package->getTarget();
break; break;