diff --git a/CHANGELOG.md b/CHANGELOG.md index 89fe8eac4..14d644c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Bug #1990: Sunrise/sunset not set correct Bug #2222: Fatigue's effect on selling price is backwards Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped + Bug #2455: Creatures attacks degrade armor Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash Bug #2772: Non-existing class or faction freezes the game Bug #2835: Player able to slowly move when overencumbered diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 92e25baee..0becb18df 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -773,22 +773,24 @@ namespace MWClass float x = damage / (damage + getArmorRating(ptr)); damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x); int damageDiff = static_cast(unmitigatedDamage - damage); - if (damage < 1) - damage = 1; + damage = std::max(1.f, damage); + damageDiff = std::max(1, damageDiff); MWWorld::InventoryStore &inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot); MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr()); if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name()) { - int armorhealth = armor.getClass().getItemHealth(armor); - armorhealth -= std::min(std::max(1, damageDiff), - armorhealth); - armor.getCellRef().setCharge(armorhealth); - - // Armor broken? unequip it - if (armorhealth == 0) - armor = *inv.unequipItem(armor, ptr); + if (attacker.isEmpty() || (!attacker.isEmpty() && !(object.isEmpty() && !attacker.getClass().isNpc()))) // Unarmed creature attacks don't affect armor condition + { + int armorhealth = armor.getClass().getItemHealth(armor); + armorhealth -= std::min(damageDiff, armorhealth); + armor.getCellRef().setCharge(armorhealth); + + // Armor broken? unequip it + if (armorhealth == 0) + armor = *inv.unequipItem(armor, ptr); + } if (ptr == MWMechanics::getPlayer()) skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index ac34c658b..6b45a513b 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -115,14 +115,16 @@ namespace MWMechanics if (Misc::Rng::roll0to99() < x) { - // Reduce shield durability by incoming damage - int shieldhealth = shield->getClass().getItemHealth(*shield); - - shieldhealth -= std::min(shieldhealth, int(damage)); - shield->getCellRef().setCharge(shieldhealth); - if (shieldhealth == 0) - inv.unequipItem(*shield, blocker); + if (!(weapon.isEmpty() && !attacker.getClass().isNpc())) // Unarmed creature attacks don't affect armor condition + { + // Reduce shield durability by incoming damage + int shieldhealth = shield->getClass().getItemHealth(*shield); + shieldhealth -= std::min(shieldhealth, int(damage)); + shield->getCellRef().setCharge(shieldhealth); + if (shieldhealth == 0) + inv.unequipItem(*shield, blocker); + } // Reduce blocker fatigue const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat(); const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();