1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-27 14:37:04 +00:00

Correct activation behavior for actors in combat (#7794)

Stop battle music upon death animation end
This commit is contained in:
Alexei Kotov 2024-01-28 20:57:46 +03:00
parent 6ce9c20d56
commit c5564323e4
4 changed files with 27 additions and 20 deletions

View File

@ -138,6 +138,7 @@
Bug #7770: Sword of the Perithia: Script execution failure Bug #7770: Sword of the Perithia: Script execution failure
Bug #7780: Non-ASCII texture paths in NIF files don't work Bug #7780: Non-ASCII texture paths in NIF files don't work
Bug #7785: OpenMW-CS initialising Skill and Attribute fields to 0 instead of -1 on non-FortifyStat spells Bug #7785: OpenMW-CS initialising Skill and Attribute fields to 0 instead of -1 on non-FortifyStat spells
Bug #7794: Fleeing NPCs name tooltip doesn't appear
Bug #7796: Absorbed enchantments don't restore magicka Bug #7796: Absorbed enchantments don't restore magicka
Feature #2566: Handle NAM9 records for manual cell references Feature #2566: Handle NAM9 records for manual cell references
Feature #3537: Shader-based water ripples Feature #3537: Shader-based water ripples

View File

@ -474,20 +474,17 @@ namespace MWClass
} }
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const MWMechanics::AiSequence& aiSequence = stats.getAiSequence();
const bool isInCombat = aiSequence.isInCombat();
if (stats.isDead()) if (stats.isDead())
{ {
// by default user can loot friendly actors during death animation // by default user can loot non-fighting actors during death animation
if (Settings::game().mCanLootDuringDeathAnimation && !isInCombat) if (Settings::game().mCanLootDuringDeathAnimation)
return std::make_unique<MWWorld::ActionOpen>(ptr); return std::make_unique<MWWorld::ActionOpen>(ptr);
// otherwise wait until death animation // otherwise wait until death animation
if (stats.isDeathAnimationFinished()) if (stats.isDeathAnimationFinished())
return std::make_unique<MWWorld::ActionOpen>(ptr); return std::make_unique<MWWorld::ActionOpen>(ptr);
} }
else if ((!isInCombat || aiSequence.isFleeing()) && !stats.getKnockedDown()) else if (!stats.getKnockedDown())
return std::make_unique<MWWorld::ActionTalk>(ptr); return std::make_unique<MWWorld::ActionTalk>(ptr);
// Tribunal and some mod companions oddly enough must use open action as fallback // Tribunal and some mod companions oddly enough must use open action as fallback

View File

@ -924,36 +924,43 @@ namespace MWClass
} }
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const MWMechanics::AiSequence& aiSequence = stats.getAiSequence();
const bool isPursuing = aiSequence.isInPursuit() && actor == MWMechanics::getPlayer();
const bool inCombatWithActor = aiSequence.isInCombat(actor) || isPursuing;
if (stats.isDead()) if (stats.isDead())
{ {
// by default user can loot friendly actors during death animation // by default user can loot non-fighting actors during death animation
if (Settings::game().mCanLootDuringDeathAnimation && !stats.getAiSequence().isInCombat()) if (Settings::game().mCanLootDuringDeathAnimation)
return std::make_unique<MWWorld::ActionOpen>(ptr); return std::make_unique<MWWorld::ActionOpen>(ptr);
// otherwise wait until death animation // otherwise wait until death animation
if (stats.isDeathAnimationFinished()) if (stats.isDeathAnimationFinished())
return std::make_unique<MWWorld::ActionOpen>(ptr); return std::make_unique<MWWorld::ActionOpen>(ptr);
} }
else if (!stats.getAiSequence().isInCombat()) else
{ {
if (stats.getKnockedDown() || MWBase::Environment::get().getMechanicsManager()->isSneaking(actor)) const bool allowStealingFromKO
return std::make_unique<MWWorld::ActionOpen>(ptr); // stealing = Settings::game().mAlwaysAllowStealingFromKnockedOutActors || !inCombatWithActor;
if (stats.getKnockedDown() && allowStealingFromKO)
return std::make_unique<MWWorld::ActionOpen>(ptr);
// Can't talk to werewolves const bool allowStealingWhileSneaking = !inCombatWithActor;
if (!getNpcStats(ptr).isWerewolf()) if (MWBase::Environment::get().getMechanicsManager()->isSneaking(actor) && allowStealingWhileSneaking)
return std::make_unique<MWWorld::ActionOpen>(ptr);
const bool allowTalking = !inCombatWithActor && !getNpcStats(ptr).isWerewolf();
if (allowTalking)
return std::make_unique<MWWorld::ActionTalk>(ptr); return std::make_unique<MWWorld::ActionTalk>(ptr);
} }
else // In combat
{
if (Settings::game().mAlwaysAllowStealingFromKnockedOutActors && stats.getKnockedDown())
return std::make_unique<MWWorld::ActionOpen>(ptr); // stealing
}
// Tribunal and some mod companions oddly enough must use open action as fallback // Tribunal and some mod companions oddly enough must use open action as fallback
if (!getScript(ptr).empty() && ptr.getRefData().getLocals().getIntVar(getScript(ptr), "companion")) if (!getScript(ptr).empty() && ptr.getRefData().getLocals().getIntVar(getScript(ptr), "companion"))
return std::make_unique<MWWorld::ActionOpen>(ptr); return std::make_unique<MWWorld::ActionOpen>(ptr);
if (inCombatWithActor)
return std::make_unique<MWWorld::FailedAction>("#{sActorInCombat}");
return std::make_unique<MWWorld::FailedAction>(); return std::make_unique<MWWorld::FailedAction>();
} }
@ -1086,7 +1093,8 @@ namespace MWClass
if (customData.mNpcStats.isDead() && customData.mNpcStats.isDeathAnimationFinished()) if (customData.mNpcStats.isDead() && customData.mNpcStats.isDeathAnimationFinished())
return true; return true;
if (!customData.mNpcStats.getAiSequence().isInCombat()) const MWMechanics::AiSequence& aiSeq = customData.mNpcStats.getAiSequence();
if (!aiSeq.isInCombat() || aiSeq.isFleeing())
return true; return true;
if (Settings::game().mAlwaysAllowStealingFromKnockedOutActors && customData.mNpcStats.getKnockedDown()) if (Settings::game().mAlwaysAllowStealingFromKnockedOutActors && customData.mNpcStats.getKnockedDown())

View File

@ -1309,7 +1309,8 @@ namespace MWMechanics
if (inProcessingRange) if (inProcessingRange)
{ {
MWMechanics::CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); MWMechanics::CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr());
if (!stats.isDead() && stats.getAiSequence().isInCombat()) bool isDead = stats.isDead() && stats.isDeathAnimationFinished();
if (!isDead && stats.getAiSequence().isInCombat())
{ {
hasHostiles = true; hasHostiles = true;
break; break;