mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 00:35:23 +00:00
Moved isActorNearInactiveCell() logic to own function.
Also, triggers when actor is near edge of cell, not when less than 1/2 way to edge.
This commit is contained in:
parent
e9c796166a
commit
573a14993a
@ -16,6 +16,7 @@
|
||||
|
||||
#include "steering.hpp"
|
||||
#include "actorutil.hpp"
|
||||
#include "coordinateconverter.hpp"
|
||||
|
||||
MWMechanics::AiPackage::~AiPackage() {}
|
||||
|
||||
@ -32,45 +33,24 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
||||
|
||||
/// Stops the actor when it gets too close to a unloaded cell
|
||||
const ESM::Cell *cell = actor.getCell()->getCell();
|
||||
//... At current time, this test is unnecessary. AI shuts down when actor is more than 7168
|
||||
//... units from player, and exterior cells are 8192 units long and wide.
|
||||
//... But AI processing distance may increase in the future.
|
||||
if (isActorNearInactiveCell(pos))
|
||||
{
|
||||
MWWorld::Ptr player = getPlayer();
|
||||
Movement &movement = actor.getClass().getMovementSettings(actor);
|
||||
|
||||
//Ensure pursuer doesn't leave loaded cells
|
||||
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
|
||||
{
|
||||
int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
{
|
||||
movement.mPosition[1] = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(cell->mData.mY != player.getCell()->getCell()->mData.mY)
|
||||
{
|
||||
int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
{
|
||||
movement.mPosition[1] = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Start position
|
||||
ESM::Pathgrid::Point start = pos.pos;
|
||||
|
||||
//***********************
|
||||
/// Checks if you can't get to the end position at all, adds end position to end of path
|
||||
/// Rebuilds path every quarter of a second, in case the target has moved
|
||||
//***********************
|
||||
if(mTimer > 0.25)
|
||||
{
|
||||
const ESM::Cell *cell = actor.getCell()->getCell();
|
||||
if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved
|
||||
mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
||||
mPathFinder.buildSyncedPath(pos.pos, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
||||
mPrevDest = dest;
|
||||
}
|
||||
|
||||
@ -133,3 +113,27 @@ bool MWMechanics::AiPackage::isTargetMagicallyHidden(const MWWorld::Ptr& target)
|
||||
return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0)
|
||||
|| (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75);
|
||||
}
|
||||
|
||||
bool MWMechanics::AiPackage::isActorNearInactiveCell(const ESM::Position& actorPos)
|
||||
{
|
||||
const ESM::Cell* playerCell(getPlayer().getCell()->getCell());
|
||||
if (playerCell->isExterior())
|
||||
{
|
||||
// get actor's distance from origin of center cell
|
||||
osg::Vec3f actorOffset(actorPos.asVec3());
|
||||
CoordinateConverter(playerCell).ToLocal(actorOffset);
|
||||
|
||||
// currently assumes 3 x 3 grid for exterior cells, with player at center cell.
|
||||
// ToDo: (Maybe) use "exterior cell load distance" setting to get count of actual active cells
|
||||
// While AI Process distance is 7168, AI shuts down actors before they reach edges of 3 x 3 grid.
|
||||
const float distanceFromEdge = 200.0;
|
||||
float minThreshold = (-1.0f * ESM::Land::REAL_SIZE) + distanceFromEdge;
|
||||
float maxThreshold = (2.0f * ESM::Land::REAL_SIZE) - distanceFromEdge;
|
||||
return (actorOffset[0] < minThreshold) || (maxThreshold < actorOffset[0])
|
||||
|| (actorOffset[1] < minThreshold) || (maxThreshold < actorOffset[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -88,6 +88,7 @@ namespace MWMechanics
|
||||
|
||||
private:
|
||||
void evadeObstacles(const MWWorld::Ptr& actor, float duration, ESM::Position& pos);
|
||||
bool isActorNearInactiveCell(const ESM::Position& actorPos);
|
||||
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user