1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-29 19:06:41 +00:00

Change all AI packages (except AiActivate) to use ActorIds

More robust in case the target changes cell or there are multiple targets with the same RefId
This commit is contained in:
scrawl 2014-05-15 03:01:48 +02:00
parent 2f13a17a39
commit 2e9985c1a3
11 changed files with 86 additions and 61 deletions

View file

@ -540,7 +540,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(ptr.getRefData().getHandle()); AiFollow package(ptr);
summonedCreatureStats.getAiSequence().stack(package, ref.getPtr()); summonedCreatureStats.getAiSequence().stack(package, ref.getPtr());
int creatureActorId = summonedCreatureStats.getActorId(); int creatureActorId = summonedCreatureStats.getActorId();
@ -754,7 +754,7 @@ namespace MWMechanics
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getWorld()->getLOS(ptr, player)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
{ {
creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr); creatureStats.getAiSequence().stack(AiPursue(player), ptr);
creatureStats.setAlarmed(true); creatureStats.setAlarmed(true);
npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId()); npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId());
} }
@ -783,7 +783,7 @@ namespace MWMechanics
else if (!creatureStats.isHostile()) else if (!creatureStats.isHostile())
{ {
if (ptr.getClass().isClass(ptr, "Guard")) if (ptr.getClass().isClass(ptr, "Guard"))
creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr); creatureStats.getAiSequence().stack(AiPursue(player), ptr);
else else
{ {
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player); MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player);

View file

@ -81,7 +81,7 @@ namespace MWMechanics
// NOTE: MIN_DIST_TO_DOOR_SQUARED is defined in obstacle.hpp // NOTE: MIN_DIST_TO_DOOR_SQUARED is defined in obstacle.hpp
AiCombat::AiCombat(const MWWorld::Ptr& actor) : AiCombat::AiCombat(const MWWorld::Ptr& actor) :
mTarget(actor), mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId()),
mTimerAttack(0), mTimerAttack(0),
mTimerReact(0), mTimerReact(0),
mTimerCombatMove(0), mTimerCombatMove(0),
@ -153,7 +153,9 @@ namespace MWMechanics
|| actor.getClass().getCreatureStats(actor).getHealth().getCurrent() <= 0) || actor.getClass().getCreatureStats(actor).getHealth().getCurrent() <= 0)
return true; return true;
if(mTarget.getClass().getCreatureStats(mTarget).isDead()) MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId);
if(target.getClass().getCreatureStats(target).isDead())
return true; return true;
//Update every frame //Update every frame
@ -325,7 +327,7 @@ namespace MWMechanics
ESM::Position pos = actor.getRefData().getPosition(); ESM::Position pos = actor.getRefData().getPosition();
Ogre::Vector3 vActorPos(pos.pos); Ogre::Vector3 vActorPos(pos.pos);
Ogre::Vector3 vTargetPos(mTarget.getRefData().getPosition().pos); Ogre::Vector3 vTargetPos(target.getRefData().getPosition().pos);
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos; Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
bool isStuck = false; bool isStuck = false;
@ -396,7 +398,7 @@ namespace MWMechanics
else // remote pathfinding else // remote pathfinding
{ {
bool preferShortcut = false; bool preferShortcut = false;
bool inLOS = MWBase::Environment::get().getWorld()->getLOS(actor, mTarget); bool inLOS = MWBase::Environment::get().getWorld()->getLOS(actor, target);
if(mReadyToAttack) isStuck = false; if(mReadyToAttack) isStuck = false;
@ -432,7 +434,7 @@ namespace MWMechanics
mFollowTarget = false; mFollowTarget = false;
buildNewPath(actor); //may fail to build a path, check before use buildNewPath(actor, target); //may fail to build a path, check before use
//delete visited path node //delete visited path node
mPathFinder.checkWaypoint(pos.pos[0],pos.pos[1],pos.pos[2]); mPathFinder.checkWaypoint(pos.pos[0],pos.pos[1],pos.pos[2]);
@ -476,9 +478,9 @@ namespace MWMechanics
//less than in time of playing weapon anim from 'start' to 'hit' tags (t_swing) //less than in time of playing weapon anim from 'start' to 'hit' tags (t_swing)
//then start attacking //then start attacking
float speed1 = actorCls.getSpeed(actor); float speed1 = actorCls.getSpeed(actor);
float speed2 = mTarget.getClass().getSpeed(mTarget); float speed2 = target.getClass().getSpeed(target);
if(mTarget.getClass().getMovementSettings(mTarget).mPosition[0] == 0 if(target.getClass().getMovementSettings(target).mPosition[0] == 0
&& mTarget.getClass().getMovementSettings(mTarget).mPosition[1] == 0) && target.getClass().getMovementSettings(target).mPosition[1] == 0)
speed2 = 0; speed2 = 0;
float s1 = distToTarget - weapRange; float s1 = distToTarget - weapRange;
@ -570,9 +572,9 @@ namespace MWMechanics
return false; return false;
} }
void AiCombat::buildNewPath(const MWWorld::Ptr& actor) void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
{ {
Ogre::Vector3 newPathTarget = Ogre::Vector3(mTarget.getRefData().getPosition().pos); Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos);
float dist; float dist;
@ -627,9 +629,12 @@ namespace MWMechanics
return 1; return 1;
} }
const std::string &AiCombat::getTargetId() const std::string AiCombat::getTargetId() const
{ {
return mTarget.getRefData().getHandle(); MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId);
if (target.isEmpty())
return "";
return target.getRefData().getHandle();
} }

