forked from mirror/openmw-tes3mp
Store original actor position in AiWander package (Fixes #2200)
This commit is contained in:
parent
5d7eb11596
commit
01652bbcc5
7 changed files with 81 additions and 45 deletions
|
@ -70,6 +70,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<unsigned char>& idle, bool repeat):
|
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)
|
mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat)
|
||||||
|
, mStoredInitialActorPosition(false)
|
||||||
{
|
{
|
||||||
mIdle.resize(8, 0);
|
mIdle.resize(8, 0);
|
||||||
init();
|
init();
|
||||||
|
@ -675,6 +676,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell)
|
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
|
// infrequently used, therefore no benefit in caching it as a member
|
||||||
const ESM::Pathgrid *
|
const ESM::Pathgrid *
|
||||||
pathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell);
|
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;
|
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
|
// 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[0] = npcPos[0] - cellXOffset;
|
||||||
npcPos[1] = npcPos[1] - cellYOffset;
|
npcPos[1] = npcPos[1] - cellYOffset;
|
||||||
|
|
||||||
|
@ -750,6 +752,9 @@ namespace MWMechanics
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
wander->mData.mIdle[i] = mIdle[i];
|
wander->mData.mIdle[i] = mIdle[i];
|
||||||
wander->mData.mShouldRepeat = mRepeat;
|
wander->mData.mShouldRepeat = mRepeat;
|
||||||
|
wander->mStoredInitialActorPosition = mStoredInitialActorPosition;
|
||||||
|
if (mStoredInitialActorPosition)
|
||||||
|
wander->mInitialActorPosition = mInitialActorPosition;
|
||||||
|
|
||||||
ESM::AiSequence::AiPackageContainer package;
|
ESM::AiSequence::AiPackageContainer package;
|
||||||
package.mType = ESM::AiSequence::Ai_Wander;
|
package.mType = ESM::AiSequence::Ai_Wander;
|
||||||
|
@ -763,6 +768,7 @@ namespace MWMechanics
|
||||||
, mStartTime(MWWorld::TimeStamp(wander->mStartTime))
|
, mStartTime(MWWorld::TimeStamp(wander->mStartTime))
|
||||||
, mTimeOfDay(wander->mData.mTimeOfDay)
|
, mTimeOfDay(wander->mData.mTimeOfDay)
|
||||||
, mRepeat(wander->mData.mShouldRepeat)
|
, mRepeat(wander->mData.mShouldRepeat)
|
||||||
|
, mStoredInitialActorPosition(wander->mStoredInitialActorPosition)
|
||||||
{
|
{
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
mIdle.push_back(wander->mData.mIdle[i]);
|
mIdle.push_back(wander->mData.mIdle[i]);
|
||||||
|
|
|
@ -84,7 +84,8 @@ namespace MWMechanics
|
||||||
// if we had the actor in the AiWander constructor...
|
// if we had the actor in the AiWander constructor...
|
||||||
Ogre::Vector3 mReturnPosition;
|
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
|
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
|
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
|
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
|
||||||
aisequence magiceffects
|
aisequence magiceffects util
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (esmterrain
|
add_component_dir (esmterrain
|
||||||
|
|
|
@ -16,12 +16,20 @@ namespace AiSequence
|
||||||
{
|
{
|
||||||
esm.getHNT (mData, "DATA");
|
esm.getHNT (mData, "DATA");
|
||||||
esm.getHNT(mStartTime, "STAR");
|
esm.getHNT(mStartTime, "STAR");
|
||||||
|
mStoredInitialActorPosition = false;
|
||||||
|
if (esm.isNextSub("POS_"))
|
||||||
|
{
|
||||||
|
mStoredInitialActorPosition = true;
|
||||||
|
esm.getHT(mInitialActorPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiWander::save(ESMWriter &esm) const
|
void AiWander::save(ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
esm.writeHNT ("DATA", mData);
|
esm.writeHNT ("DATA", mData);
|
||||||
esm.writeHNT ("STAR", mStartTime);
|
esm.writeHNT ("STAR", mStartTime);
|
||||||
|
if (mStoredInitialActorPosition)
|
||||||
|
esm.writeHNT ("POS_", mInitialActorPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiTravel::load(ESMReader &esm)
|
void AiTravel::load(ESMReader &esm)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "defs.hpp"
|
#include "defs.hpp"
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
@ -61,6 +63,9 @@ namespace ESM
|
||||||
AiWanderData mData;
|
AiWanderData mData;
|
||||||
ESM::TimeStamp mStartTime;
|
ESM::TimeStamp mStartTime;
|
||||||
|
|
||||||
|
bool mStoredInitialActorPosition;
|
||||||
|
ESM::Vector3 mInitialActorPosition;
|
||||||
|
|
||||||
/// \todo add more AiWander state
|
/// \todo add more AiWander state
|
||||||
|
|
||||||
void load(ESMReader &esm);
|
void load(ESMReader &esm);
|
||||||
|
|
|
@ -8,48 +8,13 @@
|
||||||
|
|
||||||
#include "effectlist.hpp"
|
#include "effectlist.hpp"
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
// format 0, savegames only
|
// 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
|
struct BaseProjectileState
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
51
components/esm/util.hpp
Normal file
51
components/esm/util.hpp
Normal file
|
@ -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…
Reference in a new issue