From 7983b07b106e6898c14f5277326d88b64384394b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 13 Jan 2014 06:15:22 +0100 Subject: [PATCH] Get bk_treasuryreport script to work properly: - OnPcEquip needs to be set on *using* any item, not just equipping - Handle PcSkipEquip - Execute item's script once immediately after setting OnPcEquip - Do not set OnPcEquip when an item that has skipped equipping sets pcskipequip back to 0 and gets equipped --- apps/openmw/mwgui/inventorywindow.cpp | 60 ++++++++++++++++++++------- apps/openmw/mwgui/inventorywindow.hpp | 4 ++ apps/openmw/mwgui/quickkeysmenu.cpp | 14 +------ apps/openmw/mwworld/actionequip.cpp | 6 --- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 7781c8526..7139c1b2c 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -13,6 +13,8 @@ #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/action.hpp" +#include "../mwscript/interpretercontext.hpp" +#include "../mwbase/scriptmanager.hpp" #include "bookwindow.hpp" #include "scrollwindow.hpp" @@ -351,6 +353,48 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setWeaponVisibility(!mPinned); } + void InventoryWindow::useItem(const MWWorld::Ptr &ptr) + { + const std::string& script = ptr.getClass().getScript(ptr); + + // If the item has a script, set its OnPcEquip to 1 + if (!script.empty() + // Another morrowind oddity: when an item has skipped equipping and pcskipequip is reset to 0 afterwards, + // the next time it is equipped will work normally, but will not set onpcequip + && (ptr != mSkippedToEquip || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 1)) + ptr.getRefData().getLocals().setVarByInt(script, "onpcequip", 1); + + // Give the script a chance to run once before we do anything else + // this is important when setting pcskipequip as a reaction to onpcequip being set (bk_treasuryreport does this) + if (!script.empty()) + { + MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); + MWBase::Environment::get().getScriptManager()->run (script, interpreterContext); + } + + if (script.empty() || ptr.getRefData().getLocals().getIntVar(script, "pcskipequip") == 0) + { + boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); + + action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); + + // this is necessary for books/scrolls: if they are already in the player's inventory, + // the "Take" button should not be visible. + // NOTE: the take button is "reset" when the window opens, so we can safely do the following + // without screwing up future book windows + MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); + MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); + + mSkippedToEquip = MWWorld::Ptr(); + } + else + mSkippedToEquip = ptr; + + mItemView->update(); + + notifyContentChanged(); + } + void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender) { if (mDragAndDrop->mIsOnDragAndDrop) @@ -369,21 +413,7 @@ namespace MWGui mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount); ptr = *it; } - - boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); - - action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); - - // this is necessary for books/scrolls: if they are already in the player's inventory, - // the "Take" button should not be visible. - // NOTE: the take button is "reset" when the window opens, so we can safely do the following - // without screwing up future book windows - MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); - MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); - - mItemView->update(); - - notifyContentChanged(); + useItem(ptr); } else { diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 112e737fa..7e5a0fe10 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -46,6 +46,8 @@ namespace MWGui void updatePlayer(); + void useItem(const MWWorld::Ptr& ptr); + void setGuiMode(GuiMode mode); private: @@ -74,6 +76,8 @@ namespace MWGui MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMisc; + MWWorld::Ptr mSkippedToEquip; + GuiMode mGuiMode; int mLastXSize; diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 77127f59b..61e414fc4 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -308,19 +308,7 @@ namespace MWGui { MWWorld::Ptr item = *button->getChildAt (0)->getUserData(); - boost::shared_ptr action = MWWorld::Class::get(item).use(item); - - action->execute (MWBase::Environment::get().getWorld()->getPlayerPtr()); - - // this is necessary for books/scrolls: if they are already in the player's inventory, - // the "Take" button should not be visible. - // NOTE: the take button is "reset" when the window opens, so we can safely do the following - // without screwing up future book windows - MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false); - MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false); - - // since we changed equipping status, update the inventory window - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); + MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item); } else if (type == Type_MagicItem) { diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 6a0b4eec7..348b09ad9 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -80,11 +80,5 @@ namespace MWWorld break; } } - - std::string script = MWWorld::Class::get(object).getScript(object); - - /* Set OnPCEquip Variable on item's script, if the player is equipping it, and it has a script with that variable declared */ - if(equipped && actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && script != "") - object.getRefData().getLocals().setVarByInt(script, "onpcequip", 1); } }