diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 39cd99cf6..77f465b4c 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -44,7 +44,7 @@ add_openmw_dir (mwsound add_openmw_dir (mwworld refdata world physicssystem scene environment globals class action nullaction actionteleport containerstore actiontalk actiontake manualref player cellfunctors - cells localscripts customdata weather + cells localscripts customdata weather inventorystore ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 25021b718..9b97d7de8 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -2,12 +2,17 @@ #include "armor.hpp" #include +#include +#include #include #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" + +#include "../mwworld/inventorystore.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" #include "../mwrender/objects.hpp" @@ -55,7 +60,7 @@ namespace MWClass boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -82,6 +87,79 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + std::vector slots; + + const int size = 11; + + static const int sMapping[size][2] = + { + { ESM::Armor::Helmet, MWWorld::InventoryStore::Slot_Helmet }, + { ESM::Armor::Cuirass, MWWorld::InventoryStore::Slot_Cuirass }, + { ESM::Armor::LPauldron, MWWorld::InventoryStore::Slot_LeftPauldron }, + { ESM::Armor::RPauldron, MWWorld::InventoryStore::Slot_RightPauldron }, + { ESM::Armor::Greaves, MWWorld::InventoryStore::Slot_Greaves }, + { ESM::Armor::Boots, MWWorld::InventoryStore::Slot_Boots }, + { ESM::Armor::LGauntlet, MWWorld::InventoryStore::Slot_LeftGauntlet }, + { ESM::Armor::RGauntlet, MWWorld::InventoryStore::Slot_RightGauntlet }, + { ESM::Armor::Shield, MWWorld::InventoryStore::Slot_CarriedLeft }, + { ESM::Armor::LBracer, MWWorld::InventoryStore::Slot_LeftGauntlet }, + { ESM::Armor::RBracer, MWWorld::InventoryStore::Slot_RightGauntlet } + }; + + for (int i=0; ibase->data.type) + { + slots.push_back (int (sMapping[i][1])); + break; + } + + return std::make_pair (slots, false); + } + + int Armor::getEuqipmentSkill (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + std::string typeGmst; + + switch (ref->base->data.type) + { + case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break; + case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break; + case ESM::Armor::LPauldron: + case ESM::Armor::RPauldron: typeGmst = "iPauldronWeight"; break; + case ESM::Armor::Greaves: typeGmst = "iGreavesWeight"; break; + case ESM::Armor::Boots: typeGmst = "iBootsWeight"; break; + case ESM::Armor::LGauntlet: + case ESM::Armor::RGauntlet: typeGmst = "iGauntletWeight"; break; +/// \todo how to determine if shield light, medium or heavy? +// case ESM::Armor::Shield: + case ESM::Armor::LBracer: + case ESM::Armor::RBracer: typeGmst = "iGauntletWeight"; break; + } + + if (typeGmst.empty()) + return -1; + + float iWeight = environment.mWorld->getStore().gameSettings.find (typeGmst)->f; + + if (iWeight * environment.mWorld->getStore().gameSettings.find ("fLightMaxMod")->f<= + ref->base->data.weight) + return ESM::Skill::LightArmor; + + if (iWeight * environment.mWorld->getStore().gameSettings.find ("fMedMaxMod")->f<= + ref->base->data.weight) + return ESM::Skill::MediumArmor; + + return ESM::Skill::HeavyArmor; + } + void Armor::registerSelf() { boost::shared_ptr instance (new Armor); @@ -89,116 +167,25 @@ namespace MWClass registerClass (typeid (ESM::Armor).name(), instance); } - std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { - int wc = getWeightCategory(ptr); - if (wc == WC_Light) + int es = getEuqipmentSkill(ptr, environment); + if (es == ESM::Skill::LightArmor) return std::string("Item Armor Light Up"); - else if (wc == WC_Medium) + else if (es == ESM::Skill::MediumArmor) return std::string("Item Armor Medium Up"); else return std::string("Item Armor Heavy Up"); } - std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { - int wc = getWeightCategory(ptr); - if (wc == WC_Light) + int es = getEuqipmentSkill(ptr, environment); + if (es == ESM::Skill::LightArmor) return std::string("Item Armor Light Down"); - else if (wc == WC_Medium) + else if (es == ESM::Skill::MediumArmor) return std::string("Item Armor Medium Down"); else return std::string("Item Armor Heavy Down"); } - - int Armor::getWeightCategory (const MWWorld::Ptr& ptr) const - { - ESMS::LiveCellRef *ref = - ptr.get(); - - float weight = ref->base->data.weight; - int type = ref->base->data.type; - // Boots - if (type == 5) - { - if (weight <= 12.0) - { - return WC_Light; - } - else if (weight > 18.0) - { - return WC_Heavy; - } - else - { - return WC_Medium; - } - } - // Cuirass - if (type == 1) - { - if (weight <= 18.0) - { - return WC_Light; - } - else if (weight > 27.0) - { - return WC_Heavy; - } - else - { - return WC_Medium; - } - } - // Greaves, Shield - if (type == 4 || type == 8) - { - if (weight <= 9.0) - { - return WC_Light; - } - else if (weight > 13.5) - { - return WC_Heavy; - } - else - { - return WC_Medium; - } - } - // Bracer, Gauntlet, Helmet - if (type == 6 || type == 7 || type == 9 || type == 10 || type == 0) - { - if (weight <= 3.0) - { - return WC_Light; - } - else if (weight > 4.5) - { - return WC_Heavy; - } - else - { - return WC_Medium; - } - } - // Pauldrons - if (type == 2 || type == 3) - { - if (weight <= 6.0) - { - return WC_Light; - } - else if (weight > 9.0) - { - return WC_Heavy; - } - else - { - return WC_Medium; - } - } - - return WC_Light; - } } diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 943fcaa0b..b240e96e3 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -5,13 +5,6 @@ namespace MWClass { - enum WeightCategory - { - WC_Light = 0, - WC_Medium = 1, - WC_Heavy = 2 - }; - class Armor : public MWWorld::Class { public: @@ -38,16 +31,22 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + + virtual int getEuqipmentSkill (const MWWorld::Ptr& ptr, + const MWWorld::Environment& environment) const; + /// Return the index of the skill this item corresponds to when equiopped or -1, if there is + /// no such skill. + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id - - virtual int getWeightCategory (const MWWorld::Ptr& ptr) const; - ///< Return the weight category of the armor light/medium/heavy }; } diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 9bc3eaab5..0a81ebafb 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -58,7 +58,7 @@ namespace MWClass { // TODO implement reading - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -79,12 +79,12 @@ namespace MWClass registerClass (typeid (ESM::Book).name(), instance); } - std::string Book::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Book::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Book Up"); } - std::string Book::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Book::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Book Down"); } diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index 612583dc8..ccbbfb4b2 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -27,10 +27,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 5d353a0f3..56b981fe4 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwrender/objects.hpp" @@ -56,7 +57,7 @@ namespace MWClass boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +71,58 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + std::vector slots; + + if (ref->base->data.type==ESM::Clothing::Ring) + { + slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing)); + slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing)); + } + else + { + const int size = 9; + + static const int sMapping[size][2] = + { + { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Cuirass }, + { ESM::Clothing::Belt, MWWorld::InventoryStore::Slot_Belt }, + { ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe }, + { ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants }, + { ESM::Clothing::Shoes, MWWorld::InventoryStore::Slot_Boots }, + { ESM::Clothing::LGlove, MWWorld::InventoryStore::Slot_LeftGauntlet }, + { ESM::Clothing::RGlove, MWWorld::InventoryStore::Slot_RightGauntlet }, + { ESM::Clothing::Skirt, MWWorld::InventoryStore::Slot_Skirt }, + { ESM::Clothing::Amulet, MWWorld::InventoryStore::Slot_Amulet } + }; + + for (int i=0; ibase->data.type) + { + slots.push_back (int (sMapping[i][1])); + break; + } + } + + return std::make_pair (slots, false); + } + + int Clothing::getEuqipmentSkill (const MWWorld::Ptr& ptr, + const MWWorld::Environment& environment) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + if (ref->base->data.type==ESM::Clothing::Shoes) + return ESM::Skill::Unarmored; + + return -1; + } + void Clothing::registerSelf() { boost::shared_ptr instance (new Clothing); @@ -77,7 +130,7 @@ namespace MWClass registerClass (typeid (ESM::Clothing).name(), instance); } - std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -89,7 +142,7 @@ namespace MWClass return std::string("Item Clothes Up"); } - std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 086e87dff..47faa5ad3 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -25,12 +25,21 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + + virtual int getEuqipmentSkill (const MWWorld::Ptr& ptr, + const MWWorld::Environment& environment) const; + /// Return the index of the skill this item corresponds to when equiopped or -1, if there is + /// no such skill. + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index da25a90ad..1a7edf632 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -54,7 +54,7 @@ namespace MWClass boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -75,12 +75,12 @@ namespace MWClass registerClass (typeid (ESM::Ingredient).name(), instance); } - std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Ingredient Up"); } - std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Ingredient Down"); } diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index e7cd5e9bf..9463dcf8d 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -27,10 +27,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 9a5daf24d..e2e63a89b 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -9,6 +9,7 @@ #include "../mwworld/actiontake.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwsound/soundmanager.hpp" @@ -82,7 +83,7 @@ namespace MWClass if (!(ref->base->data.flags & ESM::Light::Carry)) return boost::shared_ptr (new MWWorld::NullAction); - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -96,6 +97,19 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + std::vector slots; + + if (ref->base->data.flags & ESM::Light::Carry) + slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft)); + + return std::make_pair (slots, false); + } + void Light::registerSelf() { boost::shared_ptr instance (new Light); @@ -103,12 +117,12 @@ namespace MWClass registerClass (typeid (ESM::Light).name(), instance); } - std::string Light::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Light::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Misc Up"); } - std::string Light::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Light::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Misc Down"); } diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 212c6dbf8..46a4d60ba 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -30,12 +30,16 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 5d176675f..3dda2f4af 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwrender/objects.hpp" @@ -57,7 +58,7 @@ namespace MWClass boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -71,6 +72,15 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + std::vector slots; + + slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + + return std::make_pair (slots, false); + } + void Lockpick::registerSelf() { boost::shared_ptr instance (new Lockpick); @@ -78,12 +88,12 @@ namespace MWClass registerClass (typeid (ESM::Tool).name(), instance); } - std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Lockpick Up"); } - std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Lockpick Down"); } diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index bc5ad98ec..0c9189c54 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -25,12 +25,16 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 20a0e5b4d..864fc1e38 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -77,7 +77,7 @@ namespace MWClass registerClass (typeid (ESM::Miscellaneous).name(), instance); } - std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -89,7 +89,7 @@ namespace MWClass return std::string("Item Misc Up"); } - std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 857ef5354..b07964f99 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -27,10 +27,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index cc7daa83e..83a94d27d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -16,7 +16,7 @@ #include "../mwworld/actiontalk.hpp" #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" -#include "../mwworld/containerstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwworld/customdata.hpp" namespace @@ -29,7 +29,7 @@ namespace MWMechanics::NpcStats mNpcStats; MWMechanics::CreatureStats mCreatureStats; MWMechanics::Movement mMovement; - MWWorld::ContainerStore mContainerStore; + MWWorld::InventoryStore mInventoryStore; virtual MWWorld::CustomData *clone() const; }; @@ -161,7 +161,15 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; + return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; + } + + MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr) + const + { + ensureCustomData (ptr); + + return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; } std::string Npc::getScript (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index bef417332..f210eda5f 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -38,6 +38,9 @@ namespace MWClass virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; ///< Return container store + virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const; + ///< Return inventory store + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; ///< Generate action for activation diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 4eb62bbc7..4ab374590 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -77,12 +77,12 @@ namespace MWClass registerClass (typeid (ESM::Potion).name(), instance); } - std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Potion Up"); } - std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Potion Down"); } diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 191ef5b15..be9e713fb 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -27,10 +27,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 343022c82..4b4d79a73 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwrender/objects.hpp" @@ -56,7 +57,7 @@ namespace MWClass boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +71,15 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + std::vector slots; + + slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + + return std::make_pair (slots, false); + } + void Probe::registerSelf() { boost::shared_ptr instance (new Probe); @@ -77,12 +87,12 @@ namespace MWClass registerClass (typeid (ESM::Probe).name(), instance); } - std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Probe Up"); } - std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Probe Down"); } diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index d601e1b31..1507d65aa 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -25,12 +25,16 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 505308814..758bf4079 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -77,12 +77,12 @@ namespace MWClass registerClass (typeid (ESM::Repair).name(), instance); } - std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Repair Up"); } - std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { return std::string("Item Repair Down"); } diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index eef35acc9..17b606f4c 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -27,10 +27,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 274799d3f..45fdaada3 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwrender/objects.hpp" @@ -56,7 +57,7 @@ namespace MWClass boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -83,6 +84,61 @@ namespace MWClass return ref->base->script; } + std::pair, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + std::vector slots; + bool stack = false; + + if (ref->base->data.type==ESM::Weapon::Arrow || ref->base->data.type==ESM::Weapon::Bolt) + { + slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition)); + stack = true; + } + else if (ref->base->data.type==ESM::Weapon::MarksmanThrown) + { + slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + stack = true; + } + else + slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + + return std::make_pair (slots, stack); + } + + int Weapon::getEuqipmentSkill (const MWWorld::Ptr& ptr, + const MWWorld::Environment& environment) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + const int size = 12; + + static const int sMapping[size][2] = + { + { ESM::Weapon::ShortBladeOneHand, ESM::Skill::ShortBlade }, + { ESM::Weapon::LongBladeOneHand, ESM::Skill::LongBlade }, + { ESM::Weapon::LongBladeTwoHand, ESM::Skill::LongBlade }, + { ESM::Weapon::BluntOneHand, ESM::Skill::BluntWeapon }, + { ESM::Weapon::BluntTwoClose, ESM::Skill::BluntWeapon }, + { ESM::Weapon::BluntTwoWide, ESM::Skill::BluntWeapon }, + { ESM::Weapon::SpearTwoWide, ESM::Skill::Spear }, + { ESM::Weapon::AxeOneHand, ESM::Skill::Axe }, + { ESM::Weapon::AxeTwoHand, ESM::Skill::Axe }, + { ESM::Weapon::MarksmanBow, ESM::Skill::Marksman }, + { ESM::Weapon::MarksmanCrossbow, ESM::Skill::Marksman }, + { ESM::Weapon::MarksmanThrown, ESM::Skill::Marksman } + }; + + for (int i=0; ibase->data.type) + return sMapping[i][1]; + + return -1; + } + void Weapon::registerSelf() { boost::shared_ptr instance (new Weapon); @@ -90,7 +146,7 @@ namespace MWClass registerClass (typeid (ESM::Weapon).name(), instance); } - std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr) const + std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -136,7 +192,7 @@ namespace MWClass return std::string("Item Misc Up"); } - std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr) const + std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const { ESMS::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 330dc8d84..b5ccad303 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -31,12 +31,21 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual std::pair, bool> getEquipmentSlots (const MWWorld::Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + + virtual int getEuqipmentSkill (const MWWorld::Ptr& ptr, + const MWWorld::Environment& environment) const; + /// Return the index of the skill this item corresponds to when equiopped or -1, if there is + /// no such skill. + static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 079c888aa..8c657a5c8 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -5,6 +5,8 @@ #include #include "world.hpp" +#include "class.hpp" +#include "containerstore.hpp" MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) { @@ -35,6 +37,39 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) } } +void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore) +{ + for (ESMS::CellRefList::List::iterator iter ( + cellStore.containers.list.begin()); + iter!=cellStore.containers.list.end(); ++iter) + { + Ptr container (&*iter, &cellStore); + + Class::get (container).getContainerStore (container).fill ( + iter->base->inventory, mStore); + } + + for (ESMS::CellRefList::List::iterator iter ( + cellStore.creatures.list.begin()); + iter!=cellStore.creatures.list.end(); ++iter) + { + Ptr container (&*iter, &cellStore); + + Class::get (container).getContainerStore (container).fill ( + iter->base->inventory, mStore); + } + + for (ESMS::CellRefList::List::iterator iter ( + cellStore.npcs.list.begin()); + iter!=cellStore.npcs.list.end(); ++iter) + { + Ptr container (&*iter, &cellStore); + + Class::get (container).getContainerStore (container).fill ( + iter->base->inventory, mStore); + } +} + MWWorld::Cells::Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader, MWWorld::World& world) : mStore (store), mReader (reader), mWorld (world) {} @@ -43,6 +78,8 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) std::map, Ptr::CellStore>::iterator result = mExteriors.find (std::make_pair (x, y)); + bool fill = false; + if (result==mExteriors.end()) { const ESM::Cell *cell = mStore.cells.searchExt (x, y); @@ -63,11 +100,16 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) result = mExteriors.insert (std::make_pair ( std::make_pair (x, y), Ptr::CellStore (cell))).first; + + fill = true; } if (result->second.mState!=Ptr::CellStore::State_Loaded) result->second.load (mStore, mReader); + if (fill) + fillContainers (result->second); + return &result->second; } @@ -75,16 +117,23 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getInterior (const std::string& name) { std::map::iterator result = mInteriors.find (name); + bool fill = false; + if (result==mInteriors.end()) { const ESM::Cell *cell = mStore.cells.findInt (name); result = mInteriors.insert (std::make_pair (name, Ptr::CellStore (cell))).first; + + fill = true; } if (result->second.mState!=Ptr::CellStore::State_Loaded) result->second.load (mStore, mReader); + if (fill) + fillContainers (result->second); + return &result->second; } diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 0ecbd02d3..42aa1050c 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -34,6 +34,8 @@ namespace MWWorld Ptr::CellStore *getCellStore (const ESM::Cell *cell); + void fillContainers (Ptr::CellStore& cellStore); + public: Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader, MWWorld::World& world); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 6dbde367e..884516529 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -77,6 +77,11 @@ namespace MWWorld throw std::runtime_error ("class does not have a container store"); } + InventoryStore& Class::getInventoryStore (const Ptr& ptr) const + { + throw std::runtime_error ("class does not have an inventory store"); + } + void Class::lock (const Ptr& ptr, int lockLevel) const { throw std::runtime_error ("class does not support locking"); @@ -122,6 +127,16 @@ namespace MWWorld return Ogre::Vector3 (0, 0, 0); } + std::pair, bool> Class::getEquipmentSlots (const Ptr& ptr) const + { + return std::make_pair (std::vector(), false); + } + + int Class::getEuqipmentSkill (const Ptr& ptr, const Environment& environment) const + { + return -1; + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); @@ -142,18 +157,13 @@ namespace MWWorld sClasses.insert (std::make_pair (key, instance)); } - std::string Class::getUpSoundId (const Ptr& ptr) const + std::string Class::getUpSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const { throw std::runtime_error ("class does not have an up sound"); } - std::string Class::getDownSoundId (const Ptr& ptr) const + std::string Class::getDownSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const { throw std::runtime_error ("class does not have an down sound"); } - - int Class::getWeightCategory (const MWWorld::Ptr& ptr) - { - throw std::runtime_error ("class does not have an weight"); - } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 3e0a91824..ad0fb8d6d 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -34,6 +35,7 @@ namespace MWWorld class Ptr; class Environment; class ContainerStore; + class InventoryStore; /// \brief Base class for referenceable esm records class Class @@ -108,6 +110,10 @@ namespace MWWorld ///< Return container store or throw an exception, if class does not have a /// container store (default implementation: throw an exceoption) + virtual InventoryStore& getInventoryStore (const Ptr& ptr) const; + ///< Return inventory store or throw an exception, if class does not have a + /// inventory store (default implementation: throw an exceoption) + virtual void lock (const Ptr& ptr, int lockLevel) const; ///< Lock object (default implementation: throw an exception) @@ -137,6 +143,18 @@ namespace MWWorld ///< Return desired movement vector (determined based on movement settings, /// stance and stats). + virtual std::pair, bool> getEquipmentSlots (const Ptr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + /// + /// Default implementation: return (empty vector, false). + + virtual int getEuqipmentSkill (const Ptr& ptr, const Environment& environment) + const; + /// Return the index of the skill this item corresponds to when equiopped or -1, if there is + /// no such skill. + /// (default implementation: return -1) + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. @@ -145,17 +163,13 @@ namespace MWWorld static void registerClass (const std::string& key, boost::shared_ptr instance); - virtual std::string getUpSoundId (const Ptr& ptr) const; + virtual std::string getUpSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const; ///< Return the up sound ID of \a ptr or throw an exception, if class does not support ID retrieval /// (default implementation: throw an exception) - virtual std::string getDownSoundId (const Ptr& ptr) const; + virtual std::string getDownSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const; ///< 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 int getWeightCategory (const MWWorld::Ptr& ptr); - ///< Return the weight category of armors light/medium/heavy - /// (default implementation: throw an exception) }; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 54908deec..c498cabce 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -5,6 +5,12 @@ #include #include +#include + +#include "manualref.hpp" + +MWWorld::ContainerStore::~ContainerStore() {} + MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin (int mask) { return ContainerStoreIterator (mask, this); @@ -17,7 +23,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() void MWWorld::ContainerStore::add (const Ptr& ptr) { - /// \todo implement item stocking + /// \todo implement item stacking switch (getType (ptr)) { @@ -36,6 +42,40 @@ void MWWorld::ContainerStore::add (const Ptr& ptr) } } +void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS::ESMStore& store) +{ + for (std::vector::const_iterator iter (items.list.begin()); iter!=items.list.end(); + ++iter) + { + ManualRef ref (store, iter->item.toString()); + + if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name()) + { + /// \todo implement leveled item lists + continue; + } + + ref.getPtr().getRefData().setCount (iter->count); + add (ref.getPtr()); + } +} + +void MWWorld::ContainerStore::clear() +{ + potions.list.clear(); + appas.list.clear(); + armors.list.clear(); + books.list.clear(); + clothes.list.clear(); + ingreds.list.clear(); + lights.list.clear(); + lockpicks.list.clear(); + miscItems.list.clear(); + probes.list.clear(); + repairs.list.clear(); + weapons.list.clear(); +} + int MWWorld::ContainerStore::getType (const Ptr& ptr) { if (ptr.isEmpty()) @@ -331,6 +371,11 @@ int MWWorld::ContainerStoreIterator::getType() const return mType; } +const MWWorld::ContainerStore *MWWorld::ContainerStoreIterator::getContainerStore() const +{ + return mContainer; +} + bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right) { return left.isEqual (right); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 7263245f3..69e5ba446 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -1,11 +1,18 @@ #ifndef GAME_MWWORLD_CONTAINERSTORE_H #define GAME_MWWORLD_CONTAINERSTORE_H +#include + #include #include "refdata.hpp" #include "ptr.hpp" +namespace ESM +{ + struct InventoryList; +} + namespace MWWorld { class ContainerStoreIterator; @@ -48,6 +55,8 @@ namespace MWWorld public: + virtual ~ContainerStore(); + ContainerStoreIterator begin (int mask = Type_All); ContainerStoreIterator end(); @@ -60,6 +69,12 @@ namespace MWWorld /// \attention Do not add items to an existing stack by increasing the count instead of /// calling this function! + void fill (const ESM::InventoryList& items, const ESMS::ESMStore& store); + ///< Insert items into *this. + + void clear(); + ///< Empty container. + static int getType (const Ptr& ptr); ///< This function throws an exception, if ptr does not point to an object, that can be /// put into a container. @@ -71,6 +86,7 @@ namespace MWWorld /// /// \note The iterator will automatically skip over deleted objects. class ContainerStoreIterator + : public std::iterator { int mType; int mMask; @@ -126,6 +142,8 @@ namespace MWWorld int getType() const; + const ContainerStore *getContainerStore() const; + friend class ContainerStore; }; diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp new file mode 100644 index 000000000..264be7bb3 --- /dev/null +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -0,0 +1,86 @@ + +#include "inventorystore.hpp" + +#include +#include + +#include "class.hpp" + +void MWWorld::InventoryStore::copySlots (const InventoryStore& store) +{ + // some const-trickery, required because of a flaw in the handling of MW-references and the + // resulting workarounds + for (std::vector::const_iterator iter ( + const_cast (store).mSlots.begin()); + iter!=const_cast (store).mSlots.end(); ++iter) + { + std::size_t distance = std::distance (const_cast (store).begin(), *iter); + + ContainerStoreIterator slot = begin(); + + std::advance (slot, distance); + + mSlots.push_back (slot); + } +} + +MWWorld::InventoryStore::InventoryStore() +{ + for (int i=0; i=static_cast (mSlots.size())) + throw std::runtime_error ("slot number out of range"); + + if (iterator.getContainerStore()!=this) + throw std::runtime_error ("attempt to equip an item that is not in the inventory"); + + if (iterator!=end()) + { + std::pair, bool> slots = Class::get (*iterator).getEquipmentSlots (*iterator); + + if (std::find (slots.first.begin(), slots.first.end(), slot)==slots.first.end()) + throw std::runtime_error ("invalid slot"); + } + + /// \todo restack item previously in this slot (if required) + + /// \todo unstack item pointed to by iterator if required) + + mSlots[slot] = iterator; +} + +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) +{ + if (slot<0 || slot>=static_cast (mSlots.size())) + throw std::runtime_error ("slot number out of range"); + + if (mSlots[slot]==end()) + return end(); + + if (mSlots[slot]->getRefData().getCount()<1) + { + // object has been deleted + mSlots[slot] = end(); + return end(); + } + + return mSlots[slot]; +} diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp new file mode 100644 index 000000000..c41f9e8e3 --- /dev/null +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -0,0 +1,58 @@ +#ifndef GAME_MWWORLD_INVENTORYSTORE_H +#define GAME_MWWORLD_INVENTORYSTORE_H + +#include "containerstore.hpp" + +namespace MWWorld +{ + ///< \brief Variant of the ContainerStore for NPCs + class InventoryStore : public ContainerStore + { + public: + + static const int Slot_Helmet = 0; + static const int Slot_Cuirass = 1; + static const int Slot_Greaves = 2; + static const int Slot_LeftPauldron = 3; + static const int Slot_RightPauldron = 4; + static const int Slot_LeftGauntlet = 5; + static const int Slot_RightGauntlet = 6; + static const int Slot_Boots = 7; + static const int Slot_Shirt = 8; + static const int Slot_Pants = 9; + static const int Slot_Skirt = 10; + static const int Slot_Robe = 11; + static const int Slot_LeftRing = 12; + static const int Slot_RightRing = 13; + static const int Slot_Amulet = 14; + static const int Slot_Belt = 15; + static const int Slot_CarriedRight = 16; + static const int Slot_CarriedLeft = 17; + static const int Slot_Ammunition = 18; + + static const int Slots = 19; + + static const int Slot_NoSlot = -1; + + private: + + mutable std::vector mSlots; + + void copySlots (const InventoryStore& store); + + public: + + InventoryStore(); + + InventoryStore (const InventoryStore& store); + + InventoryStore& operator= (const InventoryStore& store); + + void equip (int slot, const ContainerStoreIterator& iterator); + ///< \note \a iteartor can be an end-iterator + + ContainerStoreIterator getSlot (int slot); + }; +} + +#endif diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index eadd4b353..eab1197c5 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -488,7 +488,10 @@ WeatherResult WeatherManager::transition(float factor) void WeatherManager::update(float duration) { mWeatherUpdateTime -= duration; - if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()) + + bool exterior = (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()); + + if (exterior) { std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region; boost::algorithm::to_lower(regionstr); @@ -663,7 +666,7 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->secundaDisable(); } - if (mCurrentWeather == "thunderstorm" && mNextWeather == "") + if (mCurrentWeather == "thunderstorm" && mNextWeather == "" && exterior) { if (mThunderFlash > 0) { @@ -725,6 +728,7 @@ void WeatherManager::update(float duration) // play sounds std::string ambientSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : ""); + if (!exterior) ambientSnd = ""; if (ambientSnd != "") { if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) @@ -735,6 +739,7 @@ void WeatherManager::update(float duration) } std::string rainSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mRainLoopSoundID : ""); + if (!exterior) rainSnd = ""; if (rainSnd != "") { if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end())