From 3bebbab78e752730b59b9e2987ca1861cb1d5402 Mon Sep 17 00:00:00 2001 From: Allofich Date: Sat, 11 Jun 2016 22:34:49 +0900 Subject: [PATCH] Duration fixes for Follow and Escort --- apps/openmw/mwmechanics/aiescort.cpp | 40 +++++++++++++++------------- apps/openmw/mwmechanics/aiescort.hpp | 5 +++- apps/openmw/mwmechanics/aifollow.cpp | 32 +++++++++++++++------- apps/openmw/mwmechanics/aifollow.hpp | 5 +++- apps/openmw/mwmechanics/aitravel.cpp | 2 +- components/esm/aisequence.cpp | 2 +- components/esm/aisequence.hpp | 2 +- 7 files changed, 55 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 48d30f3e7..36aebfe4a 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -24,29 +24,19 @@ namespace MWMechanics { 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(duration)) + : mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) , mCellX(std::numeric_limits::max()) , mCellY(std::numeric_limits::max()) { 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) - : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mRemainingDuration(static_cast(duration)) + : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) , mCellX(std::numeric_limits::max()) , mCellY(std::numeric_limits::max()) { 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) @@ -56,6 +46,12 @@ namespace MWMechanics , mCellX(std::numeric_limits::max()) , mCellY(std::numeric_limits::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 // and the duration is not infinite, the package is complete. - if(mRemainingDuration != 0) + if(mDuration > 0) { - mRemainingDuration -= duration; - if (duration <= 0) + mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + if (mRemainingDuration <= 0) { - // Reset mStarted to false so that package can be repeated again - mStarted = false; + mRemainingDuration = mDuration; + mStarted = false; // Reset to false so this package will build path again when repeating return true; } } @@ -105,8 +101,8 @@ namespace MWMechanics point.mUnknown = 0; if(pathTo(actor,point,duration)) //Returns true on path complete { - // Reset mStarted to false so that package can be repeated again - mStarted = false; + mRemainingDuration = mDuration; + mStarted = false; // Reset to false so this package will build path again when repeating return true; } mMaxDist = 450; @@ -147,5 +143,11 @@ namespace MWMechanics package.mPackage = escort.release(); sequence.mPackages.push_back(package); } + +void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state) +{ + // Update duration counter + mRemainingDuration--; +} } diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index 677cf6f43..dcb136ca4 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -42,6 +42,8 @@ namespace MWMechanics void writeState(ESM::AiSequence::AiSequence &sequence) const; + void fastForward(const MWWorld::Ptr& actor, AiState& state); + private: std::string mActorId; std::string mCellId; @@ -49,7 +51,8 @@ namespace MWMechanics float mY; float mZ; float mMaxDist; - float mRemainingDuration; // In seconds + float mDuration; // In hours + float mRemainingDuration; // In hours int mCellX; int mCellY; diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index 02daec19e..dd2219c45 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -28,30 +28,35 @@ struct AiFollowStorage : AiTemporaryBase int AiFollow::mFollowIndexCounter = 0; 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++) { } + 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++) { } 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++) { - } 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) , mActorRefId(follow->mTargetId), mActorId(-1) , 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) @@ -101,11 +106,14 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte if(!mAlwaysFollow) //Update if you only follow for a bit { //Check if we've run out of time - if (mRemainingDuration != 0) + if (mDuration != 0) { - mRemainingDuration -= duration; - if (duration <= 0) + mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + if (mRemainingDuration <= 0) + { + mRemainingDuration = mDuration; return true; + } } if((pos.pos[0]-mX)*(pos.pos[0]-mX) + @@ -228,4 +236,10 @@ int AiFollow::getFollowIndex() const return mFollowIndex; } +void AiFollow::fastForward(const MWWorld::Ptr& actor, AiState &state) +{ + // Update duration counter + mRemainingDuration--; +} + } diff --git a/apps/openmw/mwmechanics/aifollow.hpp b/apps/openmw/mwmechanics/aifollow.hpp index 0f955879a..719909ebc 100644 --- a/apps/openmw/mwmechanics/aifollow.hpp +++ b/apps/openmw/mwmechanics/aifollow.hpp @@ -50,12 +50,15 @@ namespace MWMechanics int getFollowIndex() const; + void fastForward(const MWWorld::Ptr& actor, AiState& state); + private: /// This will make the actor always follow. /** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/ bool mAlwaysFollow; bool mCommanded; - float mRemainingDuration; // Seconds + float mDuration; // Hours + float mRemainingDuration; // Hours float mX; float mY; float mZ; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 3026b4393..5375644be 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -64,7 +64,7 @@ namespace MWMechanics if (pathTo(actor, ESM::Pathgrid::Point(static_cast(mX), static_cast(mY), static_cast(mZ)), duration)) { 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 false; diff --git a/components/esm/aisequence.cpp b/components/esm/aisequence.cpp index 473313940..71f87b170 100644 --- a/components/esm/aisequence.cpp +++ b/components/esm/aisequence.cpp @@ -15,7 +15,7 @@ namespace AiSequence void AiWander::load(ESMReader &esm) { esm.getHNT (mData, "DATA"); - esm.getHNT(mDurationData, "STAR"); + esm.getHNT(mDurationData, "STAR"); // was mStartTime mStoredInitialActorPosition = false; if (esm.isNextSub("POS_")) { diff --git a/components/esm/aisequence.hpp b/components/esm/aisequence.hpp index b1ee9b1f1..52446d38f 100644 --- a/components/esm/aisequence.hpp +++ b/components/esm/aisequence.hpp @@ -66,7 +66,7 @@ namespace ESM struct AiWander : AiPackage { AiWanderData mData; - AiWanderDuration mDurationData; // was ESM::TimeStamp mStartTime; + AiWanderDuration mDurationData; // was ESM::TimeStamp mStartTime bool mStoredInitialActorPosition; ESM::Vector3 mInitialActorPosition;