diff --git a/CHANGELOG.md b/CHANGELOG.md index faea4d0b6c..07d0514f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Bug #7770: Sword of the Perithia: Script execution failure 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 #7794: Fleeing NPCs name tooltip doesn't appear Bug #7796: Absorbed enchantments don't restore magicka Feature #2566: Handle NAM9 records for manual cell references Feature #3537: Shader-based water ripples diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index d19e5d5c43..2de58c6127 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -474,20 +474,17 @@ namespace MWClass } const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - const MWMechanics::AiSequence& aiSequence = stats.getAiSequence(); - - const bool isInCombat = aiSequence.isInCombat(); if (stats.isDead()) { - // by default user can loot friendly actors during death animation - if (Settings::game().mCanLootDuringDeathAnimation && !isInCombat) + // by default user can loot non-fighting actors during death animation + if (Settings::game().mCanLootDuringDeathAnimation) return std::make_unique(ptr); // otherwise wait until death animation if (stats.isDeathAnimationFinished()) return std::make_unique(ptr); } - else if ((!isInCombat || aiSequence.isFleeing()) && !stats.getKnockedDown()) + else if (!stats.getKnockedDown()) return std::make_unique(ptr); // Tribunal and some mod companions oddly enough must use open action as fallback diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index b8cd4cd23d..ce1df10db3 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -924,36 +924,43 @@ namespace MWClass } 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()) { - // by default user can loot friendly actors during death animation - if (Settings::game().mCanLootDuringDeathAnimation && !stats.getAiSequence().isInCombat()) + // by default user can loot non-fighting actors during death animation + if (Settings::game().mCanLootDuringDeathAnimation) return std::make_unique(ptr); // otherwise wait until death animation if (stats.isDeathAnimationFinished()) return std::make_unique(ptr); } - else if (!stats.getAiSequence().isInCombat()) + else { - if (stats.getKnockedDown() || MWBase::Environment::get().getMechanicsManager()->isSneaking(actor)) - return std::make_unique(ptr); // stealing + const bool allowStealingFromKO + = Settings::game().mAlwaysAllowStealingFromKnockedOutActors || !inCombatWithActor; + if (stats.getKnockedDown() && allowStealingFromKO) + return std::make_unique(ptr); - // Can't talk to werewolves - if (!getNpcStats(ptr).isWerewolf()) + const bool allowStealingWhileSneaking = !inCombatWithActor; + if (MWBase::Environment::get().getMechanicsManager()->isSneaking(actor) && allowStealingWhileSneaking) + return std::make_unique(ptr); + + const bool allowTalking = !inCombatWithActor && !getNpcStats(ptr).isWerewolf(); + if (allowTalking) return std::make_unique(ptr); } - else // In combat - { - if (Settings::game().mAlwaysAllowStealingFromKnockedOutActors && stats.getKnockedDown()) - return std::make_unique(ptr); // stealing - } // Tribunal and some mod companions oddly enough must use open action as fallback if (!getScript(ptr).empty() && ptr.getRefData().getLocals().getIntVar(getScript(ptr), "companion")) return std::make_unique(ptr); + if (inCombatWithActor) + return std::make_unique("#{sActorInCombat}"); + return std::make_unique(); } @@ -1086,7 +1093,8 @@ namespace MWClass if (customData.mNpcStats.isDead() && customData.mNpcStats.isDeathAnimationFinished()) return true; - if (!customData.mNpcStats.getAiSequence().isInCombat()) + const MWMechanics::AiSequence& aiSeq = customData.mNpcStats.getAiSequence(); + if (!aiSeq.isInCombat() || aiSeq.isFleeing()) return true; if (Settings::game().mAlwaysAllowStealingFromKnockedOutActors && customData.mNpcStats.getKnockedDown()) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index d463fa729b..bd55652e5d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1309,7 +1309,8 @@ namespace MWMechanics if (inProcessingRange) { 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; break;