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
deque
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