From 1666bc77407deb0a89657a8e73d6f7dce93417e1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 16 Mar 2013 22:53:33 +0100 Subject: [PATCH 1/5] Armor rating --- apps/openmw/mwbase/mechanicsmanager.hpp | 5 +- apps/openmw/mwgui/inventorywindow.cpp | 5 ++ .../mwmechanics/mechanicsmanagerimp.cpp | 49 +++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 ++ files/mygui/openmw_inventory_window.layout | 1 - 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index b8733259f..6cb7c6918 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -82,7 +82,10 @@ namespace MWBase virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0; ///< Calculate the diposition of an NPC toward the player. - + + virtual float getArmorRating (const MWWorld::Ptr& ptr) = 0; + ///< Calculate the combined armor rating of an NPC. + virtual int countDeaths (const std::string& id) const = 0; ///< Return the number of deaths for actors with the given ID. diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index ab7615c0e..2caed7972 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -13,6 +13,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" @@ -50,6 +51,7 @@ namespace MWGui getWidget(mFilterMisc, "MiscButton"); getWidget(mLeftPane, "LeftPane"); getWidget(mRightPane, "RightPane"); + getWidget(mArmorRating, "ArmorRating"); mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked); @@ -288,6 +290,9 @@ namespace MWGui mPreview.update (size.width, size.height); mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setImageTexture("CharacterPreview"); + + mArmorRating->setCaptionWithReplacing ("#{sArmor}: " + + boost::lexical_cast(static_cast(MWBase::Environment::get().getMechanicsManager()->getArmorRating(mPtr)))); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index c9e4c77ea..c19b84cd8 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -2,6 +2,7 @@ #include "mechanicsmanagerimp.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -668,4 +669,52 @@ namespace MWMechanics mActors.skipAnimation(ptr); } + float MechanicsManager::getArmorRating(const MWWorld::Ptr &ptr) + { + MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr); + const MWWorld::Store &gmst = + MWBase::Environment::get().getWorld()->getStore().get(); + + int ratings[MWWorld::InventoryStore::Slots]; + + int iBaseArmorSkill = gmst.find("iBaseArmorSkill")->getInt(); + float fUnarmoredBase1 = gmst.find("fUnarmoredBase1")->getFloat(); + float fUnarmoredBase2 = gmst.find("fUnarmoredBase2")->getFloat(); + int unarmoredSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(ESM::Skill::Unarmored).getModified(); + + for (int i = 0; i < MWWorld::InventoryStore::Slots; ++i) + { + MWWorld::ContainerStoreIterator it = invStore.getSlot(i); + if (it == invStore.end() || it->getTypeName() != typeid(ESM::Armor).name()) + { + // unarmored + ratings[i] = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill); + } + else + { + MWWorld::LiveCellRef *ref = + it->get(); + + int armorSkillType = MWWorld::Class::get(*it).getEquipmentSkill(*it); + int armorSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(armorSkillType).getModified(); + + if (ref->mBase->mData.mWeight == 0) + ratings[i] = ref->mBase->mData.mArmor; + else + ratings[i] = ref->mBase->mData.mArmor * armorSkill / iBaseArmorSkill; + } + } + + float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(3).mMagnitude; + + return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3 + + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] + + ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots] + + ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + ratings[MWWorld::InventoryStore::Slot_RightPauldron] + ) * 0.1 + + (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + MWWorld::InventoryStore::Slot_RightGauntlet) + * 0.05 + + shield; + } + } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 5ad870571..2e09c5f8e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -88,6 +88,9 @@ namespace MWMechanics virtual int getDerivedDisposition(const MWWorld::Ptr& ptr); ///< Calculate the diposition of an NPC toward the player. + virtual float getArmorRating (const MWWorld::Ptr& ptr); + ///< Calculate the combined armor rating of an NPC. + virtual int countDeaths (const std::string& id) const; ///< Return the number of deaths for actors with the given ID. diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 88cc5638d..41bd40f92 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -17,7 +17,6 @@ - From dd57eabc3ef9475f2c9b7e2aadba5da8d519cd33 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 16 Mar 2013 23:28:26 +0100 Subject: [PATCH 2/5] Better use an enum for magic effect IDs --- apps/openmw/mwclass/creature.cpp | 4 +- apps/openmw/mwclass/npc.cpp | 4 +- apps/openmw/mwdialogue/filter.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 9 +- .../mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 2 +- components/esm/loadmgef.hpp | 152 ++++++++++++++++++ 8 files changed, 164 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 19f327dcb..1b6212a23 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -203,9 +203,9 @@ namespace MWClass const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); - weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (8)).mMagnitude; // feather + weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).mMagnitude; - weight += stats.getMagicEffects().get (MWMechanics::EffectKey (7)).mMagnitude; // burden + weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).mMagnitude; if (weight<0) weight = 0; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 2ed285a81..d931b9e2e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -471,9 +471,9 @@ namespace MWClass const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); - weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (8)).mMagnitude; // feather + weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).mMagnitude; - weight += stats.getMagicEffects().get (MWMechanics::EffectKey (7)).mMagnitude; // burden + weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).mMagnitude; if (weight<0) weight = 0; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index d3405b2b2..7b5f354a2 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -459,7 +459,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_PcCorprus: return MWWorld::Class::get (player).getCreatureStats (player). - getMagicEffects().get (132).mMagnitude!=0; + getMagicEffects().get (ESM::MagicEffect::Corprus).mMagnitude!=0; case SelectWrapper::Function_PcExpelled: { diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 794a9ab55..6e914a669 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -159,7 +159,7 @@ namespace MWGui float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1; - bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(136)).mMagnitude > 0); + bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0); float fRestMagicMult = store.get().find("fRestMagicMult")->getFloat(); float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 9632bdf76..efbda83ee 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -71,7 +71,7 @@ namespace MWMechanics int endurance = creatureStats.getAttribute(5).getBase(); double magickaFactor = - creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5; + creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude * 0.1 + 0.5; DynamicStat health = creatureStats.getHealth(); health.setBase (static_cast (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ()); @@ -92,8 +92,7 @@ namespace MWMechanics if (duration == 3600) { - // stunted magicka - bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0; + bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0; int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); @@ -140,9 +139,9 @@ namespace MWMechanics for (int i=0; i<8; ++i) { int modifier = - creatureStats.getMagicEffects().get (EffectKey (79, i)).mMagnitude; + creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyAttribute, i)).mMagnitude; - modifier -= creatureStats.getMagicEffects().get (EffectKey (17, i)).mMagnitude; + modifier -= creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::DrainAttribute, i)).mMagnitude; creatureStats.getAttribute(i).setModifier (modifier); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index c19b84cd8..ac470fbba 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -705,7 +705,7 @@ namespace MWMechanics } } - float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(3).mMagnitude; + float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude; return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3 + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5a23aae97..a8b413518 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1259,7 +1259,7 @@ namespace MWWorld World::isFlying(const MWWorld::Ptr &ptr) const { const MWWorld::Class &cls = MWWorld::Class::get(ptr); - if(cls.isActor() && cls.getCreatureStats(ptr).getMagicEffects().get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude > 0) + if(cls.isActor() && cls.getCreatureStats(ptr).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Levitate)).mMagnitude > 0) return true; return false; } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 93c59f9cb..7efc17aec 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -66,6 +66,158 @@ struct MagicEffect void load(ESMReader &esm); void save(ESMWriter &esm); + + + enum Effects + { + WaterBreathing = 0, + SwiftSwim = 1, + WaterWalking = 2, + Shield = 3, + FireShield = 4, + LightningShield = 5, + FrostShield = 6, + Burden = 7, + Feather = 8, + Jump = 9, + Levitate = 10, + SlowFall = 11, + Lock = 12, + Open = 13, + FireDamage = 14, + ShockDamage = 15, + FrostDamage = 16, + DrainAttribute = 17, + DrainHealth = 18, + DrainMagicka = 19, + DrainFatigue = 20, + DrainSkill = 21, + DamageAttribute = 22, + DamageHealth = 23, + DamageMagicka = 24, + DamageFatigue = 25, + DamageSkill = 26, + Poison = 27, + WeaknessToFire = 28, + WeaknessToFrost = 29, + WeaknessToShock = 30, + WeaknessToMagicka = 31, + WeaknessToCommonDisease = 32, + WeaknessToBlightDisease = 33, + WeaknessToCorprusDisease = 34, + WeaknessToPoison = 35, + WeaknessToNormalWeapons = 36, + DisintegrateWeapon = 37, + DisintegrateArmor = 38, + Invisibility = 39, + Chameleon = 40, + Light = 41, + Sanctuary = 42, + NightEye = 43, + Charm = 44, + Paralyze = 45, + Silence = 46, + Blind = 47, + Sound = 48, + CalmHumanoid = 49, + CalmCreature = 50, + FrenzyHumanoid = 51, + FrenzyCreature = 52, + DemoralizeHumanoid = 53, + DemoralizeCreature = 54, + RallyHumanoid = 55, + RallyCreature = 56, + Dispel = 57, + Soultrap = 58, + Telekinesis = 59, + Mark = 60, + Recall = 61, + DivineIntervention = 62, + AlmsiviIntervention = 63, + DetectAnimal = 64, + DetectEnchantment = 65, + DetectKey = 66, + SpellAbsorption = 67, + Reflect = 68, + CureCommonDisease = 69, + CureBlightDisease = 70, + CureCorprusDisease = 71, + CurePoison = 72, + CureParalyzation = 73, + RestoreAttribute = 74, + RestoreHealth = 75, + RestoreMagicka = 76, + RestoreFatigue = 77, + RestoreSkill = 78, + FortifyAttribute = 79, + FortifyHealth = 80, + FortifyMagicka= 81, + FortifyFatigue = 82, + FortifySkill = 83, + FortifyMaximumMagicka = 84, + AbsorbAttribute = 85, + AbsorbHealth = 86, + AbsorbMagicka = 87, + AbsorbFatigue = 88, + AbsorbSkill = 89, + ResistFire = 90, + ResistFrost = 91, + ResistShock = 92, + ResistMagicka = 93, + ResistCommonDisease = 94, + ResistBlightDisease = 95, + ResistCorprusDisease = 96, + ResistPoison = 97, + ResistNormalWeapons = 98, + ResistParalysis = 99, + RemoveCurse = 100, + TurnUndead = 101, + SummonScamp = 102, + SummonClannfear = 103, + SummonDaedroth = 104, + SummonDremora = 105, + SummonAncestralGhost = 106, + SummonSkeletalMinion = 107, + SummonBonewalker = 108, + SummonGreaterBonewalker = 109, + SummonBonelord = 110, + SummonWingedTwilight = 111, + SummonHunger = 112, + SummonGoldenSaint = 113, + SummonFlameAtronach = 114, + SummonFrostAtronach = 115, + SummonStormAtronach = 116, + FortifyAttack = 117, + CommandCreature = 118, + CommandHumanoid = 119, + BoundDagger = 120, + BoundLongsword = 121, + BoundMace = 122, + BoundBattleAxe = 123, + BoundSpear = 124, + BoundLongbow = 125, + ExtraSpell = 126, + BoundCuirass = 127, + BoundHelm = 128, + BoundBoots = 129, + BoundShield = 130, + BoundGloves = 131, + Corprus = 132, + Vampirism = 133, + SummonCenturionSphere = 134, + SunDamage = 135, + StuntedMagicka = 136, + + // Tribunal only + SummonFabricant = 137, + + // Bloodmoon only + SummonWolf = 138, + SummonBear = 139, + SummonBonewolf = 140, + SummonCreature04 = 141, + SummonCreature05 = 142 + }; }; } #endif From c07b3ea61d96b918be9df6cdd23df9691e52ee77 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 Mar 2013 04:20:30 +0100 Subject: [PATCH 3/5] Text defines for npc race, class, and faction should use the translated name --- apps/openmw/mwscript/interpretercontext.cpp | 9 ++++++--- apps/openmw/mwscript/interpretercontext.hpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index c74e3f163..cad143c46 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -215,19 +215,22 @@ namespace MWScript std::string InterpreterContext::getNPCRace() const { ESM::NPC npc = *mReference.get()->mBase; - return npc.mRace; + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mRace); + return race->mName; } std::string InterpreterContext::getNPCClass() const { ESM::NPC npc = *mReference.get()->mBase; - return npc.mClass; + const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mClass); + return class_->mName; } std::string InterpreterContext::getNPCFaction() const { ESM::NPC npc = *mReference.get()->mBase; - return npc.mFaction; + const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mFaction); + return faction->mName; } std::string InterpreterContext::getNPCRank() const diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index f0b2758d9..9c7b443ae 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -89,7 +89,7 @@ namespace MWScript virtual std::string getNPCClass() const; virtual std::string getNPCFaction() const; - + virtual std::string getNPCRank() const; virtual std::string getPCName() const; From c66675b5997f104b2de753fecb96bfbc82e0def5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 Mar 2013 22:28:28 +0100 Subject: [PATCH 4/5] Fix the 'Take all' button taking equipped items when stealing --- apps/openmw/mwgui/container.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 2b8000312..e47686543 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -683,12 +683,18 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) // transfer everything into the player's inventory MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); + std::vector equippedItems = getEquippedItems(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player); int i=0; for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter) { + if (std::find(equippedItems.begin(), equippedItems.end(), *iter) != equippedItems.end() + && !mDisplayEquippedItems) + continue; + playerStore.add(*iter); if (i==0) @@ -698,11 +704,11 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); } + iter->getRefData().setCount(0); + ++i; } - containerStore.clear(); - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } } From 95e1cdc07ddd1443522695f20617b5c110169ea7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 Mar 2013 22:29:12 +0100 Subject: [PATCH 5/5] Move getArmorRating to MWWorld::Class. --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 -- apps/openmw/mwclass/creature.cpp | 6 +++ apps/openmw/mwclass/creature.hpp | 3 ++ apps/openmw/mwclass/npc.cpp | 49 +++++++++++++++++++ apps/openmw/mwclass/npc.hpp | 3 ++ apps/openmw/mwgui/inventorywindow.cpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 48 ------------------ .../mwmechanics/mechanicsmanagerimp.hpp | 3 -- apps/openmw/mwworld/class.cpp | 7 ++- apps/openmw/mwworld/class.hpp | 3 ++ 10 files changed, 71 insertions(+), 56 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 6cb7c6918..020647744 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -83,9 +83,6 @@ namespace MWBase virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0; ///< Calculate the diposition of an NPC toward the player. - virtual float getArmorRating (const MWWorld::Ptr& ptr) = 0; - ///< Calculate the combined armor rating of an NPC. - virtual int countDeaths (const std::string& id) const = 0; ///< Return the number of deaths for actors with the given ID. diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 1b6212a23..1097f8f29 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -191,6 +191,12 @@ namespace MWClass return info; } + float Creature::getArmorRating (const MWWorld::Ptr& ptr) const + { + /// \todo add Shield magic effect magnitude here, controlled by a GMST (Vanilla vs MCP behaviour) + return 0.f; + } + float Creature::getCapacity (const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index a96c18a8c..ea356165e 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -54,6 +54,9 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. + virtual float getArmorRating (const MWWorld::Ptr& ptr) const; + ///< @return combined armor rating of this actor + virtual bool isEssential (const MWWorld::Ptr& ptr) const; ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index d931b9e2e..a5319ada0 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -505,6 +505,55 @@ namespace MWClass stats.useSkill (skill, *class_, usageType); } + float Npc::getArmorRating (const MWWorld::Ptr& ptr) const + { + MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr); + const MWWorld::Store &gmst = + MWBase::Environment::get().getWorld()->getStore().get(); + + int ratings[MWWorld::InventoryStore::Slots]; + + int iBaseArmorSkill = gmst.find("iBaseArmorSkill")->getInt(); + float fUnarmoredBase1 = gmst.find("fUnarmoredBase1")->getFloat(); + float fUnarmoredBase2 = gmst.find("fUnarmoredBase2")->getFloat(); + int unarmoredSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(ESM::Skill::Unarmored).getModified(); + + for (int i = 0; i < MWWorld::InventoryStore::Slots; ++i) + { + MWWorld::ContainerStoreIterator it = invStore.getSlot(i); + if (it == invStore.end() || it->getTypeName() != typeid(ESM::Armor).name()) + { + // unarmored + ratings[i] = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill); + } + else + { + MWWorld::LiveCellRef *ref = + it->get(); + + int armorSkillType = MWWorld::Class::get(*it).getEquipmentSkill(*it); + int armorSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(armorSkillType).getModified(); + + if (ref->mBase->mData.mWeight == 0) + ratings[i] = ref->mBase->mData.mArmor; + else + ratings[i] = ref->mBase->mData.mArmor * armorSkill / iBaseArmorSkill; + } + } + + float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude; + + return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3 + + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] + + ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots] + + ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + ratings[MWWorld::InventoryStore::Slot_RightPauldron] + ) * 0.1 + + (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + MWWorld::InventoryStore::Slot_RightGauntlet) + * 0.05 + + shield; + } + + void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const { y = 0; diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 0ca6a8d69..0f61fc8c9 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -104,6 +104,9 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. + virtual float getArmorRating (const MWWorld::Ptr& ptr) const; + ///< @return combined armor rating of this actor + virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id, const MWWorld::Ptr& actor) const; ///< Apply \a id on \a ptr. diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 2caed7972..29966bd08 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -292,7 +292,7 @@ namespace MWGui mAvatarImage->setImageTexture("CharacterPreview"); mArmorRating->setCaptionWithReplacing ("#{sArmor}: " - + boost::lexical_cast(static_cast(MWBase::Environment::get().getMechanicsManager()->getArmorRating(mPtr)))); + + boost::lexical_cast(static_cast(MWWorld::Class::get(mPtr).getArmorRating(mPtr)))); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index ac470fbba..32fa58980 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -669,52 +669,4 @@ namespace MWMechanics mActors.skipAnimation(ptr); } - float MechanicsManager::getArmorRating(const MWWorld::Ptr &ptr) - { - MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); - - int ratings[MWWorld::InventoryStore::Slots]; - - int iBaseArmorSkill = gmst.find("iBaseArmorSkill")->getInt(); - float fUnarmoredBase1 = gmst.find("fUnarmoredBase1")->getFloat(); - float fUnarmoredBase2 = gmst.find("fUnarmoredBase2")->getFloat(); - int unarmoredSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(ESM::Skill::Unarmored).getModified(); - - for (int i = 0; i < MWWorld::InventoryStore::Slots; ++i) - { - MWWorld::ContainerStoreIterator it = invStore.getSlot(i); - if (it == invStore.end() || it->getTypeName() != typeid(ESM::Armor).name()) - { - // unarmored - ratings[i] = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill); - } - else - { - MWWorld::LiveCellRef *ref = - it->get(); - - int armorSkillType = MWWorld::Class::get(*it).getEquipmentSkill(*it); - int armorSkill = MWWorld::Class::get(ptr).getNpcStats(ptr).getSkill(armorSkillType).getModified(); - - if (ref->mBase->mData.mWeight == 0) - ratings[i] = ref->mBase->mData.mArmor; - else - ratings[i] = ref->mBase->mData.mArmor * armorSkill / iBaseArmorSkill; - } - } - - float shield = MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude; - - return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3 - + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] - + ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots] - + ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + ratings[MWWorld::InventoryStore::Slot_RightPauldron] - ) * 0.1 - + (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + MWWorld::InventoryStore::Slot_RightGauntlet) - * 0.05 - + shield; - } - } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 2e09c5f8e..5ad870571 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -88,9 +88,6 @@ namespace MWMechanics virtual int getDerivedDisposition(const MWWorld::Ptr& ptr); ///< Calculate the diposition of an NPC toward the player. - virtual float getArmorRating (const MWWorld::Ptr& ptr); - ///< Calculate the combined armor rating of an NPC. - virtual int countDeaths (const std::string& id) const; ///< Return the number of deaths for actors with the given ID. diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 71b24b65d..985d35d45 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -167,11 +167,16 @@ namespace MWWorld return false; } - bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const + bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const { return false; } + float Class::getArmorRating (const MWWorld::Ptr& ptr) const + { + throw std::runtime_error("Class does not support armor rating"); + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 1a6a16ca0..53dbeff86 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -215,6 +215,9 @@ namespace MWWorld ///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval /// (default implementation: throw an exception) + virtual float getArmorRating (const MWWorld::Ptr& ptr) const; + ///< @return combined armor rating of this actor + virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; ///< Return name of inventory icon.