mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-01 19:15:33 +00:00
Use duration rather than frame counts. Stops false detection of being "stuck" with high frame rates (e.g. indoors).
This commit is contained in:
parent
c9f9566623
commit
f597d3e88b
2 changed files with 29 additions and 17 deletions
|
@ -18,9 +18,10 @@
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
// NOTE: determined empirically but probably need further tweaking
|
// NOTE: determined empirically but probably need further tweaking
|
||||||
static const int COUNT_BEFORE_STUCK = 20;
|
|
||||||
static const int COUNT_BEFORE_RESET = 200;
|
static const int COUNT_BEFORE_RESET = 200;
|
||||||
static const int COUNT_EVADE = 7;
|
static const float DIST_SAME_SPOT = 1.8f;
|
||||||
|
static const float DURATION_SAME_SPOT = 1.0f;
|
||||||
|
static const float DURATION_TO_EVADE = 0.4f;
|
||||||
|
|
||||||
AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector<int>& idle, bool repeat):
|
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)
|
||||||
|
@ -35,7 +36,8 @@ namespace MWMechanics
|
||||||
, mPrevY(0)
|
, mPrevY(0)
|
||||||
, mWalkState(State_Norm)
|
, mWalkState(State_Norm)
|
||||||
, mStuckCount(0)
|
, mStuckCount(0)
|
||||||
, mEvadeCount(0)
|
, mEvadeDuration(0)
|
||||||
|
, mStuckDuration(0)
|
||||||
, mSaidGreeting(false)
|
, mSaidGreeting(false)
|
||||||
{
|
{
|
||||||
for(unsigned short counter = 0; counter < mIdle.size(); counter++)
|
for(unsigned short counter = 0; counter < mIdle.size(); counter++)
|
||||||
|
@ -325,15 +327,21 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 1 n
|
/* f t
|
||||||
* State_Norm <---> State_CheckStuck --> State_Evade
|
* State_Norm <---> State_CheckStuck --> State_Evade
|
||||||
* ^ ^ | ^ | ^ | |
|
* ^ ^ | ^ | ^ | |
|
||||||
* | | | | | | | |
|
* | | | | | | | |
|
||||||
* | +---+ +---+ +---+ | m
|
* | +---+ +---+ +---+ | u
|
||||||
* | any < n < m |
|
* | any < t < u |
|
||||||
* +--------------------------------------------+
|
* +--------------------------------------------+
|
||||||
|
*
|
||||||
|
* f = one frame
|
||||||
|
* t = how long before considered stuck
|
||||||
|
* u = how long to move sideways
|
||||||
*/
|
*/
|
||||||
bool samePosition = (abs(pos.pos[0] - mPrevX) < 1) && (abs(pos.pos[1] - mPrevY) < 1);
|
bool samePosition = (abs(pos.pos[0] - mPrevX) < DIST_SAME_SPOT) &&
|
||||||
|
(abs(pos.pos[1] - mPrevY) < DIST_SAME_SPOT);
|
||||||
|
|
||||||
switch(mWalkState)
|
switch(mWalkState)
|
||||||
{
|
{
|
||||||
case State_Norm:
|
case State_Norm:
|
||||||
|
@ -349,30 +357,33 @@ namespace MWMechanics
|
||||||
if(!samePosition)
|
if(!samePosition)
|
||||||
{
|
{
|
||||||
mWalkState = State_Norm;
|
mWalkState = State_Norm;
|
||||||
// to do this properly need yet another variable, simply don't clear for now
|
mStuckDuration = 0;
|
||||||
//mStuckCount = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// consider stuck only if position unchanges consecutively
|
mStuckDuration += duration;
|
||||||
if((mStuckCount++ % COUNT_BEFORE_STUCK) == 0)
|
// consider stuck only if position unchanges for a period
|
||||||
|
if(mStuckDuration > DURATION_SAME_SPOT)
|
||||||
|
{
|
||||||
mWalkState = State_Evade;
|
mWalkState = State_Evade;
|
||||||
// NOTE: mStuckCount is purposely not cleared here
|
mStuckDuration = 0;
|
||||||
|
mStuckCount++;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break; // still in the same state, but counter got incremented
|
break; // still in the same state, but duration added to timer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case State_Evade:
|
case State_Evade:
|
||||||
{
|
{
|
||||||
if(mEvadeCount++ < COUNT_EVADE)
|
mEvadeDuration += duration;
|
||||||
|
if(mEvadeDuration < DURATION_TO_EVADE)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mWalkState = State_Norm; // tried to evade, assume all is ok and start again
|
mWalkState = State_Norm; // tried to evade, assume all is ok and start again
|
||||||
// NOTE: mStuckCount is purposely not cleared here
|
mEvadeDuration = 0;
|
||||||
mEvadeCount = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NO DEFAULT CASE */
|
/* NO DEFAULT CASE */
|
||||||
|
|
|
@ -58,7 +58,8 @@ namespace MWMechanics
|
||||||
WalkState mWalkState;
|
WalkState mWalkState;
|
||||||
|
|
||||||
int mStuckCount;
|
int mStuckCount;
|
||||||
int mEvadeCount;
|
float mStuckDuration;
|
||||||
|
float mEvadeDuration;
|
||||||
|
|
||||||
bool mStoredAvailableNodes;
|
bool mStoredAvailableNodes;
|
||||||
bool mChooseAction;
|
bool mChooseAction;
|
||||||
|
|
Loading…
Reference in a new issue