mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 09:06:43 +00:00
commit
b168544445
4 changed files with 28 additions and 37 deletions
|
@ -89,6 +89,11 @@ namespace MWMechanics
|
||||||
const auto maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z()));
|
const auto maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z()));
|
||||||
return world->isAreaOccupiedByOtherActor(destination, 2 * maxHalfExtent, actor);
|
return world->isAreaOccupiedByOtherActor(destination, 2 * maxHalfExtent, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopMovement(const MWWorld::Ptr& actor)
|
||||||
|
{
|
||||||
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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):
|
||||||
|
@ -165,7 +170,7 @@ namespace MWMechanics
|
||||||
* actors will enter combat (i.e. no longer wandering) and different pathfinding
|
* actors will enter combat (i.e. no longer wandering) and different pathfinding
|
||||||
* will kick in.
|
* will kick in.
|
||||||
*/
|
*/
|
||||||
bool AiWander::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
bool AiWander::execute (const MWWorld::Ptr& actor, CharacterController& /*characterController*/, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
||||||
if (cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
if (cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
||||||
|
@ -206,7 +211,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (storage.mState == AiWanderStorage::Wander_Walking)
|
if (storage.mState == AiWanderStorage::Wander_Walking)
|
||||||
{
|
{
|
||||||
stopWalking(actor, storage, false);
|
stopMovement(actor);
|
||||||
mObstacleCheck.clear();
|
mObstacleCheck.clear();
|
||||||
storage.setState(AiWanderStorage::Wander_IdleNow);
|
storage.setState(AiWanderStorage::Wander_IdleNow);
|
||||||
}
|
}
|
||||||
|
@ -230,8 +235,9 @@ namespace MWMechanics
|
||||||
if (mDistance <= 0)
|
if (mDistance <= 0)
|
||||||
storage.mCanWanderAlongPathGrid = false;
|
storage.mCanWanderAlongPathGrid = false;
|
||||||
|
|
||||||
if (isPackageCompleted(actor, storage))
|
if (isPackageCompleted())
|
||||||
{
|
{
|
||||||
|
stopWalking(actor);
|
||||||
// Reset package so it can be used again
|
// Reset package so it can be used again
|
||||||
mRemainingDuration=mDuration;
|
mRemainingDuration=mDuration;
|
||||||
init();
|
init();
|
||||||
|
@ -315,19 +321,10 @@ namespace MWMechanics
|
||||||
return actor.getRefData().getPosition().asVec3();
|
return actor.getRefData().getPosition().asVec3();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AiWander::isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage)
|
bool AiWander::isPackageCompleted() const
|
||||||
{
|
{
|
||||||
if (mDuration)
|
// End package if duration is complete
|
||||||
{
|
return mDuration && mRemainingDuration <= 0;
|
||||||
// End package if duration is complete
|
|
||||||
if (mRemainingDuration <= 0)
|
|
||||||
{
|
|
||||||
stopWalking(actor, storage);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if get here, not yet completed
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -395,7 +392,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiWander::completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage) {
|
void AiWander::completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage) {
|
||||||
stopWalking(actor, storage);
|
stopWalking(actor);
|
||||||
mObstacleCheck.clear();
|
mObstacleCheck.clear();
|
||||||
storage.setState(AiWanderStorage::Wander_IdleNow);
|
storage.setState(AiWanderStorage::Wander_IdleNow);
|
||||||
}
|
}
|
||||||
|
@ -460,13 +457,13 @@ namespace MWMechanics
|
||||||
// Is there no destination or are we there yet?
|
// Is there no destination or are we there yet?
|
||||||
if ((!mPathFinder.isPathConstructed()) || pathTo(actor, osg::Vec3f(mPathFinder.getPath().back()), duration, DESTINATION_TOLERANCE))
|
if ((!mPathFinder.isPathConstructed()) || pathTo(actor, osg::Vec3f(mPathFinder.getPath().back()), duration, DESTINATION_TOLERANCE))
|
||||||
{
|
{
|
||||||
stopWalking(actor, storage);
|
stopWalking(actor);
|
||||||
storage.setState(AiWanderStorage::Wander_ChooseAction);
|
storage.setState(AiWanderStorage::Wander_ChooseAction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// have not yet reached the destination
|
// have not yet reached the destination
|
||||||
evadeObstacles(actor, duration, storage);
|
evadeObstacles(actor, storage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,15 +494,12 @@ namespace MWMechanics
|
||||||
storage.setState(AiWanderStorage::Wander_IdleNow);
|
storage.setState(AiWanderStorage::Wander_IdleNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiWander::evadeObstacles(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage)
|
void AiWander::evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage)
|
||||||
{
|
{
|
||||||
if (mUsePathgrid)
|
if (mUsePathgrid)
|
||||||
{
|
{
|
||||||
const auto halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor);
|
const auto halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor);
|
||||||
const float actorTolerance = 2 * actor.getClass().getSpeed(actor) * duration
|
mPathFinder.buildPathByNavMeshToNextPoint(actor, halfExtents, getNavigatorFlags(actor));
|
||||||
+ 1.2 * std::max(halfExtents.x(), halfExtents.y());
|
|
||||||
const float pointTolerance = std::max(MIN_TOLERANCE, actorTolerance);
|
|
||||||
mPathFinder.buildPathByNavMeshToNextPoint(actor, halfExtents, getNavigatorFlags(actor), pointTolerance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mObstacleCheck.isEvading())
|
if (mObstacleCheck.isEvading())
|
||||||
|
@ -518,7 +512,7 @@ namespace MWMechanics
|
||||||
storage.mTrimCurrentNode = true;
|
storage.mTrimCurrentNode = true;
|
||||||
trimAllowedNodes(storage.mAllowedNodes, mPathFinder);
|
trimAllowedNodes(storage.mAllowedNodes, mPathFinder);
|
||||||
mObstacleCheck.clear();
|
mObstacleCheck.clear();
|
||||||
stopWalking(actor, storage);
|
stopWalking(actor);
|
||||||
storage.setState(AiWanderStorage::Wander_MoveNow);
|
storage.setState(AiWanderStorage::Wander_MoveNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +523,7 @@ namespace MWMechanics
|
||||||
if (storage.mStuckCount >= getCountBeforeReset(actor)) // something has gone wrong, reset
|
if (storage.mStuckCount >= getCountBeforeReset(actor)) // something has gone wrong, reset
|
||||||
{
|
{
|
||||||
mObstacleCheck.clear();
|
mObstacleCheck.clear();
|
||||||
stopWalking(actor, storage);
|
stopWalking(actor);
|
||||||
storage.setState(AiWanderStorage::Wander_ChooseAction);
|
storage.setState(AiWanderStorage::Wander_ChooseAction);
|
||||||
storage.mStuckCount = 0;
|
storage.mStuckCount = 0;
|
||||||
}
|
}
|
||||||
|
@ -609,14 +603,11 @@ namespace MWMechanics
|
||||||
return TypeIdWander;
|
return TypeIdWander;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiWander::stopWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage, bool clearPath)
|
void AiWander::stopWalking(const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
if (clearPath)
|
mPathFinder.clearPath();
|
||||||
{
|
mHasDestination = false;
|
||||||
mPathFinder.clearPath();
|
stopMovement(actor);
|
||||||
mHasDestination = false;
|
|
||||||
}
|
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
|
bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace MWMechanics
|
||||||
private:
|
private:
|
||||||
// NOTE: mDistance and mDuration must be set already
|
// NOTE: mDistance and mDuration must be set already
|
||||||
void init();
|
void init();
|
||||||
void stopWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage, bool clearPath = true);
|
void stopWalking(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
/// Have the given actor play an idle animation
|
/// Have the given actor play an idle animation
|
||||||
/// @return Success or error
|
/// @return Success or error
|
||||||
|
@ -126,14 +126,14 @@ namespace MWMechanics
|
||||||
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
||||||
short unsigned getRandomIdle();
|
short unsigned getRandomIdle();
|
||||||
void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos);
|
void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos);
|
||||||
void evadeObstacles(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
void evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
||||||
void turnActorToFacePlayer(const osg::Vec3f& actorPosition, const osg::Vec3f& playerPosition, AiWanderStorage& storage);
|
void turnActorToFacePlayer(const osg::Vec3f& actorPosition, const osg::Vec3f& playerPosition, AiWanderStorage& storage);
|
||||||
void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
||||||
void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
||||||
void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
|
||||||
void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
||||||
bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos);
|
bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos);
|
||||||
bool isPackageCompleted(const MWWorld::Ptr& actor, AiWanderStorage& storage);
|
inline bool isPackageCompleted() const;
|
||||||
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
|
void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance);
|
||||||
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);
|
bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination);
|
||||||
void completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage);
|
void completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage);
|
||||||
|
|
|
@ -361,7 +361,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
||||||
const DetourNavigator::Flags flags, const float pointTolerance)
|
const DetourNavigator::Flags flags)
|
||||||
{
|
{
|
||||||
if (mPath.empty())
|
if (mPath.empty())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace MWMechanics
|
||||||
const DetourNavigator::Flags flags);
|
const DetourNavigator::Flags flags);
|
||||||
|
|
||||||
void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
||||||
const DetourNavigator::Flags flags, const float pointTolerance);
|
const DetourNavigator::Flags flags);
|
||||||
|
|
||||||
/// Remove front point if exist and within tolerance
|
/// Remove front point if exist and within tolerance
|
||||||
void update(const osg::Vec3f& position, const float pointTolerance, const float destinationTolerance);
|
void update(const osg::Vec3f& position, const float pointTolerance, const float destinationTolerance);
|
||||||
|
|
Loading…
Reference in a new issue