AiWander: move idle animation handling to non-delayed section (Fixes #2073)

report
scrawl 10 years ago
parent f9ae0d9d66
commit a1226501fa

@ -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)
{ {
@ -496,7 +505,7 @@ 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);
int& greetingTimer = storage.mGreetingTimer; int& greetingTimer = storage.mGreetingTimer;
if (greetingState == Greet_None) if (greetingState == Greet_None)
{ {
@ -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…
Cancel
Save