AiWander: return to initial position only after combat

pull/456/head
Andrei Kortunov 7 years ago
parent 3c2c0960d1
commit 9d27eb197f

@ -201,6 +201,17 @@ namespace MWMechanics
stopWalking(actor, storage);
currentCell = actor.getCell();
storage.mPopulateAvailableNodes = true;
}
// Here we should reset an initial position, if a current cell was REALLY changed
// We do not store AiStorage in a savegame, so cellChange is not help us in this case
// TODO: find a more simple and fast solution, or do not store the mInitialActorPosition at all
if (mStoredInitialActorPosition)
{
int cx,cy;
MWBase::Environment::get().getWorld()->positionToIndex(mInitialActorPosition.x(),mInitialActorPosition.y(),cx,cy);
MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
if (cell != currentCell)
mStoredInitialActorPosition = false;
}
@ -298,13 +309,6 @@ namespace MWMechanics
if(mDistance && cellChange)
mDistance = 0;
// For stationary NPCs, move back to the starting location if another AiPackage moved us elsewhere
if (mDistance == 0 && !cellChange
&& (pos.asVec3() - mInitialActorPosition).length2() > (DESTINATION_TOLERANCE * DESTINATION_TOLERANCE))
{
returnToStartLocation(actor, storage, pos);
}
// Allow interrupting a walking actor to trigger a greeting
WanderState& wanderState = storage.mState;
if ((wanderState == Wander_IdleNow) || (wanderState == Wander_Walking))
@ -350,27 +354,6 @@ namespace MWMechanics
return false;
}
void AiWander::returnToStartLocation(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos)
{
if (!mPathFinder.isPathConstructed())
{
mDestination = mInitialActorPosition;
ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(mDestination));
// actor position is already in world coordinates
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos));
// don't take shortcuts for wandering
mPathFinder.buildSyncedPath(start, dest, actor.getCell(), getPathGridGraph(actor.getCell()));
if (mPathFinder.isPathConstructed())
{
storage.setState(Wander_Walking);
mHasDestination = true;
}
}
}
/*
* Commands actor to walk to a random location near original spawn location.
*/
@ -1041,4 +1024,3 @@ namespace MWMechanics
init();
}
}

@ -85,7 +85,6 @@ namespace MWMechanics
bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage,
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos, float duration);
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void returnToStartLocation(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos);
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);
bool destinationThroughGround(const osg::Vec3f& startPoint, const osg::Vec3f& destination);

@ -22,6 +22,7 @@
#include "aicombat.hpp"
#include "aipursue.hpp"
#include "aitravel.hpp"
#include "spellcasting.hpp"
#include "autocalcspell.hpp"
#include "npcstats.hpp"
@ -1598,9 +1599,22 @@ namespace MWMechanics
void MechanicsManager::startCombat(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target)
{
if (ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(target))
MWMechanics::AiSequence& aiSequence = ptr.getClass().getCreatureStats(ptr).getAiSequence();
if (aiSequence.isInCombat(target))
return;
ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(MWMechanics::AiCombat(target), ptr);
// we should return a wandering actor back after combat
// TODO: only for stationary wander?
if (!aiSequence.isInCombat() && aiSequence.getLastRunTypeId() == MWMechanics::AiPackage::TypeIdWander)
{
osg::Vec3f pos = ptr.getRefData().getPosition().asVec3();
MWMechanics::AiTravel travelPackage(pos.x(), pos.y(), pos.z());
aiSequence.stack(travelPackage, ptr);
}
aiSequence.stack(MWMechanics::AiCombat(target), ptr);
if (target == getPlayer())
{
// if guard starts combat with player, guards pursuing player should do the same

Loading…
Cancel
Save