diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3b4288317..e337ad039 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -89,15 +89,14 @@ 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; } }; +// Check for command effects having ended and remove package if necessary void adjustCommandedActor (const MWWorld::Ptr& actor) { CheckActorCommanded check(actor); @@ -117,13 +116,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/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()) { diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index b4ea29efe..4b196741b 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -31,6 +31,7 @@ #include "magiceffects.hpp" #include "npcstats.hpp" #include "actorutil.hpp" +#include "aifollow.hpp" namespace MWMechanics { @@ -494,6 +495,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.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); + } + // 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()) diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index ae36db1c3..f6fa3556f 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -84,6 +84,7 @@ namespace MWWorld try { copy (refData); + mFlags &= ~(Flag_SuppressActivate|Flag_OnActivate|Flag_ActivationBuffered); } catch (...) {