View file

@ -31,7 +31,7 @@ namespace MWMechanics
virtual unsigned int getPriority() const; virtual unsigned int getPriority() const;
///Returns target ID ///Returns target ID
const std::string &getTargetId() const; std::string getTargetId() const;
private: private:
PathFinder mPathFinder; PathFinder mPathFinder;
@ -53,7 +53,7 @@ namespace MWMechanics
ESM::Position mLastPos; ESM::Position mLastPos;
MWMechanics::Movement mMovement; MWMechanics::Movement mMovement;
MWWorld::Ptr mTarget; int mTargetActorId;
const MWWorld::CellStore* mCell; const MWWorld::CellStore* mCell;
ObstacleCheck mObstacleCheck; ObstacleCheck mObstacleCheck;
@ -63,7 +63,7 @@ namespace MWMechanics
MWWorld::CellRefList<ESM::Door>::List::iterator mDoorIter; MWWorld::CellRefList<ESM::Door>::List::iterator mDoorIter;
MWWorld::CellRefList<ESM::Door>& mDoors; MWWorld::CellRefList<ESM::Door>& mDoors;
void buildNewPath(const MWWorld::Ptr& actor); void buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target);
}; };
} }

View file

@ -8,6 +8,8 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/timestamp.hpp" #include "../mwworld/timestamp.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "steering.hpp" #include "steering.hpp"
#include "movement.hpp" #include "movement.hpp"
@ -19,8 +21,8 @@
namespace MWMechanics namespace MWMechanics
{ {
AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z) AiEscort::AiEscort(const MWWorld::Ptr& actor, int duration, float x, float y, float z)
: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) : mActorId(actor.getClass().getCreatureStats(actor).getActorId()), mX(x), mY(y), mZ(z), mDuration(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())
{ {
@ -38,8 +40,8 @@ namespace MWMechanics
} }
} }
AiEscort::AiEscort(const std::string &actorId, const std::string &cellId,int duration, float x, float y, float z) AiEscort::AiEscort(const MWWorld::Ptr& actor, const std::string &cellId,int duration, float x, float y, float z)
: mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) : mActorId(actor.getClass().getCreatureStats(actor).getActorId()), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(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())
{ {
@ -75,7 +77,14 @@ namespace MWMechanics
return true; return true;
} }
const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId);
if (follower.isEmpty())
{
// The follower disappeared
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
return true;
}
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];

View file

@ -15,11 +15,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 MWWorld::Ptr& actor,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 MWWorld::Ptr& actor,const std::string &cellId,int duration, float x, float y, float z);
virtual AiEscort *clone() const; virtual AiEscort *clone() const;
@ -28,7 +28,7 @@ namespace MWMechanics
virtual int getTypeId() const; virtual int getTypeId() const;
private: private:
std::string mActorId; int mActorId;
std::string mCellId; std::string mCellId;
float mX; float mX;
float mY; float mY;

View file

@ -11,23 +11,26 @@
#include "steering.hpp" #include "steering.hpp"
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) MWMechanics::AiFollow::AiFollow(const MWWorld::Ptr& actor,float duration, float x, float y, float z)
: mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(""), AiPackage() : mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mCellId(""), AiPackage()
{ {
mActorId = actor.getClass().getCreatureStats(actor).getActorId();
} }
MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z) MWMechanics::AiFollow::AiFollow(const MWWorld::Ptr& actor,const std::string &cellId,float duration, float x, float y, float z)
: mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(cellId), AiPackage() : mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mCellId(cellId), AiPackage()
{ {
mActorId = actor.getClass().getCreatureStats(actor).getActorId();
} }
MWMechanics::AiFollow::AiFollow(const std::string &actorId) MWMechanics::AiFollow::AiFollow(const MWWorld::Ptr& actor)
: mAlwaysFollow(true), mDuration(0), mX(0), mY(0), mZ(0), mActorId(actorId), mCellId(""), AiPackage() : mAlwaysFollow(true), mDuration(0), mX(0), mY(0), mZ(0), mCellId(""), AiPackage()
{ {
mActorId = actor.getClass().getCreatureStats(actor).getActorId();
} }
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration) bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
{ {
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorId, false); //The target to follow const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId); //The target to follow
if(target == MWWorld::Ptr()) return true; //Target doesn't exist if(target == MWWorld::Ptr()) return true; //Target doesn't exist
@ -75,7 +78,8 @@ bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
std::string MWMechanics::AiFollow::getFollowedActor() std::string MWMechanics::AiFollow::getFollowedActor()
{ {
return mActorId; const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId); //The target to follow
return target.getCellRef().mRefID;
} }
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const

