mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +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(); | ||||
|  | @ -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…
	
		Reference in a new issue