Merge remote-tracking branch 'scrawl/return'

actorid
Marc Zinnschlag 11 years ago
commit 4eeed4e2c7

@ -206,7 +206,7 @@ namespace MWMechanics
if (LOS) if (LOS)
{ {
creatureStats.getAiSequence().stack(AiCombat(MWBase::Environment::get().getWorld()->getPlayerPtr())); creatureStats.getAiSequence().stack(AiCombat(MWBase::Environment::get().getWorld()->getPlayerPtr()), ptr);
creatureStats.setHostile(true); creatureStats.setHostile(true);
} }
} }
@ -537,7 +537,7 @@ namespace MWMechanics
// TODO: Add AI to follow player and fight for him // TODO: Add AI to follow player and fight for him
AiFollow package(ptr.getRefData().getHandle()); AiFollow package(ptr.getRefData().getHandle());
MWWorld::Class::get (ref.getPtr()).getCreatureStats (ref.getPtr()).getAiSequence().stack(package); MWWorld::Class::get (ref.getPtr()).getCreatureStats (ref.getPtr()).getAiSequence().stack(package, ptr);
// TODO: VFX_SummonStart, VFX_SummonEnd // TODO: VFX_SummonStart, VFX_SummonEnd
creatureStats.mSummonedCreatures.insert(std::make_pair(it->first, creatureStats.mSummonedCreatures.insert(std::make_pair(it->first,
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos).getRefData().getHandle())); MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos).getRefData().getHandle()));
@ -732,7 +732,7 @@ namespace MWMechanics
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getWorld()->getLOS(ptr, player)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
{ {
creatureStats.getAiSequence().stack(AiCombat(player)); creatureStats.getAiSequence().stack(AiCombat(player), ptr);
creatureStats.setHostile(true); creatureStats.setHostile(true);
npcStats.setCrimeId( MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() ); npcStats.setCrimeId( MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() );
} }
@ -761,9 +761,9 @@ namespace MWMechanics
else if (!creatureStats.isHostile()) else if (!creatureStats.isHostile())
{ {
if (ptr.getClass().isClass(ptr, "Guard")) if (ptr.getClass().isClass(ptr, "Guard"))
creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player))); creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr);
else else
creatureStats.getAiSequence().stack(AiCombat(player)); creatureStats.getAiSequence().stack(AiCombat(player), ptr);
creatureStats.setHostile(true); creatureStats.setHostile(true);
} }
} }
@ -771,7 +771,7 @@ namespace MWMechanics
// if I didn't report a crime was I attacked? // if I didn't report a crime was I attacked?
else if (creatureStats.getAttacked() && !creatureStats.isHostile()) else if (creatureStats.getAttacked() && !creatureStats.isHostile())
{ {
creatureStats.getAiSequence().stack(AiCombat(player)); creatureStats.getAiSequence().stack(AiCombat(player), ptr);
creatureStats.setHostile(true); creatureStats.setHostile(true);
} }
} }

