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
pull/195/head
Michał Ściubidło 11 years ago
parent 20efeea5d9
commit d47bfbe69c

@ -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();
@ -421,8 +421,18 @@ namespace MWMechanics
Ogre::Vector3 playerPos(player.getRefData().getPosition().pos);
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;

@ -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...

Loading…
Cancel
Save