mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +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:
parent
2f13a17a39
commit
2e9985c1a3
11 changed files with 86 additions and 61 deletions
|
@ -540,7 +540,7 @@ namespace MWMechanics
|
|||
MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr());
|
||||
|
||||
// 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());
|
||||
int creatureActorId = summonedCreatureStats.getActorId();
|
||||
|
||||
|
@ -754,7 +754,7 @@ namespace MWMechanics
|
|||
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player)
|
||||
&& 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);
|
||||
npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId());
|
||||
}
|
||||
|
@ -783,7 +783,7 @@ namespace MWMechanics
|
|||
else if (!creatureStats.isHostile())
|
||||
{
|
||||
if (ptr.getClass().isClass(ptr, "Guard"))
|
||||
creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr);
|
||||
creatureStats.getAiSequence().stack(AiPursue(player), ptr);
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player);
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MWMechanics
|
|||
// NOTE: MIN_DIST_TO_DOOR_SQUARED is defined in obstacle.hpp
|
||||
|
||||
AiCombat::AiCombat(const MWWorld::Ptr& actor) :
|
||||
mTarget(actor),
|
||||
mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId()),
|
||||
mTimerAttack(0),
|
||||
mTimerReact(0),
|
||||
mTimerCombatMove(0),
|
||||
|
@ -153,7 +153,9 @@ namespace MWMechanics
|
|||
|| actor.getClass().getCreatureStats(actor).getHealth().getCurrent() <= 0)
|
||||
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;
|
||||
|
||||
//Update every frame
|
||||
|
@ -325,7 +327,7 @@ namespace MWMechanics
|
|||
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
Ogre::Vector3 vActorPos(pos.pos);
|
||||
Ogre::Vector3 vTargetPos(mTarget.getRefData().getPosition().pos);
|
||||
Ogre::Vector3 vTargetPos(target.getRefData().getPosition().pos);
|
||||
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
|
||||
|
||||
bool isStuck = false;
|
||||
|
@ -396,7 +398,7 @@ namespace MWMechanics
|
|||
else // remote pathfinding
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -432,7 +434,7 @@ namespace MWMechanics
|
|||
|
||||
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
|
||||
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)
|
||||
//then start attacking
|
||||
float speed1 = actorCls.getSpeed(actor);
|
||||
float speed2 = mTarget.getClass().getSpeed(mTarget);
|
||||
if(mTarget.getClass().getMovementSettings(mTarget).mPosition[0] == 0
|
||||
&& mTarget.getClass().getMovementSettings(mTarget).mPosition[1] == 0)
|
||||
float speed2 = target.getClass().getSpeed(target);
|
||||
if(target.getClass().getMovementSettings(target).mPosition[0] == 0
|
||||
&& target.getClass().getMovementSettings(target).mPosition[1] == 0)
|
||||
speed2 = 0;
|
||||
|
||||
float s1 = distToTarget - weapRange;
|
||||
|
@ -570,9 +572,9 @@ namespace MWMechanics
|
|||
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;
|
||||
|
||||
|
@ -627,9 +629,12 @@ namespace MWMechanics
|
|||
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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace MWMechanics
|
|||
virtual unsigned int getPriority() const;
|
||||
|
||||
///Returns target ID
|
||||
const std::string &getTargetId() const;
|
||||
std::string getTargetId() const;
|
||||
|
||||
private:
|
||||
PathFinder mPathFinder;
|
||||
|
@ -53,7 +53,7 @@ namespace MWMechanics
|
|||
|
||||
ESM::Position mLastPos;
|
||||
MWMechanics::Movement mMovement;
|
||||
MWWorld::Ptr mTarget;
|
||||
int mTargetActorId;
|
||||
|
||||
const MWWorld::CellStore* mCell;
|
||||
ObstacleCheck mObstacleCheck;
|
||||
|
@ -63,7 +63,7 @@ namespace MWMechanics
|
|||
MWWorld::CellRefList<ESM::Door>::List::iterator mDoorIter;
|
||||
MWWorld::CellRefList<ESM::Door>& mDoors;
|
||||
|
||||
void buildNewPath(const MWWorld::Ptr& actor);
|
||||
void buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/timestamp.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
|
||||
|
@ -19,8 +21,8 @@
|
|||
|
||||
namespace MWMechanics
|
||||
{
|
||||
AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z)
|
||||
: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration)
|
||||
AiEscort::AiEscort(const MWWorld::Ptr& actor, int duration, float x, float y, float z)
|
||||
: mActorId(actor.getClass().getCreatureStats(actor).getActorId()), mX(x), mY(y), mZ(z), mDuration(duration)
|
||||
, mCellX(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)
|
||||
: mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration)
|
||||
AiEscort::AiEscort(const MWWorld::Ptr& actor, const std::string &cellId,int duration, float x, float y, float z)
|
||||
: mActorId(actor.getClass().getCreatureStats(actor).getActorId()), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration)
|
||||
, mCellX(std::numeric_limits<int>::max())
|
||||
, mCellY(std::numeric_limits<int>::max())
|
||||
{
|
||||
|
@ -75,7 +77,14 @@ namespace MWMechanics
|
|||
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 followerPos = follower.getRefData().getPosition().pos;
|
||||
double differenceBetween[3];
|
||||
|
|
|
@ -15,11 +15,11 @@ namespace MWMechanics
|
|||
/// 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
|
||||
\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
|
||||
/** 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 **/
|
||||
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;
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace MWMechanics
|
|||
virtual int getTypeId() const;
|
||||
|
||||
private:
|
||||
std::string mActorId;
|
||||
int mActorId;
|
||||
std::string mCellId;
|
||||
float mX;
|
||||
float mY;
|
||||
|
|
|
@ -11,23 +11,26 @@
|
|||
|
||||
#include "steering.hpp"
|
||||
|
||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
|
||||
: mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(""), AiPackage()
|
||||
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), 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)
|
||||
: mAlwaysFollow(false), mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(cellId), AiPackage()
|
||||
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), mCellId(cellId), AiPackage()
|
||||
{
|
||||
mActorId = actor.getClass().getCreatureStats(actor).getActorId();
|
||||
}
|
||||
|
||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId)
|
||||
: mAlwaysFollow(true), mDuration(0), mX(0), mY(0), mZ(0), mActorId(actorId), mCellId(""), AiPackage()
|
||||
MWMechanics::AiFollow::AiFollow(const MWWorld::Ptr& actor)
|
||||
: 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)
|
||||
{
|
||||
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
|
||||
|
||||
|
@ -75,7 +78,8 @@ bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
|||
|
||||
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
|
||||
|
|
|
@ -15,11 +15,11 @@ namespace MWMechanics
|
|||
{
|
||||
public:
|
||||
/// 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
|
||||
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
|
||||
AiFollow(const std::string &ActorId);
|
||||
AiFollow(const MWWorld::Ptr& actor);
|
||||
|
||||
virtual AiFollow *clone() const;
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace MWMechanics
|
|||
float mX;
|
||||
float mY;
|
||||
float mZ;
|
||||
std::string mActorId;
|
||||
int mActorId; // The actor we should follow
|
||||
std::string mCellId;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include "../mwworld/action.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
#include "creaturestats.hpp"
|
||||
|
||||
MWMechanics::AiPursue::AiPursue(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
MWMechanics::AiPursue::AiPursue(const MWWorld::Ptr& actor)
|
||||
: mActorId(actor.getClass().getCreatureStats(actor).getActorId())
|
||||
{
|
||||
}
|
||||
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
|
||||
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())
|
||||
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
|
||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(mObjectId,false);
|
||||
MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); //Arrest player
|
||||
target.getClass().activate(target,actor).get()->execute(actor); //Arrest player
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -16,14 +16,14 @@ namespace MWMechanics
|
|||
{
|
||||
public:
|
||||
///Constructor
|
||||
/** \param objectId Actor to pursue **/
|
||||
AiPursue(const std::string &objectId);
|
||||
/** \param actor Actor to pursue **/
|
||||
AiPursue(const MWWorld::Ptr& actor);
|
||||
virtual AiPursue *clone() const;
|
||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
||||
virtual int getTypeId() const;
|
||||
|
||||
private:
|
||||
std::string mObjectId;
|
||||
int mActorId; // The actor to pursue
|
||||
int mCellX;
|
||||
int mCellY;
|
||||
};
|
||||
|
|
|
@ -175,7 +175,8 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
|
|||
else if (it->mType == ESM::AI_Escort)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -190,7 +191,8 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
|
|||
else //if (it->mType == ESM::AI_Follow)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace MWScript
|
|||
|
||||
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
|
||||
|
||||
Interpreter::Type_Float duration = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
@ -107,7 +108,7 @@ namespace MWScript
|
|||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
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);
|
||||
|
||||
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
|
||||
|
@ -126,6 +127,7 @@ namespace MWScript
|
|||
|
||||
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
|
||||
|
||||
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
@ -145,7 +147,7 @@ namespace MWScript
|
|||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
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);
|
||||
|
||||
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
|
||||
|
@ -281,6 +283,7 @@ namespace MWScript
|
|||
|
||||
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
|
||||
|
||||
Interpreter::Type_Float duration = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
@ -297,7 +300,7 @@ namespace MWScript
|
|||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
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);
|
||||
|
||||
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
|
||||
|
@ -316,6 +319,7 @@ namespace MWScript
|
|||
|
||||
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
|
||||
|
||||
std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
@ -335,8 +339,8 @@ namespace MWScript
|
|||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
for (unsigned int i=0; i<arg0; ++i) runtime.pop();
|
||||
|
||||
MWMechanics::AiFollow followPackage(actorID, cellID, duration, x, y ,z);
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
|
||||
MWMechanics::AiFollow followPackage(actor, cellID, duration, x, y ,z);
|
||||
ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
|
||||
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
|
||||
<< std::endl;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue