mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 22:45:33 +00:00
Implement correct armor mitigation mechanics
This commit is contained in:
parent
804f1a5e59
commit
5629803a08
3 changed files with 20 additions and 6 deletions
|
@ -394,6 +394,9 @@ namespace MWClass
|
|||
if (damage > 0.0f && !object.isEmpty())
|
||||
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
|
||||
|
||||
if (damage < 0.001f)
|
||||
damage = 0;
|
||||
|
||||
if (damage > 0.f)
|
||||
{
|
||||
// Check for knockdown
|
||||
|
@ -409,6 +412,8 @@ namespace MWClass
|
|||
else
|
||||
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
|
||||
|
||||
damage = std::max(1.f, damage);
|
||||
|
||||
if(ishealth)
|
||||
{
|
||||
if (!attacker.isEmpty())
|
||||
|
@ -639,6 +644,7 @@ namespace MWClass
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -280,6 +280,7 @@ namespace MWClass
|
|||
gmst.iKnockDownOddsBase = store.find("iKnockDownOddsBase");
|
||||
gmst.fDamageStrengthBase = store.find("fDamageStrengthBase");
|
||||
gmst.fDamageStrengthMult = store.find("fDamageStrengthMult");
|
||||
gmst.fCombatArmorMinMult = store.find("fCombatArmorMinMult");
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
@ -706,6 +707,9 @@ namespace MWClass
|
|||
if (damage > 0.0f && !object.isEmpty())
|
||||
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
|
||||
|
||||
if (damage < 0.001f)
|
||||
damage = 0;
|
||||
|
||||
if(damage > 0.0f)
|
||||
{
|
||||
// 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying
|
||||
|
@ -734,7 +738,7 @@ namespace MWClass
|
|||
else
|
||||
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:
|
||||
// cuirass = 30%
|
||||
|
@ -754,9 +758,12 @@ namespace MWClass
|
|||
};
|
||||
int hitslot = hitslots[(int)(::rand()/(RAND_MAX+1.0)*20.0)];
|
||||
|
||||
float damagediff = damage;
|
||||
damage /= std::min(1.0f + getArmorRating(ptr)/std::max(1.0f, damage), 4.0f);
|
||||
damagediff -= damage;
|
||||
float unmitigatedDamage = damage;
|
||||
float x = damage / (damage + getArmorRating(ptr));
|
||||
damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x);
|
||||
int damageDiff = unmitigatedDamage - damage;
|
||||
if (damage < 1)
|
||||
damage = 1;
|
||||
|
||||
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot);
|
||||
|
@ -764,13 +771,13 @@ namespace MWClass
|
|||
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
|
||||
{
|
||||
int armorhealth = armor.getClass().getItemHealth(armor);
|
||||
armorhealth -= std::min(std::max(1, (int)damagediff),
|
||||
armorhealth -= std::min(std::max(1, damageDiff),
|
||||
armorhealth);
|
||||
armor.getCellRef().setCharge(armorhealth);
|
||||
|
||||
// Armor broken? unequip it
|
||||
if (armorhealth == 0)
|
||||
inv.unequipItem(armor, ptr);
|
||||
armor = *inv.unequipItem(armor, ptr);
|
||||
|
||||
if (ptr.getRefData().getHandle() == "player")
|
||||
skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0);
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace MWClass
|
|||
const ESM::GameSetting *iKnockDownOddsBase;
|
||||
const ESM::GameSetting *fDamageStrengthBase;
|
||||
const ESM::GameSetting *fDamageStrengthMult;
|
||||
const ESM::GameSetting *fCombatArmorMinMult;
|
||||
};
|
||||
|
||||
static const GMST& getGmst();
|
||||
|
|
Loading…
Reference in a new issue