From a46c4de918853f6d539815c2341a5d0ffd4fd675 Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 12 Jan 2017 00:32:36 +0900 Subject: [PATCH 1/3] Stop combat when adding an AI package to an actor (Fixes #3722) --- apps/openmw/mwmechanics/aisequence.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index a134fd44a..1bd2f98b3 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -281,6 +281,10 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor) } } + // Stop combat when a non-combat AI package is added + if (isActualAiPackage(package.getTypeId())) + stopCombat(); + // remove previous packages if required if (package.shouldCancelPreviousAi()) { From e825010107a0d8773791cd3bd952d611665ff2da Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 12 Jan 2017 02:23:03 +0900 Subject: [PATCH 2/3] Apply command spell effects on impact Command spells should apply their effects, including taking an actor out of combat, every time a spell successfully hits, even if a previous command effect is still active. --- apps/openmw/mwmechanics/actors.cpp | 9 ++------- apps/openmw/mwmechanics/spellcasting.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index cd8f18777..c25eafcaf 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -93,6 +93,7 @@ public: } }; +// Check for command effects having ended and remove package if necessary void adjustCommandedActor (const MWWorld::Ptr& actor) { CheckActorCommanded check(actor); @@ -112,13 +113,7 @@ void adjustCommandedActor (const MWWorld::Ptr& actor) } } - if (check.mCommanded && !hasCommandPackage) - { - // FIXME: don't use refid string - MWMechanics::AiFollow package("player", true); - stats.getAiSequence().stack(package, actor); - } - else if (!check.mCommanded && hasCommandPackage) + if (!check.mCommanded && hasCommandPackage) { stats.getAiSequence().erase(it); } diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 489ab83ec..242c5e659 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -27,6 +27,7 @@ #include "magiceffects.hpp" #include "npcstats.hpp" #include "actorutil.hpp" +#include "aifollow.hpp" namespace MWMechanics { @@ -490,6 +491,15 @@ namespace MWMechanics appliedLastingEffects.push_back(effect); + // Command spells should have their effect, including taking the target out of combat, each time the spell successfully affects the target + if (effectIt->mEffectID == ESM::MagicEffect::CommandHumanoid && target.getClass().isNpc() + || (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name()) + && caster == getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel()) + { + MWMechanics::AiFollow package(caster.getCellRef().getRefId(), true); + target.getClass().getCreatureStats(target).getAiSequence().stack(package, target); + } + // For absorb effects, also apply the effect to the caster - but with a negative // magnitude, since we're transferring stats from the target to the caster if (!caster.isEmpty() && caster.getClass().isActor()) From f2240dde9cbbadce39fc5078562692dc4d227e07 Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 12 Jan 2017 03:11:45 +0900 Subject: [PATCH 3/3] Allow command spells to work when cast by AI on AI (Fixes #3723) --- apps/openmw/mwmechanics/actors.cpp | 6 ++---- apps/openmw/mwmechanics/spellcasting.cpp | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index c25eafcaf..db8598a75 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -84,10 +84,8 @@ public: const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { - MWWorld::Ptr player = MWMechanics::getPlayer(); - if ( ((key.mId == ESM::MagicEffect::CommandHumanoid && mActor.getClass().isNpc()) - || (key.mId == ESM::MagicEffect::CommandCreature && mActor.getTypeName() == typeid(ESM::Creature).name())) - && casterActorId == player.getClass().getCreatureStats(player).getActorId() + if (((key.mId == ESM::MagicEffect::CommandHumanoid && mActor.getClass().isNpc()) + || (key.mId == ESM::MagicEffect::CommandCreature && mActor.getTypeName() == typeid(ESM::Creature).name())) && magnitude >= mActor.getClass().getCreatureStats(mActor).getLevel()) mCommanded = true; } diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 242c5e659..a364f90a9 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -492,9 +492,9 @@ namespace MWMechanics appliedLastingEffects.push_back(effect); // Command spells should have their effect, including taking the target out of combat, each time the spell successfully affects the target - if (effectIt->mEffectID == ESM::MagicEffect::CommandHumanoid && target.getClass().isNpc() - || (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name()) - && caster == getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel()) + if (((effectIt->mEffectID == ESM::MagicEffect::CommandHumanoid && target.getClass().isNpc()) + || (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name())) + && !caster.isEmpty() && caster.getClass().isActor() && target != getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel()) { MWMechanics::AiFollow package(caster.getCellRef().getRefId(), true); target.getClass().getCreatureStats(target).getAiSequence().stack(package, target);