View file

@ -15,11 +15,11 @@ namespace MWMechanics
{ {
public: public:
/// 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); AiFollow(const MWWorld::Ptr& actor);
virtual AiFollow *clone() const; virtual AiFollow *clone() const;
@ -38,7 +38,7 @@ namespace MWMechanics
float mX; float mX;
float mY; float mY;
float mZ; float mZ;
std::string mActorId; int mActorId; // The actor we should follow
std::string mCellId; std::string mCellId;
}; };
} }

View file

@ -7,12 +7,14 @@
#include "../mwworld/action.hpp" #include "../mwworld/action.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "steering.hpp" #include "steering.hpp"
#include "movement.hpp" #include "movement.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
MWMechanics::AiPursue::AiPursue(const std::string &objectId) MWMechanics::AiPursue::AiPursue(const MWWorld::Ptr& actor)
: mObjectId(objectId) : mActorId(actor.getClass().getCreatureStats(actor).getActorId())
{ {
} }
MWMechanics::AiPursue *MWMechanics::AiPursue::clone() const MWMechanics::AiPursue *MWMechanics::AiPursue::clone() const
@ -23,7 +25,7 @@ bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration)
{ {
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId); //The target to follow
if(target == MWWorld::Ptr()) if(target == MWWorld::Ptr())
return true; //Target doesn't exist return true; //Target doesn't exist
@ -33,8 +35,7 @@ bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration)
if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < 100) { //Stop when you get close if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < 100) { //Stop when you get close
actor.getClass().getMovementSettings(actor).mPosition[1] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(mObjectId,false); target.getClass().activate(target,actor).get()->execute(actor); //Arrest player
MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); //Arrest player
return true; return true;
} }
else { else {

View file

@ -16,14 +16,14 @@ namespace MWMechanics
{ {
public: public:
///Constructor ///Constructor
/** \param objectId Actor to pursue **/ /** \param actor Actor to pursue **/
AiPursue(const std::string &objectId); AiPursue(const MWWorld::Ptr& actor);
virtual AiPursue *clone() const; virtual AiPursue *clone() const;
virtual bool execute (const MWWorld::Ptr& actor,float duration); virtual bool execute (const MWWorld::Ptr& actor,float duration);
virtual int getTypeId() const; virtual int getTypeId() const;
private: private:
std::string mObjectId; int mActorId; // The actor to pursue
int mCellX; int mCellX;
int mCellY; int mCellY;
}; };

View file

@ -175,7 +175,8 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
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); MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(data.mId.toString(), false);
package = new MWMechanics::AiEscort(target, data.mDuration, data.mX, data.mY, data.mZ);
} }
else if (it->mType == ESM::AI_Travel) else if (it->mType == ESM::AI_Travel)
{ {
@ -190,7 +191,8 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
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); MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(data.mId.toString(), false);
package = new MWMechanics::AiFollow(target, data.mDuration, data.mX, data.mY, data.mZ);
} }
mPackages.push_back(package); mPackages.push_back(package);
} }

View file

@ -91,6 +91,7 @@ namespace MWScript
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
Interpreter::Type_Float duration = runtime[0].mFloat; Interpreter::Type_Float duration = runtime[0].mFloat;
runtime.pop(); runtime.pop();
@ -107,7 +108,7 @@ namespace MWScript
// discard additional arguments (reset), because we have no idea what they mean. // discard additional arguments (reset), because we have no idea what they mean.
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiEscort escortPackage(actorID, duration, x, y, z); MWMechanics::AiEscort escortPackage(actor, duration, x, y, z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr);
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
@ -126,6 +127,7 @@ namespace MWScript
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
@ -145,7 +147,7 @@ namespace MWScript
// discard additional arguments (reset), because we have no idea what they mean. // discard additional arguments (reset), because we have no idea what they mean.
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiEscort escortPackage(actorID, cellID, duration, x, y, z); MWMechanics::AiEscort escortPackage(actor, cellID, duration, x, y, z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr);
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
@ -281,6 +283,7 @@ namespace MWScript
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
Interpreter::Type_Float duration = runtime[0].mFloat; Interpreter::Type_Float duration = runtime[0].mFloat;
runtime.pop(); runtime.pop();
@ -297,7 +300,7 @@ namespace MWScript
// discard additional arguments (reset), because we have no idea what they mean. // discard additional arguments (reset), because we have no idea what they mean.
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiFollow followPackage(actorID, duration, x, y ,z); MWMechanics::AiFollow followPackage(actor, duration, x, y ,z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
@ -316,6 +319,7 @@ namespace MWScript
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
@ -335,8 +339,8 @@ namespace MWScript
// discard additional arguments (reset), because we have no idea what they mean. // discard additional arguments (reset), because we have no idea what they mean.
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiFollow followPackage(actorID, cellID, duration, x, y ,z); MWMechanics::AiFollow followPackage(actor, cellID, duration, x, y ,z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr); ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
<< std::endl; << std::endl;
} }