Duration fixes for Follow and Escort

pull/1/head
Allofich 9 years ago
parent 148f2c9539
commit 3bebbab78e

@ -24,29 +24,19 @@
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), mRemainingDuration(static_cast<float>(duration)) : mActorId(actorId), 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())
{ {
mMaxDist = 450; mMaxDist = 450;
// The CS Help File states that if a duration is given, the AI package will run for that long
// BUT if a location is givin, it "trumps" the duration so it will simply escort to that location.
if(mX != 0 || mY != 0 || mZ != 0)
mRemainingDuration = 0;
} }
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), mRemainingDuration(static_cast<float>(duration)) : mActorId(actorId), 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())
{ {
mMaxDist = 450; mMaxDist = 450;
// The CS Help File states that if a duration is given, the AI package will run for that long
// BUT if a location is given, it "trumps" the duration so it will simply escort to that location.
if(mX != 0 || mY != 0 || mZ != 0)
mRemainingDuration = 0;
} }
AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort)
@ -56,6 +46,12 @@ namespace MWMechanics
, mCellX(std::numeric_limits<int>::max()) , mCellX(std::numeric_limits<int>::max())
, mCellY(std::numeric_limits<int>::max()) , mCellY(std::numeric_limits<int>::max())
{ {
// 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
if (mRemainingDuration != 0)
mDuration = 1;
else
mDuration = 0;
} }
@ -68,13 +64,13 @@ namespace MWMechanics
{ {
// If AiEscort has ran for as long or longer then the duration specified // If AiEscort has ran for as long or longer then the duration specified
// and the duration is not infinite, the package is complete. // and the duration is not infinite, the package is complete.
if(mRemainingDuration != 0) if(mDuration > 0)
{ {
mRemainingDuration -= duration; mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600);
if (duration <= 0) if (mRemainingDuration <= 0)
{ {
// Reset mStarted to false so that package can be repeated again mRemainingDuration = mDuration;
mStarted = false; mStarted = false; // Reset to false so this package will build path again when repeating
return true; return true;
} }
} }
@ -105,8 +101,8 @@ namespace MWMechanics
point.mUnknown = 0; point.mUnknown = 0;
if(pathTo(actor,point,duration)) //Returns true on path complete if(pathTo(actor,point,duration)) //Returns true on path complete
{ {
// Reset mStarted to false so that package can be repeated again mRemainingDuration = mDuration;
mStarted = false; mStarted = false; // Reset to false so this package will build path again when repeating
return true; return true;
} }
mMaxDist = 450; mMaxDist = 450;
@ -147,5 +143,11 @@ namespace MWMechanics
package.mPackage = escort.release(); package.mPackage = escort.release();
sequence.mPackages.push_back(package); sequence.mPackages.push_back(package);
} }
void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state)
{
// Update duration counter
mRemainingDuration--;
}
} }

@ -42,6 +42,8 @@ namespace MWMechanics
void writeState(ESM::AiSequence::AiSequence &sequence) const; void writeState(ESM::AiSequence::AiSequence &sequence) const;
void fastForward(const MWWorld::Ptr& actor, AiState& state);
private: private:
std::string mActorId; std::string mActorId;
std::string mCellId; std::string mCellId;
@ -49,7 +51,8 @@ namespace MWMechanics
float mY; float mY;
float mZ; float mZ;
float mMaxDist; float mMaxDist;
float mRemainingDuration; // In seconds float mDuration; // In hours
float mRemainingDuration; // In hours
int mCellX; int mCellX;
int mCellY; int mCellY;

@ -28,30 +28,35 @@ 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), 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++) , mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
} }
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), 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++) , mActorRefId(actorId), mActorId(-1), mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
} }
AiFollow::AiFollow(const std::string &actorId, bool commanded) AiFollow::AiFollow(const std::string &actorId, bool commanded)
: mAlwaysFollow(true), mCommanded(commanded), 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++) , mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++)
{ {
} }
AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow) AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
: mAlwaysFollow(follow->mAlwaysFollow), mCommanded(follow->mCommanded), mRemainingDuration(follow->mRemainingDuration) : 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) , 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 has a duration.
// The exact value of mDuration only matters for repeating packages
if (mRemainingDuration != 0)
mDuration = 1;
else
mDuration = 0;
} }
bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
@ -101,11 +106,14 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte
if(!mAlwaysFollow) //Update if you only follow for a bit if(!mAlwaysFollow) //Update if you only follow for a bit
{ {
//Check if we've run out of time //Check if we've run out of time
if (mRemainingDuration != 0) if (mDuration != 0)
{ {
mRemainingDuration -= duration; mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600);
if (duration <= 0) if (mRemainingDuration <= 0)
{
mRemainingDuration = mDuration;
return true; return true;
}
} }
if((pos.pos[0]-mX)*(pos.pos[0]-mX) + if((pos.pos[0]-mX)*(pos.pos[0]-mX) +
@ -228,4 +236,10 @@ int AiFollow::getFollowIndex() const
return mFollowIndex; return mFollowIndex;
} }
void AiFollow::fastForward(const MWWorld::Ptr& actor, AiState &state)
{
// Update duration counter
mRemainingDuration--;
}
} }

@ -50,12 +50,15 @@ namespace MWMechanics
int getFollowIndex() const; int getFollowIndex() const;
void fastForward(const MWWorld::Ptr& actor, AiState& state);
private: private:
/// This will make the actor always follow. /// This will make the actor always follow.
/** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/ /** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/
bool mAlwaysFollow; bool mAlwaysFollow;
bool mCommanded; bool mCommanded;
float mRemainingDuration; // Seconds float mDuration; // Hours
float mRemainingDuration; // Hours
float mX; float mX;
float mY; float mY;
float mZ; float mZ;

@ -64,7 +64,7 @@ namespace MWMechanics
if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration)) if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
{ {
actor.getClass().getMovementSettings(actor).mPosition[1] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
mStarted = false; mStarted = false; // Reset to false so this package will build path again when repeating
return true; return true;
} }
return false; return false;

@ -15,7 +15,7 @@ namespace AiSequence
void AiWander::load(ESMReader &esm) void AiWander::load(ESMReader &esm)
{ {
esm.getHNT (mData, "DATA"); esm.getHNT (mData, "DATA");
esm.getHNT(mDurationData, "STAR"); esm.getHNT(mDurationData, "STAR"); // was mStartTime
mStoredInitialActorPosition = false; mStoredInitialActorPosition = false;
if (esm.isNextSub("POS_")) if (esm.isNextSub("POS_"))
{ {

@ -66,7 +66,7 @@ namespace ESM
struct AiWander : AiPackage struct AiWander : AiPackage
{ {
AiWanderData mData; AiWanderData mData;
AiWanderDuration mDurationData; // was ESM::TimeStamp mStartTime; AiWanderDuration mDurationData; // was ESM::TimeStamp mStartTime
bool mStoredInitialActorPosition; bool mStoredInitialActorPosition;
ESM::Vector3 mInitialActorPosition; ESM::Vector3 mInitialActorPosition;

Loading…
Cancel
Save