Store original actor position in AiWander package (Fixes #2200)

moveref
scrawl 10 years ago
parent 5d7eb11596
commit 01652bbcc5

@ -70,6 +70,7 @@ namespace MWMechanics
AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<unsigned char>& idle, bool repeat):
mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat)
, mStoredInitialActorPosition(false)
{
mIdle.resize(8, 0);
init();
@ -675,6 +676,12 @@ namespace MWMechanics
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell)
{
if (!mStoredInitialActorPosition)
{
mInitialActorPosition = Ogre::Vector3(actor.getRefData().getPosition().pos);
mStoredInitialActorPosition = true;
}
// infrequently used, therefore no benefit in caching it as a member
const ESM::Pathgrid *
pathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell);
@ -699,13 +706,8 @@ namespace MWMechanics
cellYOffset = cell->mData.mY * ESM::Land::REAL_SIZE;
}
// FIXME: There might be a bug here. The allowed node points are
// based on the actor's current position rather than the actor's
// spawn point. As a result the allowed nodes for wander can change
// between saves, for example.
//
// convert npcPos to local (i.e. cell) co-ordinates
Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos);
Ogre::Vector3 npcPos(mInitialActorPosition);
npcPos[0] = npcPos[0] - cellXOffset;
npcPos[1] = npcPos[1] - cellYOffset;
@ -750,6 +752,9 @@ namespace MWMechanics
for (int i=0; i<8; ++i)
wander->mData.mIdle[i] = mIdle[i];
wander->mData.mShouldRepeat = mRepeat;
wander->mStoredInitialActorPosition = mStoredInitialActorPosition;
if (mStoredInitialActorPosition)
wander->mInitialActorPosition = mInitialActorPosition;
ESM::AiSequence::AiPackageContainer package;
package.mType = ESM::AiSequence::Ai_Wander;
@ -763,6 +768,7 @@ namespace MWMechanics
, mStartTime(MWWorld::TimeStamp(wander->mStartTime))
, mTimeOfDay(wander->mData.mTimeOfDay)
, mRepeat(wander->mData.mShouldRepeat)
, mStoredInitialActorPosition(wander->mStoredInitialActorPosition)
{
for (int i=0; i<8; ++i)
mIdle.push_back(wander->mData.mIdle[i]);

@ -84,7 +84,8 @@ namespace MWMechanics
// if we had the actor in the AiWander constructor...
Ogre::Vector3 mReturnPosition;
Ogre::Vector3 mInitialActorPosition;
bool mStoredInitialActorPosition;

@ -46,7 +46,7 @@ add_component_dir (esm
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
aisequence magiceffects
aisequence magiceffects util
)
add_component_dir (esmterrain

@ -16,12 +16,20 @@ namespace AiSequence
{
esm.getHNT (mData, "DATA");
esm.getHNT(mStartTime, "STAR");
mStoredInitialActorPosition = false;
if (esm.isNextSub("POS_"))
{
mStoredInitialActorPosition = true;
esm.getHT(mInitialActorPosition);
}
}
void AiWander::save(ESMWriter &esm) const
{
esm.writeHNT ("DATA", mData);
esm.writeHNT ("STAR", mStartTime);
if (mStoredInitialActorPosition)
esm.writeHNT ("POS_", mInitialActorPosition);
}
void AiTravel::load(ESMReader &esm)

@ -6,6 +6,8 @@
#include "defs.hpp"
#include "util.hpp"
namespace ESM
{
class ESMReader;
@ -61,6 +63,9 @@ namespace ESM
AiWanderData mData;
ESM::TimeStamp mStartTime;
bool mStoredInitialActorPosition;
ESM::Vector3 mInitialActorPosition;
/// \todo add more AiWander state
void load(ESMReader &esm);

@ -8,48 +8,13 @@
#include "effectlist.hpp"
#include "util.hpp"
namespace ESM
{
// format 0, savegames only
struct Quaternion
{
float mValues[4];
Quaternion() {}
Quaternion (Ogre::Quaternion q)
{
mValues[0] = q.w;
mValues[1] = q.x;
mValues[2] = q.y;
mValues[3] = q.z;
}
operator Ogre::Quaternion () const
{
return Ogre::Quaternion(mValues[0], mValues[1], mValues[2], mValues[3]);
}
};
struct Vector3
{
float mValues[3];
Vector3() {}
Vector3 (Ogre::Vector3 v)
{
mValues[0] = v.x;
mValues[1] = v.y;
mValues[2] = v.z;
}
operator Ogre::Vector3 () const
{
return Ogre::Vector3(&mValues[0]);
}
};
struct BaseProjectileState
{
std::string mId;

@ -0,0 +1,51 @@
#ifndef OPENMW_ESM_UTIL_H
#define OPENMW_ESM_UTIL_H
#include <OgreVector3.h>
#include <OgreQuaternion.h>
namespace ESM
{
// format 0, savegames only
struct Quaternion
{
float mValues[4];
Quaternion() {}
Quaternion (Ogre::Quaternion q)
{
mValues[0] = q.w;
mValues[1] = q.x;
mValues[2] = q.y;
mValues[3] = q.z;
}
operator Ogre::Quaternion () const
{
return Ogre::Quaternion(mValues[0], mValues[1], mValues[2], mValues[3]);
}
};
struct Vector3
{
float mValues[3];
Vector3() {}
Vector3 (Ogre::Vector3 v)
{
mValues[0] = v.x;
mValues[1] = v.y;
mValues[2] = v.z;
}
operator Ogre::Vector3 () const
{
return Ogre::Vector3(&mValues[0]);
}
};
}
#endif
Loading…
Cancel
Save