1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 20:15:35 +00:00

Refactor normal weapon resistance

This commit is contained in:
Capostrophic 2018-12-08 21:17:15 +03:00
parent cb5a57e41b
commit 808b8ce8db
4 changed files with 36 additions and 16 deletions

View file

@ -308,6 +308,7 @@ namespace MWClass
{ {
damage = attack[0] + ((attack[1]-attack[0])*attackStrength); damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
MWMechanics::adjustWeaponDamage(damage, weapon, ptr); MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr); MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
} }
@ -382,9 +383,6 @@ namespace MWClass
if (!object.isEmpty()) if (!object.isEmpty())
stats.setLastHitObject(object.getCellRef().getRefId()); stats.setLastHitObject(object.getCellRef().getRefId());
if (damage > 0.0f && !object.isEmpty())
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
if (damage < 0.001f) if (damage < 0.001f)
damage = 0; damage = 0;

View file

@ -604,6 +604,7 @@ namespace MWClass
} }
bool healthdmg; bool healthdmg;
bool resisted = false;
float damage = 0.0f; float damage = 0.0f;
if(!weapon.isEmpty()) if(!weapon.isEmpty())
{ {
@ -619,6 +620,7 @@ namespace MWClass
damage = attack[0] + ((attack[1]-attack[0])*attackStrength); damage = attack[0] + ((attack[1]-attack[0])*attackStrength);
} }
MWMechanics::adjustWeaponDamage(damage, weapon, ptr); MWMechanics::adjustWeaponDamage(damage, weapon, ptr);
resisted = MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr); MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
healthdmg = true; healthdmg = true;
} }
@ -629,6 +631,8 @@ namespace MWClass
if(ptr == MWMechanics::getPlayer()) if(ptr == MWMechanics::getPlayer())
{ {
skillUsageSucceeded(ptr, weapskill, 0); skillUsageSucceeded(ptr, weapskill, 0);
if (resisted)
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
const MWMechanics::AiSequence& seq = victim.getClass().getCreatureStats(victim).getAiSequence(); const MWMechanics::AiSequence& seq = victim.getClass().getCreatureStats(victim).getAiSequence();

View file

@ -148,28 +148,38 @@ namespace MWMechanics
return false; return false;
} }
void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage) bool isNormalWeapon(const MWWorld::Ptr &weapon)
{ {
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects(); if (weapon.isEmpty())
float resistance = std::min(100.f, effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() return false;
- effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude());
float multiplier = 1.f - resistance / 100.f; const int &flags = weapon.get<ESM::Weapon>()->mBase->mData.mFlags;
bool isSilver = flags & ESM::Weapon::Silver;
bool isMagical = flags & ESM::Weapon::Magical;
bool isEnchanted = !weapon.getClass().getEnchantment(weapon).empty();
if (!(weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver return !isSilver && !isMagical && (!isEnchanted || !Settings::Manager::getBool("enchanted weapons are magical", "Game"));
|| weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Magical)) }
bool resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage)
{
if (damage == 0)
return false;
if (isNormalWeapon(weapon))
{ {
if (weapon.getClass().getEnchantment(weapon).empty() const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects();
|| !Settings::Manager::getBool("enchanted weapons are magical", "Game")) const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f;
damage *= multiplier; const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f;
damage *= 1.f - std::min(1.f, resistance-weakness);
} }
if ((weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver) if ((weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver)
&& actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) && actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat(); damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat();
if (damage == 0 && attacker == getPlayer()) return (damage == 0);
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
} }
void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile, void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
@ -208,9 +218,13 @@ namespace MWMechanics
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength); damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
adjustWeaponDamage(damage, weapon, attacker); adjustWeaponDamage(damage, weapon, attacker);
bool resisted = resistNormalWeapon(victim, attacker, projectile, damage);
if (attacker == getPlayer()) if (attacker == getPlayer())
{ {
if (resisted)
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
attacker.getClass().skillUsageSucceeded(attacker, weaponSkill, 0); attacker.getClass().skillUsageSucceeded(attacker, weaponSkill, 0);
const MWMechanics::AiSequence& sequence = victim.getClass().getCreatureStats(victim).getAiSequence(); const MWMechanics::AiSequence& sequence = victim.getClass().getCreatureStats(victim).getAiSequence();

View file

@ -12,7 +12,11 @@ bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr&
/// @return can we block the attack? /// @return can we block the attack?
bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength); bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength);
void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage); /// @return does normal weapon resistance and weakness apply to the weapon?
bool isNormalWeapon (const MWWorld::Ptr& weapon);
/// @return was the damage fully resisted?
bool resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage);
/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt /// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt
/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor /// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor