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:
parent
96daad7a22
commit
fd96d47fe4
2 changed files with 20 additions and 16 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue