diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index d0a9137608..c23b9e23a6 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -359,6 +359,9 @@ namespace MWClass ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); } + if (damage > 0.0f && !object.isEmpty()) + MWMechanics::resistNormalWeapon(ptr, attacker, object, damage); + if (damage > 0.f) { // Check for knockdown diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index f4ccd3c5f7..8c6e895446 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -652,6 +652,9 @@ namespace MWClass if (!attacker.isEmpty()) MWMechanics::diseaseContact(ptr, attacker); + if (damage > 0.0f && !object.isEmpty()) + MWMechanics::resistNormalWeapon(ptr, attacker, object, damage); + if(damage > 0.0f) { // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index d547368579..2042641065 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -5,12 +5,14 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/movement.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwbase/windowmanager.hpp" + namespace { @@ -108,4 +110,28 @@ namespace MWMechanics return false; } + void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage) + { + MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); + float resistance = std::min(100.f, stats.getMagicEffects().get(ESM::MagicEffect::ResistNormalWeapons).mMagnitude + - stats.getMagicEffects().get(ESM::MagicEffect::WeaknessToNormalWeapons).mMagnitude); + + float multiplier = 0; + if (resistance >= 0) + multiplier = 1 - resistance / 100.f; + else + multiplier = -(resistance-100) / 100.f; + + if (!(weapon.get()->mBase->mData.mFlags & ESM::Weapon::Silver + || weapon.get()->mBase->mData.mFlags & ESM::Weapon::Magical)) + damage *= multiplier; + + if (weapon.get()->mBase->mData.mFlags & ESM::Weapon::Silver + & actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + damage *= MWBase::Environment::get().getWorld()->getStore().get().find("fWereWolfSilverWeaponDamageMult")->getFloat(); + + if (damage == 0 && attacker.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}"); + } + } diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index d666905f26..7f24156972 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -9,6 +9,8 @@ namespace MWMechanics /// @return can we block the attack? bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage); +void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage); + } #endif