forked from mirror/openmw-tes3mp
Add logic for NPC wandering without pathgrids
This commit is contained in:
parent
c02881a4f8
commit
92b352989a
2 changed files with 21 additions and 16 deletions
|
@ -232,6 +232,12 @@ namespace MWMechanics
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mStoredInitialActorPosition)
|
||||||
|
{
|
||||||
|
mInitialActorPosition = actor.getRefData().getPosition().asVec3();
|
||||||
|
mStoredInitialActorPosition = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialization to discover & store allowed node points for this actor.
|
// Initialization to discover & store allowed node points for this actor.
|
||||||
if (mPopulateAvailableNodes)
|
if (mPopulateAvailableNodes)
|
||||||
{
|
{
|
||||||
|
@ -239,11 +245,12 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actor becomes stationary - see above URL's for previous research
|
// Actor becomes stationary - see above URL's for previous research
|
||||||
// If not an NPC and no pathgrid is available, randomly idle or wander around near spawn point
|
// If a creature or an NPC with a wander distance and no pathgrid is available,
|
||||||
if(mAllowedNodes.empty() && !actor.getBase()->mClass->isNpc() && !storage.mIsWanderingManually) {
|
// randomly idle or wander around near spawn point
|
||||||
|
if(mAllowedNodes.empty() && (mDistance > 0 || !actor.getClass().isNpc()) && !storage.mIsWanderingManually) {
|
||||||
// Typically want to idle for a short time before the next wander
|
// Typically want to idle for a short time before the next wander
|
||||||
if (Misc::Rng::rollDice(100) >= 96) {
|
if (Misc::Rng::rollDice(100) >= 96) {
|
||||||
wanderNearSpawn(actor, storage);
|
wanderNearStart(actor, storage, mDistance, actor.getClass().isNpc());
|
||||||
}
|
}
|
||||||
} else if (mAllowedNodes.empty() && !storage.mIsWanderingManually) {
|
} else if (mAllowedNodes.empty() && !storage.mIsWanderingManually) {
|
||||||
mDistance = 0;
|
mDistance = 0;
|
||||||
|
@ -334,18 +341,22 @@ namespace MWMechanics
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commands actor to walk to a random location near original spawn location.
|
* Commands actor to walk to a random location near original spawn location.
|
||||||
|
*
|
||||||
|
* Creatures simply wander a certain distance from their starting location, while NPCs wander a scripted
|
||||||
|
* distance (mDistance) from the position where they started the wander package.
|
||||||
|
* http://www.uesp.net/wiki/Tes3Mod:AIWander
|
||||||
*/
|
*/
|
||||||
void AiWander::wanderNearSpawn(const MWWorld::Ptr& actor, AiWanderStorage& storage) {
|
void AiWander::wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance, bool isNpc) {
|
||||||
const ESM::Pathgrid::Point currentPosition = actor.getRefData().getPosition().pos;
|
const ESM::Pathgrid::Point currentPosition = actor.getRefData().getPosition().pos;
|
||||||
const ESM::Pathgrid::Point originalPosition = actor.getCellRef().getPosition().pos;
|
|
||||||
|
|
||||||
// Determine a random location within radius of original position
|
// Determine a random location within radius of original position
|
||||||
const float pi = 3.14159265359f;
|
const float pi = 3.14159265359f;
|
||||||
const float randomRadius = Misc::Rng::rollClosedProbability() * MINIMUM_WANDER_DISTANCE * 14.0f;
|
const float maxWanderDistance = isNpc ? wanderDistance : MINIMUM_WANDER_DISTANCE * 14.0f;
|
||||||
|
const float wanderRadius = Misc::Rng::rollClosedProbability() * maxWanderDistance;
|
||||||
const float randomDirection = Misc::Rng::rollClosedProbability() * 2.0f * pi;
|
const float randomDirection = Misc::Rng::rollClosedProbability() * 2.0f * pi;
|
||||||
const float destinationX = originalPosition.mX + randomRadius * std::cos(randomDirection);
|
const float destinationX = mInitialActorPosition.x() + wanderRadius * std::cos(randomDirection);
|
||||||
const float destinationY = originalPosition.mY + randomRadius * std::sin(randomDirection);
|
const float destinationY = mInitialActorPosition.y() + wanderRadius * std::sin(randomDirection);
|
||||||
ESM::Pathgrid::Point destinationPosition = ESM::Pathgrid::Point(destinationX, destinationY, originalPosition.mZ);
|
ESM::Pathgrid::Point destinationPosition = ESM::Pathgrid::Point(destinationX, destinationY, mInitialActorPosition.z());
|
||||||
|
|
||||||
storage.mPathFinder.buildSyncedPath(currentPosition, destinationPosition, actor.getCell(), true);
|
storage.mPathFinder.buildSyncedPath(currentPosition, destinationPosition, actor.getCell(), true);
|
||||||
storage.mPathFinder.addPointToPath(destinationPosition);
|
storage.mPathFinder.addPointToPath(destinationPosition);
|
||||||
|
@ -787,12 +798,6 @@ 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 = actor.getRefData().getPosition().asVec3();
|
|
||||||
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);
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace MWMechanics
|
||||||
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos);
|
const MWWorld::CellStore*& currentCell, bool cellChange, ESM::Position& pos);
|
||||||
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
||||||
void returnToStartLocation(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos);
|
void returnToStartLocation(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos);
|
||||||
void wanderNearSpawn(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance, bool isNpc);
|
||||||
void detectManualWanderingObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
void detectManualWanderingObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
||||||
|
|
||||||
int mDistance; // how far the actor can wander from the spawn point
|
int mDistance; // how far the actor can wander from the spawn point
|
||||||
|
|
Loading…
Reference in a new issue