From d0543664602cde181979a45494fc64f0f84158d8 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 5 Aug 2013 23:15:26 +0200 Subject: [PATCH 01/10] Permit to force hiding GUI windows --- apps/openmw/mwbase/windowmanager.hpp | 3 +++ apps/openmw/mwgui/windowmanagerimp.cpp | 17 +++++++++++++++-- apps/openmw/mwgui/windowmanagerimp.hpp | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 81ef9ee79..54173ff1b 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -105,6 +105,9 @@ namespace MWBase virtual void toggleVisible (MWGui::GuiWindow wnd) = 0; + virtual void forceHide(MWGui::GuiWindow wnd) = 0; + virtual void unsetForceHide(MWGui::GuiWindow wnd) = 0; + /// Disallow all inventory mode windows virtual void disallowAll() = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 792431038..551f7ad51 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -105,6 +105,7 @@ namespace MWGui , mGui(NULL) , mGarbageDialogs() , mShown(GW_ALL) + , mForceHidden(GW_None) , mAllowed(GW_ALL) , mRestAllowed(true) , mShowFPSLevel(fpsLevel) @@ -435,7 +436,7 @@ namespace MWGui // This is controlled both by what windows the // user has opened/closed (the 'shown' variable) and by what // windows we are allowed to show (the 'allowed' var.) - int eff = mShown & mAllowed; + int eff = mShown & mAllowed & ~mForceHidden; // Show the windows we want mMap ->setVisible(eff & GW_Map); @@ -1117,7 +1118,19 @@ namespace MWGui void WindowManager::toggleVisible (GuiWindow wnd) { - mShown = (mShown & wnd) ? (GuiWindow) (mShown & ~wnd) : (GuiWindow) (mShown | wnd); + mShown = (GuiWindow)(mShown ^ wnd); + updateVisible(); + } + + void WindowManager::forceHide(GuiWindow wnd) + { + mForceHidden = (GuiWindow)(mForceHidden | wnd); + updateVisible(); + } + + void WindowManager::unsetForceHide(GuiWindow wnd) + { + mForceHidden = (GuiWindow)(mForceHidden & ~wnd); updateVisible(); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a178dc621..6adf19333 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -115,6 +115,9 @@ namespace MWGui virtual void toggleVisible(GuiWindow wnd); + virtual void forceHide(MWGui::GuiWindow wnd); + virtual void unsetForceHide(MWGui::GuiWindow wnd); + // Disallow all inventory mode windows virtual void disallowAll(); @@ -334,6 +337,7 @@ namespace MWGui void cleanupGarbage(); GuiWindow mShown; // Currently shown windows in inventory mode + GuiWindow mForceHidden; // Hidden windows (overrides mShown) /* Currently ALLOWED windows in inventory mode. This is used at the start of the game, when windows are enabled one by one From ddc92d1fbd11a3feab435414b75b94170baacaba Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 6 Aug 2013 00:07:24 +0200 Subject: [PATCH 02/10] Set appropriate weapon icon when player is a werewolf --- apps/openmw/mwgui/hud.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index f5cb12e05..9edd49143 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -10,6 +10,7 @@ #include "../mwworld/class.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" #include "inventorywindow.hpp" #include "console.hpp" @@ -477,7 +478,14 @@ namespace MWGui MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0)); mWeapStatus->setProgressRange(100); mWeapStatus->setProgressPosition(0); - mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); + + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); + if (MWWorld::Class::get(player).getNpcStats(player).isWerewolf()) + mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds"); + else + mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); + mWeapBox->clearUserStrings(); } From aa563e947e0d012acc24a15456ae76aaa9ef84d9 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 6 Aug 2013 11:20:51 +0200 Subject: [PATCH 03/10] Implement MWWorld::InventoryStore::unequipAll() --- apps/openmw/mwworld/inventorystore.cpp | 17 +++++++++++++++++ apps/openmw/mwworld/inventorystore.hpp | 3 +++ 2 files changed, 20 insertions(+) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 9d07ecb76..6867c71ce 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -110,6 +110,23 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite flagAsModified(); } +void MWWorld::InventoryStore::unequipAll() +{ + for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) + { + MWWorld::ContainerStoreIterator it = getSlot(slot); + if (it != end()) + { + equip(slot, end()); + std::string script = MWWorld::Class::get(*it).getScript(*it); + + // Unset OnPCEquip Variable on item's script, if it has a script with that variable declared + if(script != "") + (*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 0); + } + } +} + MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) { if (slot<0 || slot>=static_cast (mSlots.size())) diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 0801e04bc..07d5f321e 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -78,6 +78,9 @@ namespace MWWorld ContainerStoreIterator getSlot (int slot); + void unequipAll(); + ///< Unequip all currently equipped items. + void autoEquip (const MWWorld::Ptr& npc); ///< Auto equip items according to stats and item value. From 20d40c4368769b06a3fb4f453c6681e2783951c9 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 5 Aug 2013 23:23:39 +0200 Subject: [PATCH 04/10] Implement MWWorld::World::setWerewolf() --- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwmechanics/npcstats.cpp | 2 ++ apps/openmw/mwworld/worldimp.cpp | 35 ++++++++++++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 4 files changed, 42 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 480bcf9cf..c24215e77 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -384,6 +384,9 @@ namespace MWBase /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const = 0; + + /// Turn actor into werewolf or normal form. + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 50c127856..366e6704c 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -13,7 +13,9 @@ #include #include +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f396157a4..ca38393f0 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -16,6 +16,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/movement.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwrender/sky.hpp" #include "../mwrender/animation.hpp" @@ -1848,4 +1849,38 @@ namespace MWWorld return mTeleportEnabled; } + void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) + { + MWMechanics::NpcStats& npcStats = Class::get(actor).getNpcStats(actor); + + // The actor does not have to change state + if (npcStats.isWerewolf() == werewolf) + return; + + npcStats.setWerewolf(werewolf); + + MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor); + if (werewolf) + invStore.unequipAll(); + else + invStore.autoEquip(actor); + + if (actor.getRefData().getHandle() == "player") + { + // Update the GUI only when called on the player + MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); + if (werewolf) + { + windowManager->forceHide(MWGui::GW_Inventory); + windowManager->forceHide(MWGui::GW_Magic); + windowManager->unsetSelectedWeapon(); + } + else + { + windowManager->unsetForceHide(MWGui::GW_Inventory); + windowManager->unsetForceHide(MWGui::GW_Magic); + } + } + } + } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6d8caad21..1cdf1f5ca 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -428,6 +428,8 @@ namespace MWWorld /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const; + + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); }; } From 5188a1c2cdc78ed8d6a4f2a2284c26427b457cf2 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 5 Aug 2013 23:24:48 +0200 Subject: [PATCH 05/10] Implement script instructions Become/UndoWerewolf --- apps/openmw/mwscript/docs/vmformat.txt | 6 +++++- apps/openmw/mwscript/statsextensions.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 59d988410..06026a22a 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -343,5 +343,9 @@ op 0x2000213: HitOnMe op 0x2000214: HitOnMe, explicit op 0x2000215: DisableTeleporting op 0x2000216: EnableTeleporting +op 0x2000217: BecomeWerewolf +op 0x2000218: BecomeWerewolfExplicit +op 0x2000219: UndoWerewolf +op 0x200021a: UndoWerewolfExplicit -opcodes 0x2000217-0x3ffffff unused +opcodes 0x2000219-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 04e89edc6..5322b1f0c 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1056,6 +1056,18 @@ namespace MWScript } }; + template + class OpSetWerewolf : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + MWBase::Environment::get().getWorld()->setWerewolf(ptr, set); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -1148,6 +1160,10 @@ namespace MWScript const int opcodeOnDeathExplicit = 0x2000205; const int opcodeIsWerewolf = 0x20001fd; const int opcodeIsWerewolfExplicit = 0x20001fe; + const int opcodeBecomeWerewolf = 0x2000217; + const int opcodeBecomeWerewolfExplicit = 0x2000218; + const int opcodeUndoWerewolf = 0x2000219; + const int opcodeUndoWerewolfExplicit = 0x200021a; void registerExtensions (Compiler::Extensions& extensions) { @@ -1266,6 +1282,9 @@ namespace MWScript extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath, opcodeOnDeathExplicit); extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit); + + extensions.registerInstruction("becomewerewolf", "", opcodeBecomeWerewolf, opcodeBecomeWerewolfExplicit); + extensions.registerInstruction("undowerewolf", "", opcodeUndoWerewolf, opcodeBecomeWerewolfExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -1386,6 +1405,11 @@ namespace MWScript interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf); interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf); + + interpreter.installSegment5 (opcodeBecomeWerewolf, new OpSetWerewolf); + interpreter.installSegment5 (opcodeBecomeWerewolfExplicit, new OpSetWerewolf); + interpreter.installSegment5 (opcodeUndoWerewolf, new OpSetWerewolf); + interpreter.installSegment5 (opcodeUndoWerewolfExplicit, new OpSetWerewolf); } } } From c59ad62c57512b6bfc6d31b50910c4ecb4024547 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 6 Aug 2013 14:30:01 +0200 Subject: [PATCH 06/10] Fix UndoWerewolf script instruction --- apps/openmw/mwscript/statsextensions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 5322b1f0c..18d3d0498 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1284,7 +1284,7 @@ namespace MWScript extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit); extensions.registerInstruction("becomewerewolf", "", opcodeBecomeWerewolf, opcodeBecomeWerewolfExplicit); - extensions.registerInstruction("undowerewolf", "", opcodeUndoWerewolf, opcodeBecomeWerewolfExplicit); + extensions.registerInstruction("undowerewolf", "", opcodeUndoWerewolf, opcodeUndoWerewolfExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) From 47b8a31317c8970c6974db50240288cf198655fd Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 6 Aug 2013 14:55:08 +0200 Subject: [PATCH 07/10] Fixes suggested by KittyCat --- apps/openmw/mwworld/inventorystore.cpp | 4 ++-- apps/openmw/mwworld/inventorystore.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 6867c71ce..db45dbf54 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -110,7 +110,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite flagAsModified(); } -void MWWorld::InventoryStore::unequipAll() +void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor) { for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) { @@ -121,7 +121,7 @@ void MWWorld::InventoryStore::unequipAll() std::string script = MWWorld::Class::get(*it).getScript(*it); // Unset OnPCEquip Variable on item's script, if it has a script with that variable declared - if(script != "") + if((actor.getRefData().getHandle() == "player") && (script != "")) (*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 0); } } diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 07d5f321e..713c72955 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -78,7 +78,7 @@ namespace MWWorld ContainerStoreIterator getSlot (int slot); - void unequipAll(); + void unequipAll(const MWWorld::Ptr& actor); ///< Unequip all currently equipped items. void autoEquip (const MWWorld::Ptr& npc); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ca38393f0..93eaebbcc 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1861,9 +1861,7 @@ namespace MWWorld MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor); if (werewolf) - invStore.unequipAll(); - else - invStore.autoEquip(actor); + invStore.unequipAll(actor); if (actor.getRefData().getHandle() == "player") { From fd0a159a64b7af46a1d84bfb3e01d75f912c8f97 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 6 Aug 2013 15:00:38 +0200 Subject: [PATCH 08/10] MWScript: update first unused opcode number --- apps/openmw/mwscript/docs/vmformat.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 06026a22a..005fb82c4 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -348,4 +348,4 @@ op 0x2000218: BecomeWerewolfExplicit op 0x2000219: UndoWerewolf op 0x200021a: UndoWerewolfExplicit -opcodes 0x2000219-0x3ffffff unused +opcodes 0x200021b-0x3ffffff unused From e0d0cdd18a5f5fb08facd4a4c06217379715163b Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 7 Aug 2013 14:30:13 +0200 Subject: [PATCH 09/10] Do not auto-equip items continuously This was called every couple of frames. --- apps/openmw/mwmechanics/actors.cpp | 8 -------- apps/openmw/mwmechanics/actors.hpp | 2 -- 2 files changed, 10 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index fb273c7c1..f639743b9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -36,12 +36,6 @@ namespace MWMechanics } } - void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) - { - if (!paused && ptr.getRefData().getHandle()!="player") - MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip (ptr); - } - void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) { CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature); @@ -231,8 +225,6 @@ namespace MWMechanics iter->second->resurrect(); updateActor(iter->first, totalDuration); - if(iter->first.getTypeName() == typeid(ESM::NPC).name()) - updateNpc(iter->first, totalDuration, paused); if(!stats.isDead()) continue; diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 1369d783c..d74eb5cf5 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -34,8 +34,6 @@ namespace MWMechanics float mDuration; - void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused); - void adjustMagicEffects (const MWWorld::Ptr& creature); void calculateDynamicStats (const MWWorld::Ptr& ptr); From 48d2554ac324e4494ce048a87c7e15dd71abe3f3 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 7 Aug 2013 14:45:23 +0200 Subject: [PATCH 10/10] Auto-equip when items are added to the inventory We limit that to armor pieces and clothing items. No auto-equiping for the player nor werewolves. --- apps/openmw/mwgui/containeritemmodel.cpp | 2 +- apps/openmw/mwgui/inventoryitemmodel.cpp | 2 +- apps/openmw/mwgui/inventorywindow.cpp | 4 ++-- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwmechanics/alchemy.cpp | 2 +- apps/openmw/mwmechanics/enchanting.cpp | 4 ++-- apps/openmw/mwmechanics/repair.cpp | 2 +- apps/openmw/mwscript/containerextensions.cpp | 2 +- apps/openmw/mwscript/miscextensions.cpp | 2 +- apps/openmw/mwworld/actiontake.cpp | 2 +- apps/openmw/mwworld/containerstore.cpp | 4 ++-- apps/openmw/mwworld/containerstore.hpp | 2 +- apps/openmw/mwworld/inventorystore.cpp | 16 ++++++++++++++++ apps/openmw/mwworld/inventorystore.hpp | 11 +++++++++++ 14 files changed, 42 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 5d23744b2..e23b4f77f 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -76,7 +76,7 @@ void ContainerItemModel::copyItem (const ItemStack& item, size_t count) const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1]; int origCount = item.mBase.getRefData().getCount(); item.mBase.getRefData().setCount(count); - MWWorld::ContainerStoreIterator it = MWWorld::Class::get(source).getContainerStore(source).add(item.mBase); + MWWorld::ContainerStoreIterator it = MWWorld::Class::get(source).getContainerStore(source).add(item.mBase, source); if (*it != item.mBase) item.mBase.getRefData().setCount(origCount); else diff --git a/apps/openmw/mwgui/inventoryitemmodel.cpp b/apps/openmw/mwgui/inventoryitemmodel.cpp index c78bc2c00..30269cd9c 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.cpp +++ b/apps/openmw/mwgui/inventoryitemmodel.cpp @@ -42,7 +42,7 @@ void InventoryItemModel::copyItem (const ItemStack& item, size_t count) { int origCount = item.mBase.getRefData().getCount(); item.mBase.getRefData().setCount(count); - MWWorld::ContainerStoreIterator it = MWWorld::Class::get(mActor).getContainerStore(mActor).add(item.mBase); + MWWorld::ContainerStoreIterator it = MWWorld::Class::get(mActor).getContainerStore(mActor).add(item.mBase, mActor); if (*it != item.mBase) item.mBase.getRefData().setCount(origCount); else diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 7ad17fab0..3b848f2e0 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -304,7 +304,7 @@ namespace MWGui int origCount = ptr.getRefData().getCount(); ptr.getRefData().setCount(mDragAndDrop->mDraggedCount); - it = invStore.add(ptr); + it = invStore.add(ptr, mPtr); ptr.getRefData().setCount(origCount); mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount); @@ -481,7 +481,7 @@ namespace MWGui // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object); + MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object, player); // remove from world MWBase::Environment::get().getWorld()->deleteObject (object); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 498fbace8..a073a2899 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -225,7 +225,7 @@ namespace MWGui assert(amount > 0); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001"); ref.getPtr().getRefData().setCount(amount); - playerStore.add(ref.getPtr()); + playerStore.add(ref.getPtr(), player); } } diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 718200372..1d992be41 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -287,7 +287,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) } MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId); - MWWorld::Class::get (mAlchemist).getContainerStore (mAlchemist).add (ref.getPtr()); + MWWorld::Class::get (mAlchemist).getContainerStore (mAlchemist).add (ref.getPtr(), mAlchemist); } void MWMechanics::Alchemy::increaseSkill() diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index e1b416efb..4e26b5027 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -65,7 +65,7 @@ namespace MWMechanics if(boost::iequals(mSoulGemPtr.get()->mBase->mId, "Misc_SoulGem_Azura")) { MWWorld::ManualRef azura (MWBase::Environment::get().getWorld()->getStore(), "Misc_SoulGem_Azura"); - MWWorld::Class::get (player).getContainerStore (player).add (azura.getPtr()); + MWWorld::Class::get (player).getContainerStore (player).add (azura.getPtr(), player); } if(mSelfEnchanting) @@ -93,7 +93,7 @@ namespace MWMechanics MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), mOldItemId); ref.getPtr().getRefData().setCount (mOldItemCount-1); - MWWorld::Class::get (player).getContainerStore (player).add (ref.getPtr()); + MWWorld::Class::get (player).getContainerStore (player).add (ref.getPtr(), player); if(!mSelfEnchanting) payForEnchantment(); diff --git a/apps/openmw/mwmechanics/repair.cpp b/apps/openmw/mwmechanics/repair.cpp index 8ed449885..66c492bf8 100644 --- a/apps/openmw/mwmechanics/repair.cpp +++ b/apps/openmw/mwmechanics/repair.cpp @@ -32,7 +32,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair) if (mTool.getRefData().getCount() > 1 && uses == ref->mBase->mData.mUses) { MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); - MWWorld::ContainerStoreIterator it = store.add(mTool); + MWWorld::ContainerStoreIterator it = store.add(mTool, player); it->getRefData().setCount(mTool.getRefData().getCount()-1); it->getCellRef().mCharge = -1; diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 3a46f62d6..c1efc55eb 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -64,7 +64,7 @@ namespace MWScript ref.getPtr().getRefData().setLocals(*esmscript); } - MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr()); + MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr(), ptr); // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer() ) diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 6b1adc938..b16d6e0a9 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -346,7 +346,7 @@ namespace MWScript ref.getPtr().getCellRef().mSoul = creature; - MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr()); + MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr(), ptr); } }; diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index cdd19b46e..d3c4aa2f6 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -17,7 +17,7 @@ namespace MWWorld // insert into player's inventory MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPtr ("player", true); - MWWorld::Class::get (player).getContainerStore (player).add (getTarget()); + MWWorld::Class::get (player).getContainerStore (player).add (getTarget(), player); MWBase::Environment::get().getWorld()->deleteObject (getTarget()); } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index a9d57c128..cd30f1ac0 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -74,9 +74,9 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) return false; } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, const Ptr& actorPtr) { - MWWorld::ContainerStoreIterator it = addImp(ptr); + MWWorld::ContainerStoreIterator it = addImp(itemPtr); MWWorld::Ptr item = *it; std::string script = MWWorld::Class::get(item).getScript(item); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 559463d46..bdf6d28e4 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -65,7 +65,7 @@ namespace MWWorld ContainerStoreIterator end(); - ContainerStoreIterator add (const Ptr& ptr); + virtual ContainerStoreIterator add (const Ptr& itemPtr, const Ptr& actorPtr); ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// /// \note The item pointed to is not required to exist beyond this function call. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index db45dbf54..e737ab827 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -64,6 +64,22 @@ MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStor return *this; } +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, const Ptr& actorPtr) +{ + const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, actorPtr); + + // Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves + if ((actorPtr.getRefData().getHandle() != "player") + && !(MWWorld::Class::get(actorPtr).getNpcStats(actorPtr).isWerewolf())) + { + std::string type = itemPtr.getTypeName(); + if ((type == typeid(ESM::Armor).name()) || (type == typeid(ESM::Clothing).name())) + autoEquip(actorPtr); + } + + return retVal; +} + void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& iterator) { if (slot<0 || slot>=static_cast (mSlots.size())) diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 713c72955..f0cba0f9f 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -65,6 +65,17 @@ namespace MWWorld InventoryStore& operator= (const InventoryStore& store); + virtual ContainerStoreIterator add (const Ptr& itemPtr, const Ptr& actorPtr); + ///< 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). + /// + /// \note The item pointed to is not required to exist beyond this function call. + /// + /// \attention Do not add items to an existing stack by increasing the count instead of + /// calling this function! + /// + /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item. + void equip (int slot, const ContainerStoreIterator& iterator); ///< \note \a iterator can be an end-iterator