Store integer actor ID in AI packages (bug #4036)

pull/456/head
Andrei Kortunov 7 years ago
parent 9d0ce25052
commit fed10e87aa

@ -1,6 +1,7 @@
0.45.0 0.45.0
------ ------
Bug #2835: Player able to slowly move when overencumbered Bug #2835: Player able to slowly move when overencumbered
Bug #4036: Weird behaviour of AI packages if package target has non-unique ID
Bug #4221: Characters get stuck in V-shaped terrain Bug #4221: Characters get stuck in V-shaped terrain
Bug #4293: Faction members are not aware of faction ownerships in barter Bug #4293: Faction members are not aware of faction ownerships in barter
Bug #4327: Missing animations during spell/weapon stance switching Bug #4327: Missing animations during spell/weapon stance switching

@ -103,9 +103,10 @@ namespace MWMechanics
bool isFleeing(); bool isFleeing();
}; };
AiCombat::AiCombat(const MWWorld::Ptr& actor) : AiCombat::AiCombat(const MWWorld::Ptr& actor)
mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId()) {
{} mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId();
}
AiCombat::AiCombat(const ESM::AiSequence::AiCombat *combat) AiCombat::AiCombat(const ESM::AiSequence::AiCombat *combat)
{ {

@ -54,9 +54,6 @@ namespace MWMechanics
virtual bool shouldCancelPreviousAi() const { return false; } virtual bool shouldCancelPreviousAi() const { return false; }
private: private:
int mTargetActorId;
/// Returns true if combat should end /// Returns true if combat should end
bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController); bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController);