@ -116,8 +116,18 @@ void MWMechanics::AiSequence::clear()
mPackages.clear(); mPackages.clear();
} }
void MWMechanics::AiSequence::stack (const AiPackage& package) void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
{ {
if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPersue)
{
// Notify AiWander of our current position so we can return to it after combat finished
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
{
if ((*iter)->getTypeId() == AiPackage::TypeIdWander)
static_cast<AiWander*>(*iter)->setReturnPosition(Ogre::Vector3(actor.getRefData().getPosition().pos));
}
}
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); ++it) for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
{ {
if(mPackages.front()->getPriority() <= package.getPriority()) if(mPackages.front()->getPriority() <= package.getPriority())

@ -62,7 +62,7 @@ namespace MWMechanics
void clear(); void clear();
///< Remove all packages. ///< Remove all packages.
void stack (const AiPackage& package); void stack (const AiPackage& package, const MWWorld::Ptr& actor);
///< Add \a package to the front of the sequence (suspends current package) ///< Add \a package to the front of the sequence (suspends current package)
void queue (const AiPackage& package); void queue (const AiPackage& package);

@ -38,6 +38,8 @@ namespace MWMechanics
, mRotate(false) , mRotate(false)
, mTargetAngle(0) , mTargetAngle(0)
, mSaidGreeting(false) , mSaidGreeting(false)
, mHasReturnPosition(false)
, mReturnPosition(0,0,0)
{ {
for(unsigned short counter = 0; counter < mIdle.size(); counter++) for(unsigned short counter = 0; counter < mIdle.size(); counter++)
{ {
@ -331,6 +333,40 @@ namespace MWMechanics
if(mDistance && cellChange) if(mDistance && cellChange)
mDistance = 0; mDistance = 0;
// For stationary NPCs, move back to the starting location if another AiPackage moved us elsewhere
if (cellChange)
mHasReturnPosition = false;
if (mDistance == 0 && mHasReturnPosition && Ogre::Vector3(pos.pos).squaredDistance(mReturnPosition) > 20*20)
{
mChooseAction = false;
mIdleNow = false;
if (!mPathFinder.isPathConstructed())
{
Ogre::Vector3 destNodePos = mReturnPosition;
ESM::Pathgrid::Point dest;
dest.mX = destNodePos[0];
dest.mY = destNodePos[1];
dest.mZ = destNodePos[2];
// actor position is already in world co-ordinates
ESM::Pathgrid::Point start;
start.mX = pos.pos[0];
start.mY = pos.pos[1];
start.mZ = pos.pos[2];
// don't take shortcuts for wandering
mPathFinder.buildPath(start, dest, actor.getCell(), false);
if(mPathFinder.isPathConstructed())
{
mMoveNow = false;
mWalking = true;
}
}
}
if(mChooseAction) if(mChooseAction)
{ {
mPlayedIdle = 0; mPlayedIdle = 0;
@ -365,7 +401,7 @@ namespace MWMechanics
} }
// Allow interrupting a walking actor to trigger a greeting // Allow interrupting a walking actor to trigger a greeting
if(mIdleNow || (mWalking && !mObstacleCheck.isNormalState())) if(mIdleNow || (mWalking && !mObstacleCheck.isNormalState() && mDistance))
{ {
// Play a random voice greeting if the player gets too close // Play a random voice greeting if the player gets too close
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified(); int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
@ -496,6 +532,7 @@ namespace MWMechanics
mMoveNow = false; mMoveNow = false;
mWalking = false; mWalking = false;
mChooseAction = true; mChooseAction = true;
mHasReturnPosition = false;
} }
return false; // AiWander package not yet completed return false; // AiWander package not yet completed
@ -580,6 +617,15 @@ namespace MWMechanics
return false; return false;
} }
void AiWander::setReturnPosition(const Ogre::Vector3& position)
{
if (!mHasReturnPosition)
{
mHasReturnPosition = true;
mReturnPosition = position;
}
}
void AiWander::getRandomIdle() void AiWander::getRandomIdle()
{ {
unsigned short idleRoll = 0; unsigned short idleRoll = 0;

@ -2,8 +2,11 @@
#define GAME_MWMECHANICS_AIWANDER_H #define GAME_MWMECHANICS_AIWANDER_H
#include "aipackage.hpp" #include "aipackage.hpp"
#include <vector> #include <vector>
#include <OgreVector3.h>
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include "obstacle.hpp" #include "obstacle.hpp"
@ -22,6 +25,10 @@ namespace MWMechanics
virtual int getTypeId() const; virtual int getTypeId() const;
///< 0: Wander ///< 0: Wander
void setReturnPosition (const Ogre::Vector3& position);
///< Set the position to return to for a stationary (non-wandering) actor, in case
/// another AI package moved the actor elsewhere
private: private:
void stopWalking(const MWWorld::Ptr& actor); void stopWalking(const MWWorld::Ptr& actor);
void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
@ -39,6 +46,10 @@ namespace MWMechanics
float mGreetDistanceReset; float mGreetDistanceReset;
float mChance; float mChance;
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
// if we had the actor in the AiWander constructor...
Ogre::Vector3 mReturnPosition;
// Cached current cell location // Cached current cell location
int mCellX; int mCellX;
int mCellY; int mCellY;

@ -48,7 +48,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiActivate activatePackage(objectID); MWMechanics::AiActivate activatePackage(objectID);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(activatePackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(activatePackage, ptr);
std::cout << "AiActivate" << std::endl; std::cout << "AiActivate" << std::endl;
} }
}; };
@ -75,7 +75,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiTravel travelPackage(x, y, z); MWMechanics::AiTravel travelPackage(x, y, z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(travelPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(travelPackage, ptr);
std::cout << "AiTravel: " << x << ", " << y << ", " << z << std::endl; std::cout << "AiTravel: " << x << ", " << y << ", " << z << std::endl;
} }
@ -109,7 +109,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiEscort escortPackage(actorID, duration, x, y, z); MWMechanics::AiEscort escortPackage(actorID, duration, x, y, z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr);
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
<< std::endl; << std::endl;
@ -147,7 +147,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiEscort escortPackage(actorID, cellID, duration, x, y, z); MWMechanics::AiEscort escortPackage(actorID, cellID, duration, x, y, z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr);
std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration
<< std::endl; << std::endl;
@ -211,7 +211,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiWander wanderPackage(range, duration, time, idleList, repeat); MWMechanics::AiWander wanderPackage(range, duration, time, idleList, repeat);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(wanderPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(wanderPackage, ptr);
} }
}; };
@ -299,7 +299,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiFollow followPackage(actorID, duration, x, y ,z); MWMechanics::AiFollow followPackage(actorID, duration, x, y ,z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
<< std::endl; << std::endl;
@ -337,7 +337,7 @@ namespace MWScript
for (unsigned int i=0; i<arg0; ++i) runtime.pop(); for (unsigned int i=0; i<arg0; ++i) runtime.pop();
MWMechanics::AiFollow followPackage(actorID, cellID, duration, x, y ,z); MWMechanics::AiFollow followPackage(actorID, cellID, duration, x, y ,z);
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage); MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage, ptr);
std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration
<< std::endl; << std::endl;
} }
@ -440,7 +440,7 @@ namespace MWScript
creatureStats.setHostile(true); creatureStats.setHostile(true);
creatureStats.getAiSequence().stack( creatureStats.getAiSequence().stack(
MWMechanics::AiCombat(MWBase::Environment::get().getWorld()->getPtr(targetID, true) )); MWMechanics::AiCombat(MWBase::Environment::get().getWorld()->getPtr(targetID, true) ), actor);
} }
}; };

@ -253,8 +253,6 @@ void MWState::StateManager::quickSave (std::string name)
slot = &*it; slot = &*it;
} }
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage4}");
saveGame(name, slot); saveGame(name, slot);
} }
@ -368,10 +366,7 @@ void MWState::StateManager::quickLoad()
{ {
if (Character* mCurrentCharacter = getCurrentCharacter (false)) if (Character* mCurrentCharacter = getCurrentCharacter (false))
if (const MWState::Slot* slot = &*mCurrentCharacter->begin()) //Get newest save if (const MWState::Slot* slot = &*mCurrentCharacter->begin()) //Get newest save
{
//MWBase::Environment::get().getWindowManager()->messageBox("#{sLoadingMessage14}"); //it overlaps
loadGame (mCurrentCharacter, slot); loadGame (mCurrentCharacter, slot);
}
} }
void MWState::StateManager::deleteGame(const MWState::Character *character, const MWState::Slot *slot) void MWState::StateManager::deleteGame(const MWState::Character *character, const MWState::Slot *slot)

Loading…
Cancel
Save