diff --git a/CHANGELOG.md b/CHANGELOG.md index 769f09bedb..6017f62db4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions) Bug #3792: 1 frame late magicka recalc breaks early scripted magicka reactions to Intelligence change Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes + Bug #3855: AI sometimes spams defensive spells Bug #3905: Great House Dagoth issues Bug #4203: Resurrecting an actor should close the loot GUI Bug #4602: Robert's Bodies: crash inside createInstance() diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index eb276deb78..acc9fc2a3f 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -368,6 +368,24 @@ namespace MWMechanics return 0.f; break; + case ESM::MagicEffect::BoundShield: + if(!actor.getClass().hasInventoryStore(actor)) + return 0.f; + else if(!actor.getClass().isNpc()) + { + // If the actor is an NPC they can benefit from the armor rating, otherwise check if we've got a one-handed weapon to use with the shield + const auto& store = actor.getClass().getInventoryStore(actor); + auto oneHanded = std::find_if(store.cbegin(MWWorld::ContainerStore::Type_Weapon), store.cend(), [](const MWWorld::ConstPtr& weapon) + { + if(weapon.getClass().getItemHealth(weapon) <= 0.f) + return false; + short type = weapon.get()->mBase->mData.mType; + return !(MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded); + }); + if(oneHanded == store.cend()) + return 0.f; + } + break; // Creatures can not wear armor case ESM::MagicEffect::BoundCuirass: case ESM::MagicEffect::BoundGloves: @@ -552,6 +570,13 @@ namespace MWMechanics if (!creatureStats.getSummonedCreatureMap().empty()) return 0.f; } + if(effect.mEffectID >= ESM::MagicEffect::BoundDagger && effect.mEffectID <= ESM::MagicEffect::BoundGloves) + { + // While rateSpell prevents actors from recasting the same spell, it doesn't prevent them from casting different spells with the same effect. + // Multiple instances of the same bound item don't stack so if the effect is already active, rate it as useless. + if(actor.getClass().getCreatureStats(actor).getMagicEffects().get(effect.mEffectID).getMagnitude() > 0.f) + return 0.f; + } // Underwater casting not possible if (effect.mRange == ESM::RT_Target)