Merge pull request #962 from Allofich/AIPackageFixes

Duration fixes for Follow and Escort
coverity_scan^2
scrawl 9 years ago committed by GitHub
commit 372f2e2f18

@ -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<float>(duration))
: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration))
, mCellX(std::numeric_limits<int>::max())
, mCellY(std::numeric_limits<int>::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<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())
, mCellY(std::numeric_limits<int>::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<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
// 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--;
}
}

@ -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;

@ -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--;
}
}

@ -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;

@ -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))
{
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;

@ -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_"))
{

@ -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;

Loading…
Cancel
Save