From 45b43042371dd2ccba7073d446f8281f9e7aab30 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 21 Sep 2014 13:37:20 +0200 Subject: [PATCH 1/5] Store levitation/teleport enabled state in savegames (Fixes #1923) --- apps/openmw/mwstate/statemanagerimp.cpp | 1 + apps/openmw/mwworld/worldimp.cpp | 41 ++++++++++++++++--------- components/esm/defs.hpp | 1 + 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index aa2d48372..18ebe11ce 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -351,6 +351,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl case ESM::REC_ACTC: case ESM::REC_PROJ: case ESM::REC_MPRJ: + case ESM::REC_ENAB: MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap); break; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 425fa20e5..aff24abbd 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -302,7 +302,8 @@ namespace MWWorld +mProjectileManager->countSavedGameRecords() +1 // player record +1 // weather record - +1; // actorId counter + +1 // actorId counter + +1; // levitation/teleport enabled state } void World::write (ESM::ESMWriter& writer, Loading::Listener& progress) const @@ -325,25 +326,37 @@ namespace MWWorld mPlayer->write (writer, progress); mWeatherManager->write (writer, progress); mProjectileManager->write (writer, progress); + + writer.startRecord(ESM::REC_ENAB); + writer.writeHNT("TELE", mTeleportEnabled); + writer.writeHNT("LEVT", mLevitationEnabled); + writer.endRecord(ESM::REC_ENAB); + progress.increaseProgress(); } void World::readRecord (ESM::ESMReader& reader, int32_t type, const std::map& contentFileMap) { - if (type == ESM::REC_ACTC) - { - MWMechanics::CreatureStats::readActorIdCounter(reader); - return; - } - - if (!mStore.readRecord (reader, type) && - !mGlobalVariables.readRecord (reader, type) && - !mPlayer->readRecord (reader, type) && - !mWeatherManager->readRecord (reader, type) && - !mCells.readRecord (reader, type, contentFileMap) && - !mProjectileManager->readRecord (reader, type)) + switch (type) { - throw std::runtime_error ("unknown record in saved game"); + case ESM::REC_ACTC: + MWMechanics::CreatureStats::readActorIdCounter(reader); + return; + case ESM::REC_ENAB: + reader.getHNT(mTeleportEnabled, "TELE"); + reader.getHNT(mLevitationEnabled, "LEVT"); + return; + default: + if (!mStore.readRecord (reader, type) && + !mGlobalVariables.readRecord (reader, type) && + !mPlayer->readRecord (reader, type) && + !mWeatherManager->readRecord (reader, type) && + !mCells.readRecord (reader, type, contentFileMap) && + !mProjectileManager->readRecord (reader, type)) + { + throw std::runtime_error ("unknown record in saved game"); + } + break; } } diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 67461d467..d5ba919b0 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -113,6 +113,7 @@ enum RecNameInts REC_PROJ = FourCC<'P','R','O','J'>::value, REC_DCOU = FourCC<'D','C','O','U'>::value, REC_MARK = FourCC<'M','A','R','K'>::value, + REC_ENAB = FourCC<'E','N','A','B'>::value, // format 1 REC_FILT = 0x544C4946, From 5d77c5e8cac1c506f50a9e415dfeb489c0704ddb Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 21 Sep 2014 18:01:52 +0200 Subject: [PATCH 2/5] Transfer item ownership to the buyer if item wasn't stolen (Fixes #1933) --- apps/openmw/mwgui/containeritemmodel.cpp | 2 +- apps/openmw/mwgui/tradeitemmodel.cpp | 8 +++++--- apps/openmw/mwgui/tradeitemmodel.hpp | 3 ++- apps/openmw/mwgui/tradewindow.cpp | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index b2befc3ba..520a32ef8 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -76,7 +76,7 @@ MWWorld::Ptr ContainerItemModel::copyItem (const ItemStack& item, size_t count, const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1]; if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source)) throw std::runtime_error("Item to copy needs to be from a different container!"); - return *source.getClass().getContainerStore(source).add(item.mBase, count, source); + return *source.getClass().getContainerStore(source).add(item.mBase, count, source, setNewOwner); } void ContainerItemModel::removeItem (const ItemStack& item, size_t count) diff --git a/apps/openmw/mwgui/tradeitemmodel.cpp b/apps/openmw/mwgui/tradeitemmodel.cpp index 3abfac997..e1283c89d 100644 --- a/apps/openmw/mwgui/tradeitemmodel.cpp +++ b/apps/openmw/mwgui/tradeitemmodel.cpp @@ -119,7 +119,7 @@ namespace MWGui return mBorrowedToUs; } - void TradeItemModel::transferItems() + void TradeItemModel::transferItems(const MWWorld::Ptr& transferFrom) { std::vector::iterator it = mBorrowedToUs.begin(); for (; it != mBorrowedToUs.end(); ++it) @@ -135,9 +135,11 @@ namespace MWGui if (i == sourceModel->getItemCount()) throw std::runtime_error("The borrowed item disappeared"); - // reset owner while copying, but only for items bought by the player - bool setNewOwner = (mMerchant.isEmpty()); const ItemStack& item = sourceModel->getItem(i); + + bool setNewOwner = Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), transferFrom.getCellRef().getRefId()) + || item.mBase.getCellRef().getOwner().empty(); + // copy the borrowed items to our model copyItem(item, it->mCount, setNewOwner); // then remove them from the source model diff --git a/apps/openmw/mwgui/tradeitemmodel.hpp b/apps/openmw/mwgui/tradeitemmodel.hpp index 1bfee9b2a..c463bf40b 100644 --- a/apps/openmw/mwgui/tradeitemmodel.hpp +++ b/apps/openmw/mwgui/tradeitemmodel.hpp @@ -30,7 +30,8 @@ namespace MWGui void returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count); /// Permanently transfers items that were borrowed to us from another model to this model - void transferItems (); + /// @param transferFrom the actor that lent us the items + void transferItems (const MWWorld::Ptr& transferFrom); /// Aborts trade void abort(); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index f09aff5ac..bf4a4c192 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -360,8 +360,8 @@ namespace MWGui MWBase::Environment::get().getDialogueManager()->applyDispositionChange(iBarterSuccessDisposition); // make the item transfer - mTradeModel->transferItems(); - playerItemModel->transferItems(); + mTradeModel->transferItems(player); + playerItemModel->transferItems(mPtr); // transfer the gold if (mCurrentBalance != 0) From a7c0e07d780527782a6650beec8cf1429ff53a88 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 21 Sep 2014 19:51:33 +0200 Subject: [PATCH 3/5] Add missing World cleanup for mLevitationEnabled --- apps/openmw/mwworld/worldimp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index aff24abbd..ed66ae427 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -289,6 +289,7 @@ namespace MWWorld mGodMode = false; mSky = true; mTeleportEnabled = true; + mLevitationEnabled = true; mGlobalVariables.fill (mStore); } From 0f99a959eb76e4d4a679720dcd976e189ad9b314 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Sep 2014 11:26:16 +0200 Subject: [PATCH 4/5] Update barter offer for all items when another item is added (Fixes #1935) --- apps/openmw/mwgui/inventorywindow.cpp | 4 ++-- apps/openmw/mwgui/tradewindow.cpp | 34 +++++++++++++++++++-------- apps/openmw/mwgui/tradewindow.hpp | 2 ++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 151016fe3..2786f6bd3 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -278,14 +278,14 @@ namespace MWGui if (item.mType == ItemStack::Type_Barter) { // this was an item borrowed to us by the merchant - MWBase::Environment::get().getWindowManager()->getTradeWindow()->returnItem(mSelectedItem, count); mTradeModel->returnItemBorrowedToUs(mSelectedItem, count); + MWBase::Environment::get().getWindowManager()->getTradeWindow()->returnItem(mSelectedItem, count); } else { // borrow item to the merchant - MWBase::Environment::get().getWindowManager()->getTradeWindow()->borrowItem(mSelectedItem, count); mTradeModel->borrowItemFromUs(mSelectedItem, count); + MWBase::Environment::get().getWindowManager()->getTradeWindow()->borrowItem(mSelectedItem, count); } mItemView->update(); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index bf4a4c192..00f812c11 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -480,24 +480,38 @@ namespace MWGui mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast(getMerchantGold())); } - void TradeWindow::sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem) + void TradeWindow::updateOffer() { - int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(item, count), boughtItem); + TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); - mCurrentBalance += diff; - mCurrentMerchantOffer += diff; + int merchantOffer = 0; + + std::vector playerBorrowed = playerTradeModel->getItemsBorrowedToUs(); + for (std::vector::const_iterator it = playerBorrowed.begin(); it != playerBorrowed.end(); ++it) + { + merchantOffer -= MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(it->mBase, it->mCount), true); + } + + std::vector merchantBorrowed = mTradeModel->getItemsBorrowedToUs(); + for (std::vector::const_iterator it = merchantBorrowed.begin(); it != merchantBorrowed.end(); ++it) + { + merchantOffer += MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(it->mBase, it->mCount), false); + } + int diff = merchantOffer - mCurrentMerchantOffer; + mCurrentMerchantOffer = merchantOffer; + mCurrentBalance += diff; updateLabels(); } - void TradeWindow::buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem) + void TradeWindow::sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem) { - int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(item, count), !soldItem); - - mCurrentBalance -= diff; - mCurrentMerchantOffer -= diff; + updateOffer(); + } - updateLabels(); + void TradeWindow::buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem) + { + updateOffer(); } void TradeWindow::onReferenceUnavailable() diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index b822331c3..11c0614b7 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -72,6 +72,8 @@ namespace MWGui void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance + void updateOffer(); + void onItemSelected (int index); void sellItem (MyGUI::Widget* sender, int count); From 62ea913e697233a767a6bc78bdff38c7d79c455b Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 24 Sep 2014 20:09:48 +0200 Subject: [PATCH 5/5] Fix cmake warning --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2165fa07a..542ea3e94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -607,8 +607,8 @@ if (WIN32) foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) - set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)\" ) - set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)\" ) + set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)" ) + set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)" ) endforeach( OUTPUTCONFIG ) if (USE_DEBUG_CONSOLE)