From c4aae96d94e1a1dab397095f17e9b4f110b2451e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 11 May 2012 07:18:41 +0200 Subject: [PATCH 1/7] implemented "goodbye" script function that force-cancels dialogue --- apps/openmw/mwdialogue/dialoguemanager.cpp | 7 +++++++ apps/openmw/mwdialogue/dialoguemanager.hpp | 2 ++ apps/openmw/mwgui/dialogue.cpp | 17 +++++++++++++++++ apps/openmw/mwgui/dialogue.hpp | 3 +++ apps/openmw/mwscript/dialogueextensions.cpp | 13 +++++++++++++ apps/openmw/mwscript/docs/vmformat.txt | 3 ++- 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 282fba3543..7baf589c44 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -883,4 +883,11 @@ namespace MWDialogue } return factionID; } + + void DialogueManager::goodbye() + { + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + + win->goodbye(); + } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index a3e37987db..992175c0cf 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -56,6 +56,8 @@ namespace MWDialogue void askQuestion(std::string question,int choice); + void goodbye(); + ///get the faction of the actor you are talking with std::string getFaction(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 2e74290555..45163017a6 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -39,6 +39,7 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su DialogueWindow::DialogueWindow(WindowManager& parWindowManager) : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) + , mEnabled(true) { // Centre dialog center(); @@ -64,6 +65,7 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager) MyGUI::ButtonPtr byeButton; getWidget(byeButton, "ByeButton"); byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); + byeButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str); getWidget(pDispositionBar, "Disposition"); getWidget(pDispositionText,"DispositionText"); @@ -81,6 +83,10 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) size_t cursorPosition = t->getCursorPosition(lastPressed); MyGUI::UString color = history->getColorAtPos(cursorPosition); + + if (!mEnabled && color == "#572D21") + MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); + if(color != "#B29154") { UString key = history->getColorTextAt(cursorPosition); @@ -119,11 +125,15 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) void DialogueWindow::onSelectTopic(std::string topic) { + if (!mEnabled) return; + MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } void DialogueWindow::startDialogue(std::string npcName) { + mEnabled = true; + topicsList->setEnabled(true); static_cast(mMainWidget)->setCaption(npcName); adjustWindowCaption(); } @@ -224,3 +234,10 @@ void DialogueWindow::updateOptions() pDispositionText->eraseText(0,pDispositionText->getTextLength()); pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154"); } + +void DialogueWindow::goodbye() +{ + history->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str); + topicsList->setEnabled(false); + mEnabled = false; +} diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index a8fed7d31e..a29e737997 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -45,6 +45,7 @@ namespace MWGui void addText(std::string text); void addTitle(std::string text); void askQuestion(std::string question); + void goodbye(); protected: void onSelectTopic(std::string topic); @@ -60,6 +61,8 @@ namespace MWGui */ std::string parseText(std::string text); + bool mEnabled; + DialogueHistory* history; Widgets::MWList* topicsList; MyGUI::ProgressPtr pDispositionBar; diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index b99d55999c..ec8ab59b41 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -115,6 +115,16 @@ namespace MWScript } }; + class OpGoodbye : public Interpreter::Opcode0 + { + public: + + virtual void execute(Interpreter::Runtime& runtime) + { + MWBase::Environment::get().getDialogueManager()->goodbye(); + } + }; + const int opcodeJournal = 0x2000133; const int opcodeSetJournalIndex = 0x2000134; const int opcodeGetJournalIndex = 0x2000135; @@ -122,6 +132,7 @@ namespace MWScript const int opcodeChoice = 0x2000a; const int opcodeForceGreeting = 0x200014f; const int opcodeForceGreetingExplicit = 0x2000150; + const int opcodeGoodbye = 0x2000152; void registerExtensions (Compiler::Extensions& extensions) { @@ -133,6 +144,7 @@ namespace MWScript extensions.registerInstruction("forcegreeting","",opcodeForceGreeting); extensions.registerInstruction("forcegreeting","",opcodeForceGreeting, opcodeForceGreetingExplicit); + extensions.registerInstruction("goodbye", "", opcodeGoodbye); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -144,6 +156,7 @@ namespace MWScript interpreter.installSegment3 (opcodeChoice,new OpChoice); interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting); interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting); + interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye); } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 378b2412a5..0920c72f8e 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -145,4 +145,5 @@ op 0x200014e: ModDisposition, explicit reference op 0x200014f: ForceGreeting op 0x2000150: ForceGreeting, explicit reference op 0x2000151: ToggleFullHelp -opcodes 0x2000152-0x3ffffff unused +op 0x2000152: Goodbye +opcodes 0x2000153-0x3ffffff unused From d9e39bd90e742fa17707a9202e58d486660af4e5 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 11 May 2012 21:32:38 +0200 Subject: [PATCH 2/7] Changed order of plugins.cfg file paths. Changed order of plugins.cfg file paths - before when plugins.cfg file was found in global path then it was used as default one. Now the behavoiur is opposite if plugins.cfg file exists in local path then it is used as default one. --- components/files/configurationmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index ef45b6543e..d5f322ebd4 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -28,10 +28,10 @@ ConfigurationManager::ConfigurationManager() { setupTokensMapping(); - mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile; + mPluginsCfgPath = mFixedPath.getLocalPath() / pluginsCfgFile; if (!boost::filesystem::is_regular_file(mPluginsCfgPath)) { - mPluginsCfgPath = mFixedPath.getLocalPath() / pluginsCfgFile; + mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile; if (!boost::filesystem::is_regular_file(mPluginsCfgPath)) { std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl; From 5b0251b09f1123874b5af665aa44eae5e452489c Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 May 2012 16:17:03 +0200 Subject: [PATCH 3/7] item stacking --- apps/openmw/mwclass/armor.cpp | 8 ++++++++ apps/openmw/mwclass/armor.hpp | 3 +++ apps/openmw/mwclass/clothing.cpp | 8 ++++++++ apps/openmw/mwclass/clothing.hpp | 3 +++ apps/openmw/mwclass/weapon.cpp | 8 ++++++++ apps/openmw/mwclass/weapon.hpp | 3 +++ apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 6 +++++- apps/openmw/mwworld/containerstore.cpp | 18 +++++++++++++++++- 9 files changed, 60 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index fb34e4c883..87a5dde27a 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -248,4 +248,12 @@ namespace MWClass return info; } + + std::string Armor::getEnchantment (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->enchant; + } } diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index c757587e5e..3ff101a5e5 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -55,6 +55,9 @@ namespace MWClass virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id + + virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string }; } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 620b664cc4..a242874df3 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -201,4 +201,12 @@ namespace MWClass return info; } + + std::string Clothing::getEnchantment (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->enchant; + } } diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index afb1849995..9b9322969a 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -49,6 +49,9 @@ namespace MWClass virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id + + virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string }; } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index fcfaebcb7a..0ddf19d3cc 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -339,4 +339,12 @@ namespace MWClass return info; } + + std::string Weapon::getEnchantment (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->enchant; + } } diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 9c5f43bd3f..c27a39620d 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -55,6 +55,9 @@ namespace MWClass virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id + + virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string }; } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 78ed5ca2e5..151d913bed 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -181,4 +181,9 @@ namespace MWWorld { return false; } + + std::string Class::getEnchantment (const Ptr& ptr) const + { + return ""; + } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index e69b8f2ac9..d7a2d2d759 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -136,7 +136,7 @@ namespace MWWorld ///< Set or unset a stance. virtual bool getStance (const Ptr& ptr, Stance stance, bool ignoreForce = false) const; - ////< Check if a stance is active or not. + ///< Check if a stance is active or not. virtual float getSpeed (const Ptr& ptr) const; ///< Return movement speed. @@ -179,6 +179,10 @@ namespace MWWorld virtual std::string getDownSoundId (const Ptr& ptr) 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 std::string getEnchantment (const MWWorld::Ptr& ptr) const; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + /// (default implementation: return empty string) }; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 2800b6f3c1..4f799f5766 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -9,6 +9,7 @@ #include "manualref.hpp" #include "refdata.hpp" +#include "class.hpp" namespace { @@ -46,7 +47,22 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() void MWWorld::ContainerStore::add (const Ptr& ptr) { - /// \todo implement item stacking + // determine whether to stack or not + // item stacking depends on owner, script, enchantment and name + for (MWWorld::ContainerStoreIterator iter (begin(getType(ptr))); iter!=end(); ++iter) + { + if ( iter->mCellRef->refID == ptr.mCellRef->refID + && MWWorld::Class::get(*iter).getScript(*iter) == MWWorld::Class::get(ptr).getScript(ptr) + && MWWorld::Class::get(*iter).getEnchantment(*iter) == MWWorld::Class::get(ptr).getEnchantment(ptr) + && iter->mCellRef->owner == ptr.mCellRef->owner) + { + // stack + iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() ); + + flagAsModified(); + return; + } + } switch (getType (ptr)) { From 9f2595183b039a29f3c79788a4048063041521d9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 May 2012 16:30:27 +0200 Subject: [PATCH 4/7] type --- apps/openmw/mwworld/containerstore.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 4f799f5766..32e2da0ae1 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -47,9 +47,11 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() void MWWorld::ContainerStore::add (const Ptr& ptr) { + int type = getType(ptr); + // determine whether to stack or not // item stacking depends on owner, script, enchantment and name - for (MWWorld::ContainerStoreIterator iter (begin(getType(ptr))); iter!=end(); ++iter) + for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) { if ( iter->mCellRef->refID == ptr.mCellRef->refID && MWWorld::Class::get(*iter).getScript(*iter) == MWWorld::Class::get(ptr).getScript(ptr) @@ -64,7 +66,7 @@ void MWWorld::ContainerStore::add (const Ptr& ptr) } } - switch (getType (ptr)) + switch (type) { case Type_Potion: potions.list.push_back (*ptr.get()); break; case Type_Apparatus: appas.list.push_back (*ptr.get()); break; From 16522ddc59dfe697c3b4fe73f6b91beae96222bc Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 May 2012 23:09:03 +0200 Subject: [PATCH 5/7] InventoryStore re-stacking unequipped items --- apps/openmw/mwworld/containerstore.cpp | 19 ++++++++++++++----- apps/openmw/mwworld/containerstore.hpp | 3 +++ apps/openmw/mwworld/inventorystore.cpp | 20 ++++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 32e2da0ae1..e28346de51 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -45,18 +45,27 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() return ContainerStoreIterator (this); } +bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) const +{ + /// \todo add current weapon/armor health, remaining lockpick/repair uses, current enchantment charge here as soon as they are implemented + if ( ptr1.mCellRef->refID == ptr2.mCellRef->refID + && (MWWorld::Class::get(ptr1).getScript(ptr1) == "" && MWWorld::Class::get(ptr2).getScript(ptr2) == "") // item with a script never stacks + && ptr1.mCellRef->owner == ptr2.mCellRef->owner + && ptr1.mCellRef->soul == ptr2.mCellRef->soul + && ptr1.mCellRef->charge == ptr2.mCellRef->charge) + return true; + + return false; +} + void MWWorld::ContainerStore::add (const Ptr& ptr) { int type = getType(ptr); // determine whether to stack or not - // item stacking depends on owner, script, enchantment and name for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) { - if ( iter->mCellRef->refID == ptr.mCellRef->refID - && MWWorld::Class::get(*iter).getScript(*iter) == MWWorld::Class::get(ptr).getScript(ptr) - && MWWorld::Class::get(*iter).getEnchantment(*iter) == MWWorld::Class::get(ptr).getEnchantment(ptr) - && iter->mCellRef->owner == ptr.mCellRef->owner) + if (stacks(*iter, ptr)) { // stack iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() ); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index da5424fe08..2d330f6ea7 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -66,6 +66,9 @@ namespace MWWorld ContainerStoreIterator end(); + bool stacks (const Ptr& ptr1, const Ptr& ptr2) const; + ///< @return true if the two specified objects can stack with each other + void add (const Ptr& ptr); ///< Add the item pointed to by \a ptr to this container. /// diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 576f2371f9..f149513dfd 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -67,9 +67,25 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite throw std::runtime_error ("invalid slot"); } - /// \todo restack item previously in this slot (if required) + // restack item previously in this slot (if required) + if (mSlots[slot] != end()) + { + for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter) + { + if (stacks(*iter, *mSlots[slot])) + { + iter->getRefData().setCount( iter->getRefData().getCount() + mSlots[slot]->getRefData().getCount() ); + mSlots[slot]->getRefData().setCount(0); + break; + } + } + } - /// \todo unstack item pointed to by iterator if required) + // unstack item pointed to by iterator if required + if (iterator->getRefData().getCount() > 1) + { + /// \ŧodo ??? + } mSlots[slot] = iterator; From ee7e482cba639a8c34b3b94e4433827032725a80 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 May 2012 11:52:17 +0200 Subject: [PATCH 6/7] implemented un-stacking --- apps/openmw/mwworld/containerstore.cpp | 8 +++++++- apps/openmw/mwworld/containerstore.hpp | 8 +++++++- apps/openmw/mwworld/inventorystore.cpp | 19 +++++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index e28346de51..94df222d4f 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -75,7 +75,13 @@ void MWWorld::ContainerStore::add (const Ptr& ptr) } } - switch (type) + // if we got here, this means no stacking + addImpl(ptr); +} + +void MWWorld::ContainerStore::addImpl (const Ptr& ptr) +{ + switch (getType(ptr)) { case Type_Potion: potions.list.push_back (*ptr.get()); break; case Type_Apparatus: appas.list.push_back (*ptr.get()); break; diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 2d330f6ea7..9b9d29c576 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -70,13 +70,19 @@ namespace MWWorld ///< @return true if the two specified objects can stack with each other void add (const Ptr& ptr); - ///< Add the item pointed to by \a ptr to this container. + ///< 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. /// /// \attention Do not add items to an existing stack by increasing the count instead of /// calling this function! + protected: + void addImpl (const Ptr& ptr); + ///< Add the item to this container (no stacking) + + public: + void fill (const ESM::InventoryList& items, const ESMS::ESMStore& store); ///< Insert items into *this. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index f149513dfd..ea295e9034 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -84,7 +84,11 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite // unstack item pointed to by iterator if required if (iterator->getRefData().getCount() > 1) { - /// \ŧodo ??? + // add the item again with a count of count-1, then set the count of the original (that will be equipped) to 1 + int count = iterator->getRefData().getCount(); + iterator->getRefData().setCount(count-1); + addImpl(*iterator); + iterator->getRefData().setCount(1); } mSlots[slot] = iterator; @@ -163,7 +167,18 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats) } } - /// \todo unstack, if reqquired (itemsSlots.second) + if (!itemsSlots.second) // if itemsSlots.second is true, item can stay stacked when equipped + { + // unstack item pointed to by iterator if required + if (iter->getRefData().getCount() > 1) + { + // add the item again with a count of count-1, then set the count of the original (that will be equipped) to 1 + int count = iter->getRefData().getCount(); + iter->getRefData().setCount(count-1); + addImpl(*iter); + iter->getRefData().setCount(1); + } + } slots[*iter2] = iter; break; From d341d2113c8585093781f3c6975b3d7c3b1fabd4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 May 2012 14:58:38 +0200 Subject: [PATCH 7/7] fixed some issues --- apps/openmw/mwworld/containerstore.cpp | 2 +- apps/openmw/mwworld/containerstore.hpp | 7 ++++--- apps/openmw/mwworld/inventorystore.cpp | 22 ++++++++++++++++++++-- apps/openmw/mwworld/inventorystore.hpp | 7 +++++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 94df222d4f..dcddc333b0 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -49,7 +49,7 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) const { /// \todo add current weapon/armor health, remaining lockpick/repair uses, current enchantment charge here as soon as they are implemented if ( ptr1.mCellRef->refID == ptr2.mCellRef->refID - && (MWWorld::Class::get(ptr1).getScript(ptr1) == "" && MWWorld::Class::get(ptr2).getScript(ptr2) == "") // item with a script never stacks + && MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks && ptr1.mCellRef->owner == ptr2.mCellRef->owner && ptr1.mCellRef->soul == ptr2.mCellRef->soul && ptr1.mCellRef->charge == ptr2.mCellRef->charge) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 9b9d29c576..f0e9d7e4ab 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -66,9 +66,6 @@ namespace MWWorld ContainerStoreIterator end(); - bool stacks (const Ptr& ptr1, const Ptr& ptr2) const; - ///< @return true if the two specified objects can stack with each other - void add (const Ptr& ptr); ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// @@ -81,6 +78,10 @@ namespace MWWorld void addImpl (const Ptr& ptr); ///< Add the item to this container (no stacking) + virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2) const; + ///< @return true if the two specified objects can stack with each other + /// @note ptr1 is the item that is already in this container + public: void fill (const ESM::InventoryList& items, const ESMS::ESMStore& store); diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index ea295e9034..6cf35ac644 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -59,9 +59,10 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite if (iterator.getContainerStore()!=this) throw std::runtime_error ("attempt to equip an item that is not in the inventory"); + std::pair, bool> slots; if (iterator!=end()) { - std::pair, bool> slots = Class::get (*iterator).getEquipmentSlots (*iterator); + 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"); @@ -82,7 +83,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite } // unstack item pointed to by iterator if required - if (iterator->getRefData().getCount() > 1) + if (iterator!=end() && !slots.second && iterator->getRefData().getCount() > 1) // if slots.second is true, item can stay stacked when equipped { // add the item again with a count of count-1, then set the count of the original (that will be equipped) to 1 int count = iterator->getRefData().getCount(); @@ -199,3 +200,20 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats) flagAsModified(); } } + +bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2) const +{ + bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2); + if (!canStack) + return false; + + // don't stack if the item being checked against is currently equipped. + for (TSlots::const_iterator iter (mSlots.begin()); + iter!=mSlots.end(); ++iter) + { + if (ptr1 == **iter) + return false; + } + + return true; +} diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 5eeaf570d0..4162c7e2e8 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -64,6 +64,13 @@ namespace MWWorld void autoEquip (const MWMechanics::NpcStats& stats); ///< Auto equip items according to stats and item value. + + protected: + + virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2) const; + ///< @return true if the two specified objects can stack with each other + /// @note ptr1 is the item that is already in this container + }; }