1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-02 01:45:31 +00:00

Implement correct armor mitigation mechanics

This commit is contained in:
scrawl 2014-07-20 23:08:22 +02:00
parent 804f1a5e59
commit 5629803a08
3 changed files with 20 additions and 6 deletions

View file

@ -394,6 +394,9 @@ namespace MWClass
if (damage > 0.0f && !object.isEmpty()) if (damage > 0.0f && !object.isEmpty())
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage); MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
if (damage < 0.001f)
damage = 0;
if (damage > 0.f) if (damage > 0.f)
{ {
// Check for knockdown // Check for knockdown
@ -409,6 +412,8 @@ namespace MWClass
else else
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
damage = std::max(1.f, damage);
if(ishealth) if(ishealth)
{ {
if (!attacker.isEmpty()) if (!attacker.isEmpty())
@ -639,6 +644,7 @@ namespace MWClass
float Creature::getArmorRating (const MWWorld::Ptr& ptr) const float Creature::getArmorRating (const MWWorld::Ptr& ptr) const
{ {
// Note this is currently unused. Creatures do not use armor mitigation.
return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude; return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude;
} }

View file

@ -280,6 +280,7 @@ namespace MWClass
gmst.iKnockDownOddsBase = store.find("iKnockDownOddsBase"); gmst.iKnockDownOddsBase = store.find("iKnockDownOddsBase");
gmst.fDamageStrengthBase = store.find("fDamageStrengthBase"); gmst.fDamageStrengthBase = store.find("fDamageStrengthBase");
gmst.fDamageStrengthMult = store.find("fDamageStrengthMult"); gmst.fDamageStrengthMult = store.find("fDamageStrengthMult");
gmst.fCombatArmorMinMult = store.find("fCombatArmorMinMult");
inited = true; inited = true;
} }
@ -706,6 +707,9 @@ namespace MWClass
if (damage > 0.0f && !object.isEmpty()) if (damage > 0.0f && !object.isEmpty())
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage); MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
if (damage < 0.001f)
damage = 0;
if(damage > 0.0f) if(damage > 0.0f)
{ {
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
@ -734,7 +738,7 @@ namespace MWClass
else else
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
if(ishealth && !attacker.isEmpty()) // Don't use armor mitigation for fall damage if(damage > 0 && ishealth && !attacker.isEmpty()) // Don't use armor mitigation for fall damage
{ {
// Hit percentages: // Hit percentages:
// cuirass = 30% // cuirass = 30%
@ -754,9 +758,12 @@ namespace MWClass
}; };
int hitslot = hitslots[(int)(::rand()/(RAND_MAX+1.0)*20.0)]; int hitslot = hitslots[(int)(::rand()/(RAND_MAX+1.0)*20.0)];
float damagediff = damage; float unmitigatedDamage = damage;
damage /= std::min(1.0f + getArmorRating(ptr)/std::max(1.0f, damage), 4.0f); float x = damage / (damage + getArmorRating(ptr));
damagediff -= damage; damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x);
int damageDiff = unmitigatedDamage - damage;
if (damage < 1)
damage = 1;
MWWorld::InventoryStore &inv = getInventoryStore(ptr); MWWorld::InventoryStore &inv = getInventoryStore(ptr);
MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot); MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot);
@ -764,13 +771,13 @@ namespace MWClass
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name()) if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
{ {
int armorhealth = armor.getClass().getItemHealth(armor); int armorhealth = armor.getClass().getItemHealth(armor);
armorhealth -= std::min(std::max(1, (int)damagediff), armorhealth -= std::min(std::max(1, damageDiff),
armorhealth); armorhealth);
armor.getCellRef().setCharge(armorhealth); armor.getCellRef().setCharge(armorhealth);
// Armor broken? unequip it // Armor broken? unequip it
if (armorhealth == 0) if (armorhealth == 0)
inv.unequipItem(armor, ptr); armor = *inv.unequipItem(armor, ptr);
if (ptr.getRefData().getHandle() == "player") if (ptr.getRefData().getHandle() == "player")
skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0); skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0);

View file

@ -40,6 +40,7 @@ namespace MWClass
const ESM::GameSetting *iKnockDownOddsBase; const ESM::GameSetting *iKnockDownOddsBase;
const ESM::GameSetting *fDamageStrengthBase; const ESM::GameSetting *fDamageStrengthBase;
const ESM::GameSetting *fDamageStrengthMult; const ESM::GameSetting *fDamageStrengthMult;
const ESM::GameSetting *fCombatArmorMinMult;
}; };
static const GMST& getGmst(); static const GMST& getGmst();