1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-29 22:36:43 +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; mReaction = 0;
mRotate = false; mRotate = false;
mTargetAngle = 0; mTargetAngle = 0;
mSaidGreeting = false; mSaidGreeting = Greet_None;
mHasReturnPosition = false; mHasReturnPosition = false;
mReturnPosition = Ogre::Vector3(0,0,0); mReturnPosition = Ogre::Vector3(0,0,0);
@ -407,7 +407,7 @@ namespace MWMechanics
} }
// Allow interrupting a walking actor to trigger a greeting // 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 // Play a random voice greeting if the player gets too close
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified(); int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
@ -421,8 +421,18 @@ namespace MWMechanics
Ogre::Vector3 playerPos(player.getRefData().getPosition().pos); Ogre::Vector3 playerPos(player.getRefData().getPosition().pos);
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
float playerDistSqr = playerPos.squaredDistance(actorPos); 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) if(mWalking)
{ {
@ -449,29 +459,22 @@ namespace MWMechanics
mRotate = true; mRotate = true;
} }
} }
mSaidGreeting = Greet_Done;
} }
if (!mSaidGreeting) if (mSaidGreeting == MWMechanics::AiWander::Greet_Done)
{
// TODO: check if actor is aware / has line of sight
if (playerDistSqr <= helloDistance*helloDistance)
{
mSaidGreeting = true;
MWBase::Environment::get().getDialogueManager()->say(actor, "hello");
}
}
else
{ {
static float fGreetDistanceReset = MWBase::Environment::get().getWorld()->getStore() static float fGreetDistanceReset = MWBase::Environment::get().getWorld()->getStore()
.get<ESM::GameSetting>().find("fGreetDistanceReset")->getFloat(); .get<ESM::GameSetting>().find("fGreetDistanceReset")->getFloat();
if (playerDistSqr >= fGreetDistanceReset*fGreetDistanceReset) if (playerDistSqr >= fGreetDistanceReset*fGreetDistanceReset)
mSaidGreeting = false; mSaidGreeting = Greet_None;
} }
// Check if idle animation finished // Check if idle animation finished
// FIXME: don't stay forever // 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; mPlayedIdle = 0;
mIdleNow = false; mIdleNow = false;

View file

@ -62,7 +62,12 @@ namespace MWMechanics
std::vector<unsigned char> mIdle; std::vector<unsigned char> mIdle;
bool mRepeat; 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, bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
// if we had the actor in the AiWander constructor... // if we had the actor in the AiWander constructor...