mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:26:40 +00:00 
			
		
		
		
	Issue #777: Create InventoryStore for creatures with weapons/shields
This commit is contained in:
		
							parent
							
								
									69ca03c308
								
							
						
					
					
						commit
						589fbbd871
					
				
					 23 changed files with 111 additions and 62 deletions
				
			
		| 
						 | 
					@ -289,7 +289,7 @@ namespace MWClass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
 | 
					    std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(npc).getInventoryStore(npc);
 | 
					        MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (ptr.getCellRef().mCharge == 0)
 | 
					        if (ptr.getCellRef().mCharge == 0)
 | 
				
			||||||
            return std::make_pair(0, "#{sInventoryMessage1}");
 | 
					            return std::make_pair(0, "#{sInventoryMessage1}");
 | 
				
			||||||
| 
						 | 
					@ -300,6 +300,8 @@ namespace MWClass
 | 
				
			||||||
        if (slots_.first.empty())
 | 
					        if (slots_.first.empty())
 | 
				
			||||||
            return std::make_pair(0, "");
 | 
					            return std::make_pair(0, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (npc.getClass().isNpc())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            std::string npcRace = npc.get<ESM::NPC>()->mBase->mRace;
 | 
					            std::string npcRace = npc.get<ESM::NPC>()->mBase->mRace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Beast races cannot equip shoes / boots, or full helms (head part vs hair part)
 | 
					            // Beast races cannot equip shoes / boots, or full helms (head part vs hair part)
 | 
				
			||||||
| 
						 | 
					@ -316,6 +318,7 @@ namespace MWClass
 | 
				
			||||||
                        return std::make_pair(0, "#{sNotifyMessage14}");
 | 
					                        return std::make_pair(0, "#{sNotifyMessage14}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (std::vector<int>::const_iterator slot=slots_.first.begin();
 | 
					        for (std::vector<int>::const_iterator slot=slots_.first.begin();
 | 
				
			||||||
            slot!=slots_.first.end(); ++slot)
 | 
					            slot!=slots_.first.end(); ++slot)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,6 +238,8 @@ namespace MWClass
 | 
				
			||||||
        if (slots_.first.empty())
 | 
					        if (slots_.first.empty())
 | 
				
			||||||
            return std::make_pair(0, "");
 | 
					            return std::make_pair(0, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (npc.getClass().isNpc())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            std::string npcRace = npc.get<ESM::NPC>()->mBase->mRace;
 | 
					            std::string npcRace = npc.get<ESM::NPC>()->mBase->mRace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Beast races cannot equip shoes / boots, or full helms (head part vs hair part)
 | 
					            // Beast races cannot equip shoes / boots, or full helms (head part vs hair part)
 | 
				
			||||||
| 
						 | 
					@ -254,6 +256,7 @@ namespace MWClass
 | 
				
			||||||
                        return std::make_pair(0, "#{sNotifyMessage15}");
 | 
					                        return std::make_pair(0, "#{sNotifyMessage15}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return std::make_pair (1, "");
 | 
					        return std::make_pair (1, "");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwgui/tooltips.hpp"
 | 
					#include "../mwgui/tooltips.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../mwworld/inventorystore.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwmechanics/npcstats.hpp"
 | 
					#include "../mwmechanics/npcstats.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
| 
						 | 
					@ -33,15 +35,20 @@ namespace
 | 
				
			||||||
    struct CustomData : public MWWorld::CustomData
 | 
					    struct CustomData : public MWWorld::CustomData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWMechanics::CreatureStats mCreatureStats;
 | 
					        MWMechanics::CreatureStats mCreatureStats;
 | 
				
			||||||
        MWWorld::ContainerStore mContainerStore;
 | 
					        MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures
 | 
				
			||||||
        MWMechanics::Movement mMovement;
 | 
					        MWMechanics::Movement mMovement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual MWWorld::CustomData *clone() const;
 | 
					        virtual MWWorld::CustomData *clone() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CustomData() : mContainerStore(0) {}
 | 
				
			||||||
 | 
					        virtual ~CustomData() { delete mContainerStore; }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWWorld::CustomData *CustomData::clone() const
 | 
					    MWWorld::CustomData *CustomData::clone() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return new CustomData (*this);
 | 
					        CustomData* cloned = new CustomData (*this);
 | 
				
			||||||
 | 
					        cloned->mContainerStore = mContainerStore->clone();
 | 
				
			||||||
 | 
					        return cloned;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,15 +113,23 @@ namespace MWClass
 | 
				
			||||||
                data->mCreatureStats.getSpells().add (*iter);
 | 
					                data->mCreatureStats.getSpells().add (*iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // inventory
 | 
					            // inventory
 | 
				
			||||||
            data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), "",
 | 
					            if (ref->mBase->mFlags & ESM::Creature::Weapon)
 | 
				
			||||||
 | 
					                data->mContainerStore = new MWWorld::InventoryStore();
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                data->mContainerStore = new MWWorld::ContainerStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // store
 | 
				
			||||||
 | 
					            ptr.getRefData().setCustomData (data.release());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "",
 | 
				
			||||||
                                       MWBase::Environment::get().getWorld()->getStore());
 | 
					                                       MWBase::Environment::get().getWorld()->getStore());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
 | 
					            // TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
 | 
				
			||||||
            // (except for gold you gave him)
 | 
					            // (except for gold you gave him)
 | 
				
			||||||
            data->mContainerStore.add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr);
 | 
					            getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // store
 | 
					            if (ref->mBase->mFlags & ESM::Creature::Weapon)
 | 
				
			||||||
            ptr.getRefData().setCustomData (data.release());
 | 
					                getInventoryStore(ptr).autoEquip(ptr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -325,18 +340,33 @@ namespace MWClass
 | 
				
			||||||
        return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
 | 
					        return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr)
 | 
					    MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr) const
 | 
				
			||||||
        const
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ensureCustomData (ptr);
 | 
					        ensureCustomData (ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
 | 
					        return *dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ref->mBase->mFlags & ESM::Creature::Weapon)
 | 
				
			||||||
 | 
					            return dynamic_cast<MWWorld::InventoryStore&>(getContainerStore(ptr));
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            throw std::runtime_error("this creature has no inventory store");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool Creature::hasInventoryStore(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (ref->mBase->mFlags & ESM::Creature::Weapon);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string Creature::getScript (const MWWorld::Ptr& ptr) const
 | 
					    std::string Creature::getScript (const MWWorld::Ptr& ptr) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::LiveCellRef<ESM::Creature> *ref =
 | 
					        MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
 | 
				
			||||||
            ptr.get<ESM::Creature>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return ref->mBase->mScript;
 | 
					        return ref->mBase->mScript;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,11 @@ namespace MWClass
 | 
				
			||||||
                const MWWorld::Ptr& ptr) const;
 | 
					                const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
            ///< Return container store
 | 
					            ///< Return container store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
 | 
					            ///< Return inventory store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual bool hasInventoryStore (const MWWorld::Ptr &ptr) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual std::string getScript (const MWWorld::Ptr& ptr) const;
 | 
					            virtual std::string getScript (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
            ///< Return name of the script attached to ptr
 | 
					            ///< Return name of the script attached to ptr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,8 @@ namespace MWClass
 | 
				
			||||||
            virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
 | 
					            virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const;
 | 
				
			||||||
            ///< Return inventory store
 | 
					            ///< Return inventory store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual bool hasInventoryStore(const MWWorld::Ptr &ptr) const { return true; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void hit(const MWWorld::Ptr& ptr, int type) const;
 | 
					            virtual void hit(const MWWorld::Ptr& ptr, int type) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const;
 | 
					            virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -420,7 +420,7 @@ namespace MWDialogue
 | 
				
			||||||
        MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
 | 
					        MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Apply disposition change to NPC's base disposition
 | 
					        // Apply disposition change to NPC's base disposition
 | 
				
			||||||
        if (mActor.getTypeName() == typeid(ESM::NPC).name())
 | 
					        if (mActor.getClass().isNpc())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
					            MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
				
			||||||
            npcStats.setBaseDisposition(npcStats.getBaseDisposition() + mPermanentDispositionChange);
 | 
					            npcStats.setBaseDisposition(npcStats.getBaseDisposition() + mPermanentDispositionChange);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CompanionItemModel::copyItem (const ItemStack& item, size_t count)
 | 
					    void CompanionItemModel::copyItem (const ItemStack& item, size_t count)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mActor.getTypeName() == typeid(ESM::NPC).name())
 | 
					        if (mActor.getClass().isNpc())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
					            MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
				
			||||||
            stats.modifyProfit(MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
 | 
					            stats.modifyProfit(MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
 | 
					    void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mActor.getTypeName() == typeid(ESM::NPC).name())
 | 
					        if (mActor.getClass().isNpc())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
					            MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
 | 
				
			||||||
            stats.modifyProfit(-MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
 | 
					            stats.modifyProfit(-MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,9 +74,9 @@ void InventoryItemModel::update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ItemStack newItem (item, this, item.getRefData().getCount());
 | 
					        ItemStack newItem (item, this, item.getRefData().getCount());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mActor.getTypeName() == typeid(ESM::NPC).name())
 | 
					        if (mActor.getClass().hasInventoryStore(mActor))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MWWorld::InventoryStore& store = MWWorld::Class::get(mActor).getInventoryStore(mActor);
 | 
					            MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
 | 
				
			||||||
            for (int slot=0; slot<MWWorld::InventoryStore::Slots; ++slot)
 | 
					            for (int slot=0; slot<MWWorld::InventoryStore::Slots; ++slot)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MWWorld::ContainerStoreIterator equipped = store.getSlot(slot);
 | 
					                MWWorld::ContainerStoreIterator equipped = store.getSlot(slot);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@ namespace MWGui
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // don't show equipped items
 | 
					                // don't show equipped items
 | 
				
			||||||
                if(mMerchant.getTypeName() == typeid(ESM::NPC).name())
 | 
					                if(mMerchant.getClass().hasInventoryStore(mMerchant))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    bool isEquipped = false;
 | 
					                    bool isEquipped = false;
 | 
				
			||||||
                    MWWorld::InventoryStore& store = MWWorld::Class::get(mMerchant).getInventoryStore(mMerchant);
 | 
					                    MWWorld::InventoryStore& store = MWWorld::Class::get(mMerchant).getInventoryStore(mMerchant);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,6 @@
 | 
				
			||||||
#include "../mwworld/containerstore.hpp"
 | 
					#include "../mwworld/containerstore.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwmechanics/creaturestats.hpp"
 | 
					#include "../mwmechanics/creaturestats.hpp"
 | 
				
			||||||
#include "../mwmechanics/npcstats.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "inventorywindow.hpp"
 | 
					#include "inventorywindow.hpp"
 | 
				
			||||||
#include "itemview.hpp"
 | 
					#include "itemview.hpp"
 | 
				
			||||||
| 
						 | 
					@ -293,8 +292,8 @@ namespace MWGui
 | 
				
			||||||
            float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
 | 
					            float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
 | 
				
			||||||
                + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
 | 
					                + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
 | 
					            const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
 | 
				
			||||||
            const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
 | 
					            const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100);
 | 
					            float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100);
 | 
				
			||||||
            float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
					            float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,8 +47,7 @@ void adjustBoundItem (const std::string& item, bool bound, const MWWorld::Ptr& a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
 | 
					bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // TODO: remove this check once creatures support inventory store
 | 
					    if (ptr.getClass().hasInventoryStore(ptr))
 | 
				
			||||||
    if (ptr.getTypeName() == typeid(ESM::NPC).name())
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
 | 
					        MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
 | 
				
			||||||
        MWWorld::ContainerStoreIterator item =
 | 
					        MWWorld::ContainerStoreIterator item =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,8 +196,8 @@ namespace MWMechanics
 | 
				
			||||||
            creatureStats.setDynamic (i, stat);
 | 
					            creatureStats.setDynamic (i, stat);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // auto-equip again. we need this for when the race is changed to a beast race
 | 
					        // auto-equip again. we need this for when the race is changed to a beast race and shoes are no longer equippable
 | 
				
			||||||
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
 | 
					        MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
 | 
				
			||||||
        for (int i=0; i<MWWorld::InventoryStore::Slots; ++i)
 | 
					        for (int i=0; i<MWWorld::InventoryStore::Slots; ++i)
 | 
				
			||||||
            invStore.unequipAll(ptr);
 | 
					            invStore.unequipAll(ptr);
 | 
				
			||||||
        invStore.autoEquip(ptr);
 | 
					        invStore.autoEquip(ptr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,9 +75,6 @@ void Actors::insertNPC(const MWWorld::Ptr& ptr)
 | 
				
			||||||
    delete mAllActors[ptr];
 | 
					    delete mAllActors[ptr];
 | 
				
			||||||
    mAllActors[ptr] = anim;
 | 
					    mAllActors[ptr] = anim;
 | 
				
			||||||
    mRendering->addWaterRippleEmitter (ptr);
 | 
					    mRendering->addWaterRippleEmitter (ptr);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Create CustomData, will do autoEquip and trigger animation parts update
 | 
					 | 
				
			||||||
    ptr.getClass().getInventoryStore(ptr);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Actors::insertCreature (const MWWorld::Ptr& ptr)
 | 
					void Actors::insertCreature (const MWWorld::Ptr& ptr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +142,7 @@ namespace MWRender
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mAnimation->updateParts();
 | 
					        mAnimation->updateParts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter);
 | 
					        MWWorld::InventoryStore &inv = mCharacter.getClass().getInventoryStore(mCharacter);
 | 
				
			||||||
        MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
 | 
					        MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
 | 
				
			||||||
        std::string groupname;
 | 
					        std::string groupname;
 | 
				
			||||||
        if(iter == inv.end())
 | 
					        if(iter == inv.end())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -892,8 +892,6 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
 | 
				
			||||||
        mPlayerAnimation->~NpcAnimation();
 | 
					        mPlayerAnimation->~NpcAnimation();
 | 
				
			||||||
        new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(), RV_Actors);
 | 
					        new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(), RV_Actors);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Ensure CustomData -> autoEquip -> animation update
 | 
					 | 
				
			||||||
    ptr.getClass().getInventoryStore(ptr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mCamera->setAnimation(mPlayerAnimation);
 | 
					    mCamera->setAnimation(mPlayerAnimation);
 | 
				
			||||||
    mWater->removeEmitter(ptr);
 | 
					    mWater->removeEmitter(ptr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,7 +159,7 @@ namespace MWScript
 | 
				
			||||||
                    std::string item = runtime.getStringLiteral (runtime[0].mInteger);
 | 
					                    std::string item = runtime.getStringLiteral (runtime[0].mInteger);
 | 
				
			||||||
                    runtime.pop();
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
 | 
					                    MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr);
 | 
				
			||||||
                    MWWorld::ContainerStoreIterator it = invStore.begin();
 | 
					                    MWWorld::ContainerStoreIterator it = invStore.begin();
 | 
				
			||||||
                    for (; it != invStore.end(); ++it)
 | 
					                    for (; it != invStore.end(); ++it)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,9 +19,9 @@ namespace MWWorld
 | 
				
			||||||
    void ActionEquip::executeImp (const Ptr& actor)
 | 
					    void ActionEquip::executeImp (const Ptr& actor)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::Ptr object = getTarget();
 | 
					        MWWorld::Ptr object = getTarget();
 | 
				
			||||||
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor);
 | 
					        MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::pair <int, std::string> result = MWWorld::Class::get (object).canBeEquipped (object, actor);
 | 
					        std::pair <int, std::string> result = object.getClass().canBeEquipped (object, actor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // display error message if the player tried to equip something
 | 
					        // display error message if the player tried to equip something
 | 
				
			||||||
        if (!result.second.empty() && actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
 | 
					        if (!result.second.empty() && actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,11 @@ namespace MWWorld
 | 
				
			||||||
        throw std::runtime_error ("class does not have an inventory store");
 | 
					        throw std::runtime_error ("class does not have an inventory store");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool Class::hasInventoryStore(const Ptr &ptr) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Class::lock (const Ptr& ptr, int lockLevel) const
 | 
					    void Class::lock (const Ptr& ptr, int lockLevel) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        throw std::runtime_error ("class does not support locking");
 | 
					        throw std::runtime_error ("class does not support locking");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,9 @@ namespace MWWorld
 | 
				
			||||||
            ///< Return inventory store or throw an exception, if class does not have a
 | 
					            ///< Return inventory store or throw an exception, if class does not have a
 | 
				
			||||||
            /// inventory store (default implementation: throw an exceoption)
 | 
					            /// inventory store (default implementation: throw an exceoption)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual bool hasInventoryStore (const Ptr& ptr) const;
 | 
				
			||||||
 | 
					            ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual void lock (const Ptr& ptr, int lockLevel) const;
 | 
					            virtual void lock (const Ptr& ptr, int lockLevel) const;
 | 
				
			||||||
            ///< Lock object (default implementation: throw an exception)
 | 
					            ///< Lock object (default implementation: throw an exception)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,8 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual ~ContainerStore();
 | 
					            virtual ~ContainerStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual ContainerStore* clone() { return new ContainerStore(*this); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ContainerStoreIterator begin (int mask = Type_All);
 | 
					            ContainerStoreIterator begin (int mask = Type_All);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ContainerStoreIterator end();
 | 
					            ContainerStoreIterator end();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves
 | 
					    // Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves
 | 
				
			||||||
    if ((actorPtr.getRefData().getHandle() != "player")
 | 
					    if ((actorPtr.getRefData().getHandle() != "player")
 | 
				
			||||||
            && !(MWWorld::Class::get(actorPtr).getNpcStats(actorPtr).isWerewolf())
 | 
					            && !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf())
 | 
				
			||||||
            && !actorPtr.getClass().getCreatureStats(actorPtr).isDead())
 | 
					            && !actorPtr.getClass().getCreatureStats(actorPtr).isDead())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::string type = itemPtr.getTypeName();
 | 
					        std::string type = itemPtr.getTypeName();
 | 
				
			||||||
| 
						 | 
					@ -457,7 +457,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
 | 
				
			||||||
    // If an armor/clothing item is removed, try to find a replacement,
 | 
					    // If an armor/clothing item is removed, try to find a replacement,
 | 
				
			||||||
    // but not for the player nor werewolves.
 | 
					    // but not for the player nor werewolves.
 | 
				
			||||||
    if ((actor.getRefData().getHandle() != "player")
 | 
					    if ((actor.getRefData().getHandle() != "player")
 | 
				
			||||||
            && !(MWWorld::Class::get(actor).getNpcStats(actor).isWerewolf()))
 | 
					            && !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::string type = item.getTypeName();
 | 
					        std::string type = item.getTypeName();
 | 
				
			||||||
        if (((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()))
 | 
					        if (((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name()))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,6 +113,8 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            InventoryStore& operator= (const InventoryStore& store);
 | 
					            InventoryStore& operator= (const InventoryStore& store);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            virtual InventoryStore* clone() { return new InventoryStore(*this); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool setOwner=false);
 | 
					            virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool setOwner=false);
 | 
				
			||||||
            ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
 | 
					            ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
 | 
				
			||||||
            /// Auto-equip items if specific conditions are fulfilled (see the implementation).
 | 
					            /// Auto-equip items if specific conditions are fulfilled (see the implementation).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2097,7 +2097,6 @@ namespace MWWorld
 | 
				
			||||||
    void World::castSpell(const Ptr &actor)
 | 
					    void World::castSpell(const Ptr &actor)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
 | 
					        MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
 | 
				
			||||||
        InventoryStore& inv = actor.getClass().getInventoryStore(actor);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MWWorld::Ptr target = getFacedObject();
 | 
					        MWWorld::Ptr target = getFacedObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2111,8 +2110,10 @@ namespace MWWorld
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cast.cast(spell);
 | 
					            cast.cast(spell);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (inv.getSelectedEnchantItem() != inv.end())
 | 
					        else if (actor.getClass().hasInventoryStore(actor))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor);
 | 
				
			||||||
 | 
					            if (inv.getSelectedEnchantItem() != inv.end())
 | 
				
			||||||
                cast.cast(*inv.getSelectedEnchantItem());
 | 
					                cast.cast(*inv.getSelectedEnchantItem());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2282,7 +2283,7 @@ namespace MWWorld
 | 
				
			||||||
    void World::breakInvisibility(const Ptr &actor)
 | 
					    void World::breakInvisibility(const Ptr &actor)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility);
 | 
					        actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility);
 | 
				
			||||||
        if (actor.getClass().isNpc())
 | 
					        if (actor.getClass().hasInventoryStore(actor))
 | 
				
			||||||
            actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility);
 | 
					            actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue