From 67de61e1fb3bf14ef0b5f6bb1cecc3b6b4d3d363 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 24 Oct 2018 18:51:34 +0300 Subject: [PATCH] Avoid item condition and charge zero divisions --- apps/openmw/mwclass/armor.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 11 +++++- apps/openmw/mwclass/weapon.cpp | 2 +- apps/openmw/mwgui/merchantrepair.cpp | 2 +- apps/openmw/mwgui/sortfilteritemmodel.cpp | 48 +++++++++++++++++++++-- apps/openmw/mwgui/tradewindow.cpp | 11 +++++- apps/openmw/mwgui/windowmanagerimp.cpp | 29 ++++++++++++-- apps/openmw/mwmechanics/combat.cpp | 11 +++++- 8 files changed, 100 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index b90c1ec581..ad64ad0d1e 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -297,7 +297,7 @@ namespace MWClass { const MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc); - if (ptr.getCellRef().getCharge() == 0) + if (getItemHealth(ptr) == 0) return std::make_pair(0, "#{sInventoryMessage1}"); // slots that this item can be equipped in diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index d6dafd2a25..f7172ac0b9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1148,9 +1148,16 @@ namespace MWClass const bool hasHealth = it->getClass().hasItemHealth(*it); if (hasHealth) { - int armorHealth = it->getClass().getItemHealth(*it); int armorMaxHealth = it->getClass().getItemMaxHealth(*it); - ratings[i] *= (float(armorHealth) / armorMaxHealth); + if (armorMaxHealth == 0) + { + ratings[i] = 0; + } + else + { + int armorHealth = it->getClass().getItemHealth(*it); + ratings[i] *= (float(armorHealth) / armorMaxHealth); + } } } } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 78678f4617..7d28c89835 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -383,7 +383,7 @@ namespace MWClass std::pair Weapon::canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const { - if (hasItemHealth(ptr) && ptr.getCellRef().getCharge() == 0) + if (hasItemHealth(ptr) && getItemHealth(ptr) == 0) return std::make_pair(0, "#{sInventoryMessage1}"); // Do not allow equip weapons from inventory during attack diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index b9d4c80f4f..282c0e4ea2 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -51,7 +51,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) { int maxDurability = iter->getClass().getItemMaxHealth(*iter); int durability = iter->getClass().getItemHealth(*iter); - if (maxDurability == durability) + if (maxDurability == durability || maxDurability == 0) continue; int basePrice = iter->getClass().getValue(*iter); diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index fe7f619524..5172c85ee8 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -86,26 +86,66 @@ namespace if (!leftName.empty()) { const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(leftName); + if (ench) { if (ench->mData.mType == ESM::Enchantment::ConstantEffect) + { leftChargePercent = 101; + } else - leftChargePercent = (left.mBase.getCellRef().getEnchantmentCharge() == -1) ? 100 - : static_cast(left.mBase.getCellRef().getEnchantmentCharge() / static_cast(ench->mData.mCharge) * 100); + { + int maxEnchCharge = ench->mData.mCharge; + if (maxEnchCharge == 0) + { + leftChargePercent = 0; + } + else + { + float enchCharge = left.mBase.getCellRef().getEnchantmentCharge(); + if (enchCharge == -1) + { + leftChargePercent = 100; + } + else + { + leftChargePercent = static_cast(enchCharge / static_cast(maxEnchCharge) * 100); + } + } + } } } if (!rightName.empty()) { const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(rightName); + if (ench) { if (ench->mData.mType == ESM::Enchantment::ConstantEffect) + { rightChargePercent = 101; + } else - rightChargePercent = (right.mBase.getCellRef().getEnchantmentCharge() == -1) ? 100 - : static_cast(right.mBase.getCellRef().getEnchantmentCharge() / static_cast(ench->mData.mCharge) * 100); + { + int maxEnchCharge = ench->mData.mCharge; + if (maxEnchCharge == 0) + { + rightChargePercent = 0; + } + else + { + float enchCharge = right.mBase.getCellRef().getEnchantmentCharge(); + if (enchCharge == -1) + { + rightChargePercent = 100; + } + else + { + rightChargePercent = static_cast(enchCharge / static_cast(maxEnchCharge) * 100); + } + } + } } } diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 4404b2b1a6..2fd91fd4a0 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -35,8 +35,15 @@ namespace float price = static_cast(item.getClass().getValue(item)); if (item.getClass().hasItemHealth(item)) { - price *= item.getClass().getItemHealth(item); - price /= item.getClass().getItemMaxHealth(item); + if (item.getClass().getItemMaxHealth(item) == 0) + { + price = 0; + } + else + { + price *= item.getClass().getItemHealth(item); + price /= item.getClass().getItemMaxHealth(item); + } } return static_cast(price * count); } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e4515fdc3f..3b26edecb8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1369,8 +1369,22 @@ namespace MWGui const ESM::Enchantment* ench = mStore->get() .find(item.getClass().getEnchantment(item)); - int chargePercent = (item.getCellRef().getEnchantmentCharge() == -1) ? 100 - : static_cast(item.getCellRef().getEnchantmentCharge() / static_cast(ench->mData.mCharge) * 100); + int chargePercent = 100; + + int maxEnchCharge = ench->mData.mCharge; + if (maxEnchCharge == 0) + { + chargePercent = 0; + } + else + { + float enchCharge = item.getCellRef().getEnchantmentCharge(); + if (enchCharge != -1) + { + chargePercent = static_cast(enchCharge / static_cast(maxEnchCharge) * 100); + } + } + mHud->setSelectedEnchantItem(item, chargePercent); mSpellWindow->setTitle(item.getClass().getName(item)); } @@ -1386,7 +1400,16 @@ namespace MWGui int durabilityPercent = 100; if (item.getClass().hasItemHealth(item)) { - durabilityPercent = static_cast(item.getClass().getItemHealth(item) / static_cast(item.getClass().getItemMaxHealth(item)) * 100); + int weapmaxhealth = item.getClass().getItemMaxHealth(item); + if (weapmaxhealth == 0) + { + durabilityPercent = 0; + } + else + { + int weaphealth = item.getClass().getItemHealth(item); + durabilityPercent = static_cast(weaphealth / static_cast(weapmaxhealth) * 100); + } } mHud->setSelectedWeapon(item, durabilityPercent); mInventoryWindow->setTitle(item.getClass().getName(item)); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index be55b681f1..2a9ff5e84f 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -371,10 +371,17 @@ namespace MWMechanics return; const bool weaphashealth = weapon.getClass().hasItemHealth(weapon); - if(weaphashealth) + if (weaphashealth) { - int weaphealth = weapon.getClass().getItemHealth(weapon); int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon); + + if (weapmaxhealth == 0) + { + damage = 0; + return; + } + + int weaphealth = weapon.getClass().getItemHealth(weapon); damage *= (float(weaphealth) / weapmaxhealth); }