1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-28 23:36:41 +00:00

Implement AI greeting states.

Greeting consist of 3 phases:
- none - default one, greeting state can only change to "in progress"
  when near enough and some time passes
- in progress - NPC says his greating and rotates toward player,
  state can only change to "done" after some time
- done - rotation is stoped, after idling can go away from player,
  state can only change to "none" when player and NPC are faraway
This commit is contained in:
Michał Ściubidło 2014-07-28 23:16:24 +01:00
parent 20efeea5d9
commit d47bfbe69c
2 changed files with 26 additions and 18 deletions

View file

@ -43,7 +43,7 @@ namespace MWMechanics
mReaction = 0;
mRotate = false;
mTargetAngle = 0;
mSaidGreeting = false;
mSaidGreeting = Greet_None;
mHasReturnPosition = false;
mReturnPosition = Ogre::Vector3(0,0,0);
@ -407,7 +407,7 @@ namespace MWMechanics
}
// Allow interrupting a walking actor to trigger a greeting
if(mIdleNow || (mWalking && !mObstacleCheck.isNormalState() && mDistance))
if(mIdleNow || mWalking)
{
// Play a random voice greeting if the player gets too close
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
@ -422,7 +422,17 @@ namespace MWMechanics
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
float playerDistSqr = playerPos.squaredDistance(actorPos);
if(playerDistSqr <= helloDistance*helloDistance)
if (mSaidGreeting == Greet_None)
{
// TODO: check if actor is aware / has line of sight
if (playerDistSqr <= helloDistance*helloDistance)
{
mSaidGreeting = Greet_InProgress;
MWBase::Environment::get().getDialogueManager()->say(actor, "hello");
}
}
if(mSaidGreeting == Greet_InProgress)
{
if(mWalking)
{
@ -449,29 +459,22 @@ namespace MWMechanics
mRotate = true;
}
}
mSaidGreeting = Greet_Done;
}
if (!mSaidGreeting)
{
// TODO: check if actor is aware / has line of sight
if (playerDistSqr <= helloDistance*helloDistance)
{
mSaidGreeting = true;
MWBase::Environment::get().getDialogueManager()->say(actor, "hello");
}
}
else
if (mSaidGreeting == MWMechanics::AiWander::Greet_Done)
{
static float fGreetDistanceReset = MWBase::Environment::get().getWorld()->getStore()
.get<ESM::GameSetting>().find("fGreetDistanceReset")->getFloat();
if (playerDistSqr >= fGreetDistanceReset*fGreetDistanceReset)
mSaidGreeting = false;
mSaidGreeting = Greet_None;
}
// Check if idle animation finished
// FIXME: don't stay forever
if(!checkIdle(actor, mPlayedIdle) && playerDistSqr > helloDistance*helloDistance)
if(!checkIdle(actor, mPlayedIdle) && (playerDistSqr > helloDistance*helloDistance || mSaidGreeting == MWMechanics::AiWander::Greet_Done))
{
mPlayedIdle = 0;
mIdleNow = false;

View file

@ -62,7 +62,12 @@ namespace MWMechanics
std::vector<unsigned char> mIdle;
bool mRepeat;
bool mSaidGreeting;
enum GreetingState {
Greet_None,
Greet_InProgress,
Greet_Done
};
GreetingState mSaidGreeting;
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
// if we had the actor in the AiWander constructor...