@ -22,28 +22,32 @@
namespace MWMechanics namespace MWMechanics
{ {
AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z) AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z)
: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) : mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration))
, mCellX(std::numeric_limits<int>::max()) , mCellX(std::numeric_limits<int>::max())
, mCellY(std::numeric_limits<int>::max()) , mCellY(std::numeric_limits<int>::max())
{ {
mTargetActorRefId = actorId;
mMaxDist = 450; mMaxDist = 450;
} }
AiEscort::AiEscort(const std::string &actorId, const std::string &cellId,int duration, float x, float y, float z) AiEscort::AiEscort(const std::string &actorId, const std::string &cellId, int duration, float x, float y, float z)
: mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) : mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration))
, mCellX(std::numeric_limits<int>::max()) , mCellX(std::numeric_limits<int>::max())
, mCellY(std::numeric_limits<int>::max()) , mCellY(std::numeric_limits<int>::max())
{ {
mTargetActorRefId = actorId;
mMaxDist = 450; mMaxDist = 450;
} }
AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort)
: mActorId(escort->mTargetId), mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) : mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ)
, mMaxDist(450) , mMaxDist(450)
, mRemainingDuration(escort->mRemainingDuration) , mRemainingDuration(escort->mRemainingDuration)
, mCellX(std::numeric_limits<int>::max()) , mCellX(std::numeric_limits<int>::max())
, mCellY(std::numeric_limits<int>::max()) , mCellY(std::numeric_limits<int>::max())
{ {
mTargetActorRefId = escort->mTargetId;
mTargetActorId = escort->mTargetActorId;
// mDuration isn't saved in the save file, so just giving it "1" for now if the package has a duration. // mDuration isn't saved in the save file, so just giving it "1" for now if the package has a duration.
// The exact value of mDuration only matters for repeating packages. // The exact value of mDuration only matters for repeating packages.
if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves. if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
@ -78,7 +82,7 @@ namespace MWMechanics
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false);
const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false);
const float* const leaderPos = actor.getRefData().getPosition().pos; const float* const leaderPos = actor.getRefData().getPosition().pos;
const float* const followerPos = follower.getRefData().getPosition().pos; const float* const followerPos = follower.getRefData().getPosition().pos;
double differenceBetween[3]; double differenceBetween[3];
@ -119,18 +123,14 @@ namespace MWMechanics
return TypeIdEscort; return TypeIdEscort;
} }
MWWorld::Ptr AiEscort::getTarget() const
{
return MWBase::Environment::get().getWorld()->getPtr(mActorId, false);
}
void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const
{ {
std::unique_ptr<ESM::AiSequence::AiEscort> escort(new ESM::AiSequence::AiEscort()); std::unique_ptr<ESM::AiSequence::AiEscort> escort(new ESM::AiSequence::AiEscort());
escort->mData.mX = mX; escort->mData.mX = mX;
escort->mData.mY = mY; escort->mData.mY = mY;
escort->mData.mZ = mZ; escort->mData.mZ = mZ;
escort->mTargetId = mActorId; escort->mTargetId = mTargetActorRefId;
escort->mTargetActorId = mTargetActorId;
escort->mRemainingDuration = mRemainingDuration; escort->mRemainingDuration = mRemainingDuration;
escort->mCellId = mCellId; escort->mCellId = mCellId;

@ -24,11 +24,11 @@ namespace MWMechanics
/// Implementation of AiEscort /// Implementation of AiEscort
/** The Actor will escort the specified actor to the world position x, y, z until they reach their position, or they run out of time /** The Actor will escort the specified actor to the world position x, y, z until they reach their position, or they run out of time
\implement AiEscort **/ \implement AiEscort **/
AiEscort(const std::string &actorId,int duration, float x, float y, float z); AiEscort(const std::string &actorId, int duration, float x, float y, float z);
/// Implementation of AiEscortCell /// Implementation of AiEscortCell
/** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or they run out of time /** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or they run out of time
\implement AiEscortCell **/ \implement AiEscortCell **/
AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z); AiEscort(const std::string &actorId, const std::string &cellId, int duration, float x, float y, float z);
AiEscort(const ESM::AiSequence::AiEscort* escort); AiEscort(const ESM::AiSequence::AiEscort* escort);
@ -38,7 +38,6 @@ namespace MWMechanics
virtual int getTypeId() const; virtual int getTypeId() const;
MWWorld::Ptr getTarget() const;
virtual bool sideWithTarget() const { return true; } virtual bool sideWithTarget() const { return true; }
void writeState(ESM::AiSequence::AiSequence &sequence) const; void writeState(ESM::AiSequence::AiSequence &sequence) const;
@ -46,7 +45,6 @@ namespace MWMechanics
void fastForward(const MWWorld::Ptr& actor, AiState& state); void fastForward(const MWWorld::Ptr& actor, AiState& state);
private: private:
std::string mActorId;
std::string mCellId; std::string mCellId;
float mX; float mX;
float mY; float mY;

@ -35,32 +35,53 @@ struct AiFollowStorage : AiTemporaryBase
int AiFollow::mFollowIndexCounter = 0; int AiFollow::mFollowIndexCounter = 0;
AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) AiFollow::AiFollow(const std::string &actorId, float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) , mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
mTargetActorRefId = actorId;
} }
AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z) AiFollow::AiFollow(const std::string &actorId, const std::string &cellId, float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mActorRefId(actorId), mActorId(-1), mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++) , mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
mTargetActorRefId = actorId;
} }
AiFollow::AiFollow(const std::string &actorId, bool commanded) AiFollow::AiFollow(const MWWorld::Ptr& actor, float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++)
{
mTargetActorRefId = actor.getCellRef().getRefId();
mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId();
}
AiFollow::AiFollow(const MWWorld::Ptr& actor, const std::string &cellId, float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++)
{
mTargetActorRefId = actor.getCellRef().getRefId();
mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId();
}
AiFollow::AiFollow(const MWWorld::Ptr& actor, bool commanded)
: mAlwaysFollow(true), mCommanded(commanded), mDuration(0), mRemainingDuration(0), mX(0), mY(0), mZ(0) : mAlwaysFollow(true), mCommanded(commanded), mDuration(0), mRemainingDuration(0), mX(0), mY(0), mZ(0)
, mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) , mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
mTargetActorRefId = actor.getCellRef().getRefId();
mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId();
} }
AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow) AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
: mAlwaysFollow(follow->mAlwaysFollow), mCommanded(follow->mCommanded), mRemainingDuration(follow->mRemainingDuration) : mAlwaysFollow(follow->mAlwaysFollow), mCommanded(follow->mCommanded), mRemainingDuration(follow->mRemainingDuration)
, mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ) , mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ)
, mActorRefId(follow->mTargetId), mActorId(-1)
, mCellId(follow->mCellId), mActive(follow->mActive), mFollowIndex(mFollowIndexCounter++) , mCellId(follow->mCellId), mActive(follow->mActive), mFollowIndex(mFollowIndexCounter++)
{ {
// mDuration isn't saved in the save file, so just giving it "1" for now if the package had a duration. mTargetActorRefId = follow->mTargetId;
// The exact value of mDuration only matters for repeating packages. mTargetActorId = follow->mTargetActorId;
// mDuration isn't saved in the save file, so just giving it "1" for now if the package had a duration.
// The exact value of mDuration only matters for repeating packages.
if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves. if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
mDuration = 1; mDuration = 1;
else else
@ -204,7 +225,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
std::string AiFollow::getFollowedActor() std::string AiFollow::getFollowedActor()
{ {
return mActorRefId; return mTargetActorRefId;
} }
AiFollow *MWMechanics::AiFollow::clone() const AiFollow *MWMechanics::AiFollow::clone() const
@ -228,7 +249,8 @@ void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const
follow->mData.mX = mX; follow->mData.mX = mX;
follow->mData.mY = mY; follow->mData.mY = mY;
follow->mData.mZ = mZ; follow->mData.mZ = mZ;
follow->mTargetId = mActorRefId; follow->mTargetId = mTargetActorRefId;
follow->mTargetActorId = mTargetActorId;
follow->mRemainingDuration = mRemainingDuration; follow->mRemainingDuration = mRemainingDuration;
follow->mCellId = mCellId; follow->mCellId = mCellId;
follow->mAlwaysFollow = mAlwaysFollow; follow->mAlwaysFollow = mAlwaysFollow;
@ -241,29 +263,6 @@ void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const
sequence.mPackages.push_back(package); sequence.mPackages.push_back(package);
} }
MWWorld::Ptr AiFollow::getTarget() const
{
if (mActorId == -2)
return MWWorld::Ptr();
if (mActorId == -1)
{
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorRefId, false);
if (target.isEmpty())
{
mActorId = -2;
return target;
}
else
mActorId = target.getClass().getCreatureStats(target).getActorId();
}
if (mActorId != -1)
return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId);
else
return MWWorld::Ptr();
}
int AiFollow::getFollowIndex() const int AiFollow::getFollowIndex() const
{ {
return mFollowIndex; return mFollowIndex;

@ -25,16 +25,17 @@ namespace MWMechanics
class AiFollow : public AiPackage class AiFollow : public AiPackage
{ {
public: public:
AiFollow(const std::string &actorId, float duration, float x, float y, float z);
AiFollow(const std::string &actorId, const std::string &CellId, float duration, float x, float y, float z);
/// Follow Actor for duration or until you arrive at a world position /// Follow Actor for duration or until you arrive at a world position
AiFollow(const std::string &ActorId,float duration, float X, float Y, float Z); AiFollow(const MWWorld::Ptr& actor, float duration, float X, float Y, float Z);
/// Follow Actor for duration or until you arrive at a position in a cell /// Follow Actor for duration or until you arrive at a position in a cell
AiFollow(const std::string &ActorId,const std::string &CellId,float duration, float X, float Y, float Z); AiFollow(const MWWorld::Ptr& actor, const std::string &CellId, float duration, float X, float Y, float Z);
/// Follow Actor indefinitively /// Follow Actor indefinitively
AiFollow(const std::string &ActorId, bool commanded=false); AiFollow(const MWWorld::Ptr& actor, bool commanded=false);
AiFollow(const ESM::AiSequence::AiFollow* follow); AiFollow(const ESM::AiSequence::AiFollow* follow);
MWWorld::Ptr getTarget() const;
virtual bool sideWithTarget() const { return true; } virtual bool sideWithTarget() const { return true; }
virtual bool followTargetThroughDoors() const { return true; } virtual bool followTargetThroughDoors() const { return true; }
virtual bool shouldCancelPreviousAi() const { return !mCommanded; } virtual bool shouldCancelPreviousAi() const { return !mCommanded; }
@ -66,8 +67,6 @@ namespace MWMechanics
float mX; float mX;
float mY; float mY;
float mZ; float mZ;
std::string mActorRefId;
mutable int mActorId;
std::string mCellId; std::string mCellId;
bool mActive; // have we spotted the target? bool mActive; // have we spotted the target?
int mFollowIndex; int mFollowIndex;

@ -27,15 +27,36 @@ MWMechanics::AiPackage::~AiPackage() {}
MWMechanics::AiPackage::AiPackage() : MWMechanics::AiPackage::AiPackage() :
mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild
mTargetActorRefId(""),
mTargetActorId(-1),
mRotateOnTheRunChecks(0), mRotateOnTheRunChecks(0),
mIsShortcutting(false), mIsShortcutting(false),
mShortcutProhibited(false), mShortcutFailPos() mShortcutProhibited(false),
mShortcutFailPos()
{ {
} }
MWWorld::Ptr MWMechanics::AiPackage::getTarget() const MWWorld::Ptr MWMechanics::AiPackage::getTarget() const
{ {
return MWWorld::Ptr(); if (mTargetActorId == -2)
return MWWorld::Ptr();
if (mTargetActorId == -1)
{
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mTargetActorRefId, false);
if (target.isEmpty())
{
mTargetActorId = -2;
return target;
}
else
mTargetActorId = target.getClass().getCreatureStats(target).getActorId();
}
if (mTargetActorId != -1)
return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId);
else
return MWWorld::Ptr();
} }
bool MWMechanics::AiPackage::sideWithTarget() const bool MWMechanics::AiPackage::sideWithTarget() const

@ -128,6 +128,9 @@ namespace MWMechanics
float mTimer; float mTimer;
std::string mTargetActorRefId;
mutable int mTargetActorId;
osg::Vec3f mLastActorPos; osg::Vec3f mLastActorPos;
short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility

@ -15,13 +15,13 @@ namespace MWMechanics
{ {
AiPursue::AiPursue(const MWWorld::Ptr& actor) AiPursue::AiPursue(const MWWorld::Ptr& actor)
: mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId())
{ {
mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId();
} }
AiPursue::AiPursue(const ESM::AiSequence::AiPursue *pursue) AiPursue::AiPursue(const ESM::AiSequence::AiPursue *pursue)
: mTargetActorId(pursue->mTargetActorId)
{ {
mTargetActorId = pursue->mTargetActorId;
} }
AiPursue *MWMechanics::AiPursue::clone() const AiPursue *MWMechanics::AiPursue::clone() const

@ -40,10 +40,6 @@ namespace MWMechanics
virtual bool canCancel() const { return false; } virtual bool canCancel() const { return false; }
virtual bool shouldCancelPreviousAi() const { return false; } virtual bool shouldCancelPreviousAi() const { return false; }
private:
int mTargetActorId; // The actor to pursue
}; };
} }
#endif #endif

