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:
parent
20efeea5d9
commit
d47bfbe69c
2 changed files with 26 additions and 18 deletions
|
@ -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;
|
||||
|
|
|
@ -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…
Reference in a new issue