forked from teamnwah/openmw-tes3coop
Store integer actor ID in AI packages (bug #4036)
This commit is contained in:
parent
9d0ce25052
commit
fed10e87aa
16 changed files with 93 additions and 72 deletions
|
@ -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…
Reference in a new issue