@ -547,7 +547,7 @@ namespace MWMechanics
|| (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name())) || (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name()))
&& !caster.isEmpty() && caster.getClass().isActor() && target != getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel()) && !caster.isEmpty() && caster.getClass().isActor() && target != getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel())
{ {
MWMechanics::AiFollow package(caster.getCellRef().getRefId(), true); MWMechanics::AiFollow package(caster, true);
target.getClass().getCreatureStats(target).getAiSequence().stack(package, target); target.getClass().getCreatureStats(target).getAiSequence().stack(package, target);
} }

@ -59,7 +59,7 @@ namespace MWMechanics
MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr()); MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr());
// Make the summoned creature follow its master and help in fights // Make the summoned creature follow its master and help in fights
AiFollow package(mActor.getCellRef().getRefId()); AiFollow package(mActor);
summonedCreatureStats.getAiSequence().stack(package, ref.getPtr()); summonedCreatureStats.getAiSequence().stack(package, ref.getPtr());
creatureActorId = summonedCreatureStats.getActorId(); creatureActorId = summonedCreatureStats.getActorId();

@ -46,6 +46,7 @@ namespace AiSequence
{ {
esm.getHNT (mData, "DATA"); esm.getHNT (mData, "DATA");
mTargetId = esm.getHNString("TARG"); mTargetId = esm.getHNString("TARG");
esm.getHNOT (mTargetActorId, "TAID");
esm.getHNT (mRemainingDuration, "DURA"); esm.getHNT (mRemainingDuration, "DURA");
mCellId = esm.getHNOString ("CELL"); mCellId = esm.getHNOString ("CELL");
} }
@ -54,6 +55,7 @@ namespace AiSequence
{ {
esm.writeHNT ("DATA", mData); esm.writeHNT ("DATA", mData);
esm.writeHNString ("TARG", mTargetId); esm.writeHNString ("TARG", mTargetId);
esm.writeHNT ("TAID", mTargetActorId);
esm.writeHNT ("DURA", mRemainingDuration); esm.writeHNT ("DURA", mRemainingDuration);
if (!mCellId.empty()) if (!mCellId.empty())
esm.writeHNString ("CELL", mCellId); esm.writeHNString ("CELL", mCellId);
@ -63,6 +65,7 @@ namespace AiSequence
{ {
esm.getHNT (mData, "DATA"); esm.getHNT (mData, "DATA");
mTargetId = esm.getHNString("TARG"); mTargetId = esm.getHNString("TARG");
esm.getHNOT (mTargetActorId, "TAID");
esm.getHNT (mRemainingDuration, "DURA"); esm.getHNT (mRemainingDuration, "DURA");
mCellId = esm.getHNOString ("CELL"); mCellId = esm.getHNOString ("CELL");
esm.getHNT (mAlwaysFollow, "ALWY"); esm.getHNT (mAlwaysFollow, "ALWY");
@ -76,6 +79,7 @@ namespace AiSequence
{ {
esm.writeHNT ("DATA", mData); esm.writeHNT ("DATA", mData);
esm.writeHNString("TARG", mTargetId); esm.writeHNString("TARG", mTargetId);
esm.writeHNT ("TAID", mTargetActorId);
esm.writeHNT ("DURA", mRemainingDuration); esm.writeHNT ("DURA", mRemainingDuration);
if (!mCellId.empty()) if (!mCellId.empty())
esm.writeHNString ("CELL", mCellId); esm.writeHNString ("CELL", mCellId);

@ -89,6 +89,7 @@ namespace ESM
{ {
AiEscortData mData; AiEscortData mData;
int mTargetActorId;
std::string mTargetId; std::string mTargetId;
std::string mCellId; std::string mCellId;
float mRemainingDuration; float mRemainingDuration;
@ -101,6 +102,7 @@ namespace ESM
{ {
AiEscortData mData; AiEscortData mData;
int mTargetActorId;
std::string mTargetId; std::string mTargetId;
std::string mCellId; std::string mCellId;
float mRemainingDuration; float mRemainingDuration;

@ -5,7 +5,7 @@
#include "defs.hpp" #include "defs.hpp"
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
int ESM::SavedGame::sCurrentFormat = 3; int ESM::SavedGame::sCurrentFormat = 4;
void ESM::SavedGame::load (ESMReader &esm) void ESM::SavedGame::load (ESMReader &esm)
{ {

Loading…
Cancel
Save