mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 09:53:50 +00:00
AiWander: move idle animation handling to non-delayed section (Fixes #2073)
This commit is contained in:
parent
f9ae0d9d66
commit
a1226501fa
1 changed files with 53 additions and 52 deletions
|
@ -282,6 +282,58 @@ namespace MWMechanics
|
||||||
rotate = false;
|
rotate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if idle animation finished
|
||||||
|
short unsigned& playedIdle = storage.mPlayedIdle;
|
||||||
|
GreetingState& greetingState = storage.mSaidGreeting;
|
||||||
|
if(idleNow && !checkIdle(actor, playedIdle) && (greetingState == Greet_Done || greetingState == Greet_None))
|
||||||
|
{
|
||||||
|
playedIdle = 0;
|
||||||
|
idleNow = false;
|
||||||
|
chooseAction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
|
if(chooseAction)
|
||||||
|
{
|
||||||
|
playedIdle = 0;
|
||||||
|
getRandomIdle(playedIdle); // NOTE: sets mPlayedIdle with a random selection
|
||||||
|
|
||||||
|
if(!playedIdle && mDistance)
|
||||||
|
{
|
||||||
|
chooseAction = false;
|
||||||
|
moveNow = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander:
|
||||||
|
MWWorld::TimeStamp currentTime = world->getTimeStamp();
|
||||||
|
mStartTime = currentTime;
|
||||||
|
playIdle(actor, playedIdle);
|
||||||
|
chooseAction = false;
|
||||||
|
idleNow = true;
|
||||||
|
|
||||||
|
// Play idle voiced dialogue entries randomly
|
||||||
|
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
|
||||||
|
if (hello > 0)
|
||||||
|
{
|
||||||
|
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
|
||||||
|
// Don't bother if the player is out of hearing range
|
||||||
|
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
||||||
|
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->getFloat();
|
||||||
|
|
||||||
|
// Only say Idle voices when player is in LOS
|
||||||
|
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
||||||
|
// voices going through walls?
|
||||||
|
if (roll < fVoiceIdleOdds && Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(pos.pos)) < 1500*1500
|
||||||
|
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
||||||
|
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float& lastReaction = storage.mReaction;
|
float& lastReaction = storage.mReaction;
|
||||||
lastReaction += duration;
|
lastReaction += duration;
|
||||||
if(lastReaction < REACTION_INTERVAL)
|
if(lastReaction < REACTION_INTERVAL)
|
||||||
|
@ -293,7 +345,6 @@ namespace MWMechanics
|
||||||
|
|
||||||
// NOTE: everything below get updated every REACTION_INTERVAL seconds
|
// NOTE: everything below get updated every REACTION_INTERVAL seconds
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
||||||
if(mDuration)
|
if(mDuration)
|
||||||
{
|
{
|
||||||
// End package if duration is complete or mid-night hits:
|
// End package if duration is complete or mid-night hits:
|
||||||
|
@ -439,48 +490,6 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AiWander::GreetingState& greetingState = storage.mSaidGreeting;
|
|
||||||
short unsigned& playedIdle = storage.mPlayedIdle;
|
|
||||||
if(chooseAction)
|
|
||||||
{
|
|
||||||
playedIdle = 0;
|
|
||||||
getRandomIdle(playedIdle); // NOTE: sets mPlayedIdle with a random selection
|
|
||||||
|
|
||||||
if(!playedIdle && mDistance)
|
|
||||||
{
|
|
||||||
chooseAction = false;
|
|
||||||
moveNow = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander:
|
|
||||||
MWWorld::TimeStamp currentTime = world->getTimeStamp();
|
|
||||||
mStartTime = currentTime;
|
|
||||||
playIdle(actor, playedIdle);
|
|
||||||
chooseAction = false;
|
|
||||||
idleNow = true;
|
|
||||||
|
|
||||||
// Play idle voiced dialogue entries randomly
|
|
||||||
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
|
|
||||||
if (hello > 0)
|
|
||||||
{
|
|
||||||
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
|
||||||
|
|
||||||
// Don't bother if the player is out of hearing range
|
|
||||||
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
|
||||||
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->getFloat();
|
|
||||||
|
|
||||||
// Only say Idle voices when player is in LOS
|
|
||||||
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
|
||||||
// voices going through walls?
|
|
||||||
if (roll < fVoiceIdleOdds && Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(pos.pos)) < 1500*1500
|
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
|
||||||
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow interrupting a walking actor to trigger a greeting
|
// Allow interrupting a walking actor to trigger a greeting
|
||||||
if(idleNow || walking)
|
if(idleNow || walking)
|
||||||
{
|
{
|
||||||
|
@ -556,14 +565,6 @@ namespace MWMechanics
|
||||||
if (playerDistSqr >= fGreetDistanceReset*fGreetDistanceReset)
|
if (playerDistSqr >= fGreetDistanceReset*fGreetDistanceReset)
|
||||||
greetingState = Greet_None;
|
greetingState = Greet_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if idle animation finished
|
|
||||||
if(!checkIdle(actor, playedIdle) && (playerDistSqr > helloDistance*helloDistance || greetingState == MWMechanics::AiWander::Greet_Done))
|
|
||||||
{
|
|
||||||
playedIdle = 0;
|
|
||||||
idleNow = false;
|
|
||||||
chooseAction = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(moveNow && mDistance)
|
if(moveNow && mDistance)
|
||||||
|
|
Loading…
Reference in a new issue