1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 21:53:51 +00:00

AIWander Completed. Replicates vanilla as best possible, pathfinding needs fixing before this looks correct but once the pathfinding files are edited this will behave pretty much exactly as vanilla. Major credit to Hrnchamd for major research.

This commit is contained in:
Torben Carrington 2013-05-26 11:30:42 -07:00
parent 96daad7a22
commit fd96d47fe4
2 changed files with 20 additions and 16 deletions

View file

@ -1,5 +1,4 @@
#include "aiwander.hpp" #include "aiwander.hpp"
#include <iostream>
#include "movement.hpp" #include "movement.hpp"
@ -23,14 +22,11 @@ namespace
MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<int>& idle, bool repeat): MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<int>& idle, bool repeat):
mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat)
{ {
std::cout << "AIWander: " << mDistance << " " << mDuration << " " << mTimeOfDay << " ";
for(unsigned short counter = 0; counter < mIdle.size(); counter++) for(unsigned short counter = 0; counter < mIdle.size(); counter++)
{ {
std::cout << mIdle[counter] << " ";
if(mIdle[counter] >= 127 || mIdle[counter] < 0) if(mIdle[counter] >= 127 || mIdle[counter] < 0)
mIdle[counter] = 0; mIdle[counter] = 0;
} }
std::cout << mRepeat << std::endl;
if(mDistance < 0) if(mDistance < 0)
mDistance = 0; mDistance = 0;
@ -42,7 +38,7 @@ MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const
srand(time(NULL)); srand(time(NULL));
mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp();
mPlayedIdle = 0; mPlayedIdle = 0;
mChanceMultiplyer = mIdleChanceMultiplier =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fIdleChanceMultiplier")->getFloat(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fIdleChanceMultiplier")->getFloat();
mStoredAvailableNodes = false; mStoredAvailableNodes = false;
@ -98,7 +94,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
if(mDistance && !mPathgrid->mPoints.empty()) if(mDistance && !mPathgrid->mPoints.empty())
{ {
// TODO: Limit selecting range in the Z axis.
mXCell = 0; mXCell = 0;
mYCell = 0; mYCell = 0;
if(actor.getCell()->mCell->isExterior()) if(actor.getCell()->mCell->isExterior())
@ -173,8 +168,8 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
for(unsigned int counter = 1; counter < mIdle.size(); counter++) for(unsigned int counter = 1; counter < mIdle.size(); counter++)
{ {
unsigned short idleChance = mChanceMultiplyer * mIdle[counter]; unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter];
unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mChanceMultiplyer)); unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier));
if(randSelect < idleChance && randSelect > idleRoll) if(randSelect < idleChance && randSelect > idleRoll)
{ {
mPlayedIdle = counter; mPlayedIdle = counter;
@ -241,9 +236,16 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]);
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
}
if(mWalking && mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be
// at the same path node at the same time and both will complete instead of endlessly walking into eachother:
Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ);
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
actorPos[0] = actorPos[0] - mXCell;
actorPos[1] = actorPos[1] - mYCell;
float distance = actorPos.squaredDistance(destNodePos);
if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
{ {
stopWalking(actor, mPathFinder); stopWalking(actor, mPathFinder);
mMoveNow = false; mMoveNow = false;
@ -251,6 +253,8 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
mChooseAction = true; mChooseAction = true;
} }
}
return false; return false;
} }

View file

@ -47,7 +47,7 @@ namespace MWMechanics
bool mMoveNow; bool mMoveNow;
bool mWalking; bool mWalking;
float mChanceMultiplyer; float mIdleChanceMultiplier;
unsigned short mPlayedIdle; unsigned short mPlayedIdle;
MWWorld::TimeStamp mStartTime; MWWorld::TimeStamp mStartTime;