diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index cab6809aa0..dfb002cfc0 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -61,6 +61,8 @@ namespace MWBase virtual void persuade (int type) = 0; virtual int getTemporaryDispositionChange () const = 0; + + /// @note This change is temporary and gets discarded when dialogue ends. virtual void applyDispositionChange (int delta) = 0; virtual int countSavedGameRecords() const = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index b6cef2fe7f..57681b7fb0 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -560,17 +560,7 @@ namespace MWDialogue void DialogueManager::applyDispositionChange(int delta) { - int oldTemp = mTemporaryDispositionChange; mTemporaryDispositionChange += delta; - // don't allow increasing beyond 100 or decreasing below 0 - int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor); - if (curDisp + mTemporaryDispositionChange < 0) - mTemporaryDispositionChange = -curDisp; - else if (curDisp + mTemporaryDispositionChange > 100) - mTemporaryDispositionChange = 100 - curDisp; - - int diff = mTemporaryDispositionChange - oldTemp; - mPermanentDispositionChange += diff; } bool DialogueManager::checkServiceRefused() diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index db0b78d594..94f8f3ec1a 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -84,6 +84,8 @@ namespace MWDialogue virtual void persuade (int type); virtual int getTemporaryDispositionChange () const; + + /// @note This change is temporary and gets discarded when dialogue ends. virtual void applyDispositionChange (int delta); virtual int countSavedGameRecords() const; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 5e3f93ab96..441e31e327 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -271,7 +271,8 @@ namespace MWGui void DialogueWindow::exit() { - if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice()) + if ((!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice()) + && !mGoodbye) return; MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); } @@ -517,7 +518,7 @@ namespace MWGui MyGUI::Button* byeButton; getWidget(byeButton, "ByeButton"); - if(MWBase::Environment::get().getDialogueManager()->isInChoice()) { + if(MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye) { byeButton->setEnabled(false); } else { diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 55317724e3..59b54e171d 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -100,7 +100,7 @@ namespace MWGui for (size_t i=0; igetItemCount(); ++i) { const ItemStack& item = mSourceModel->getItem(i); - if (item == itemToSearch) + if (item.mBase == itemToSearch.mBase) return i; } return -1; @@ -112,7 +112,7 @@ namespace MWGui for (size_t i=0; iupdate(); + { + if (!mVideo->update()) + { + // If finished playing, start again + mVideo->playVideo("video\\menu_background.bik", 0); + } + } } void MainMenu::updateMenu() diff --git a/apps/openmw/mwgui/tradeitemmodel.cpp b/apps/openmw/mwgui/tradeitemmodel.cpp index fe43eb5483..5fdf604dac 100644 --- a/apps/openmw/mwgui/tradeitemmodel.cpp +++ b/apps/openmw/mwgui/tradeitemmodel.cpp @@ -35,7 +35,7 @@ namespace MWGui bool found = false; for (; it != out.end(); ++it) { - if (it->stacks(item)) + if (it->mBase == item.mBase) { it->mCount += item.mCount; found = true; @@ -52,7 +52,7 @@ namespace MWGui bool found = false; for (; it != out.end(); ++it) { - if (it->stacks(item)) + if (it->mBase == item.mBase) { if (it->mCount < count) throw std::runtime_error("Not enough borrowed items to return"); @@ -114,7 +114,7 @@ namespace MWGui size_t i=0; for (; igetItemCount(); ++i) { - if (it->stacks(sourceModel->getItem(i))) + if (it->mBase == sourceModel->getItem(i).mBase) break; } if (i == sourceModel->getItemCount()) @@ -182,7 +182,7 @@ namespace MWGui std::vector::iterator it = mBorrowedFromUs.begin(); for (; it != mBorrowedFromUs.end(); ++it) { - if (it->stacks(item)) + if (it->mBase == item.mBase) { if (item.mCount < it->mCount) throw std::runtime_error("Lent more items than present"); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index cb7f3b0bd4..73f48c8cf4 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -74,6 +74,8 @@ namespace MWGui mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed); mDecreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased); + mTotalBalance->eventEditTextChange += MyGUI::newDelegate(this, &TradeWindow::onBalanceEdited); + setCoord(400, 0, 400, 300); } @@ -300,6 +302,9 @@ namespace MWGui } } + // Is the player buying? + bool buying = (mCurrentMerchantOffer < 0); + if(mCurrentBalance > mCurrentMerchantOffer) { //if npc is a creature: reject (no haggle) @@ -313,7 +318,7 @@ namespace MWGui int a = abs(mCurrentMerchantOffer); int b = abs(mCurrentBalance); int d = 0; - if (mCurrentBalance<0) + if (buying) d = int(100 * (a - b) / a); else d = int(100 * (b - a) / a); @@ -334,7 +339,7 @@ namespace MWGui float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm(); float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat(); - if (mCurrentBalance<0) + if (buying) x += abs(int(pcTerm - npcTerm)); else x += abs(int(npcTerm - pcTerm)); @@ -410,6 +415,19 @@ namespace MWGui mBalanceButtonsState = BBS_None; } + void TradeWindow::onBalanceEdited(MyGUI::EditBox *_sender) + { + try + { + unsigned int count = boost::lexical_cast(_sender->getCaption()); + mCurrentBalance = count * (mCurrentBalance >= 0 ? 1 : -1); + updateLabels(); + } + catch (std::bad_cast&) + { + } + } + void TradeWindow::onIncreaseButtonTriggered() { if(mCurrentBalance<=-1) mCurrentBalance -= 1; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 420a642e81..cc70f1ae96 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -55,7 +55,7 @@ namespace MWGui MyGUI::Button* mIncreaseButton; MyGUI::Button* mDecreaseButton; MyGUI::TextBox* mTotalBalanceLabel; - MyGUI::TextBox* mTotalBalance; + MyGUI::EditBox* mTotalBalance; MyGUI::Widget* mBottomPane; @@ -91,6 +91,7 @@ namespace MWGui void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onBalanceEdited(MyGUI::EditBox* _sender); void onIncreaseButtonTriggered(); void onDecreaseButtonTriggered(); diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 03d928d2a5..cd6cc4a165 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -68,13 +68,12 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) if (it == mStores.end()) { if (n.val == ESM::REC_INFO) { - std::string id = esm.getHNOString("INAM"); - if (dialogue) { - ESM::DialInfo info; - info.mId = id; - info.load(esm); - dialogue->addInfo(info, esm.getIndex() != 0); - } else { + if (dialogue) + { + dialogue->readInfo(esm, esm.getIndex() != 0); + } + else + { std::cerr << "error: info record without dialog" << std::endl; esm.skipRecord(); } diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp index ee7ddbfadf..92077b572f 100644 --- a/components/esm/loaddial.cpp +++ b/components/esm/loaddial.cpp @@ -40,21 +40,21 @@ void Dialogue::save(ESMWriter &esm) const } } - void Dialogue::blank() - { - mInfo.clear(); - } - -void Dialogue::addInfo(const ESM::DialInfo& info, bool merge) +void Dialogue::blank() { - if (!merge || mInfo.empty() || info.mNext.empty()) + mInfo.clear(); +} + +void Dialogue::readInfo(ESMReader &esm, bool merge) +{ + const std::string& id = esm.getHNOString("INAM"); + + if (!merge || mInfo.empty()) { - mLookup[info.mId] = mInfo.insert(mInfo.end(), info); - return; - } - if (info.mPrev.empty()) - { - mLookup[info.mId] = mInfo.insert(mInfo.begin(), info); + ESM::DialInfo info; + info.mId = id; + info.load(esm); + mLookup[id] = mInfo.insert(mInfo.end(), info); return; } @@ -62,11 +62,30 @@ void Dialogue::addInfo(const ESM::DialInfo& info, bool merge) std::map::iterator lookup; - lookup = mLookup.find(info.mId); + lookup = mLookup.find(id); if (lookup != mLookup.end()) { it = lookup->second; - *it = info; + + // Merge with existing record. Only the subrecords that are present in + // the new record will be overwritten. + it->load(esm); + return; + } + + // New record + ESM::DialInfo info; + info.mId = id; + info.load(esm); + + if (info.mNext.empty()) + { + mLookup[id] = mInfo.insert(mInfo.end(), info); + return; + } + if (info.mPrev.empty()) + { + mLookup[id] = mInfo.insert(mInfo.begin(), info); return; } @@ -75,7 +94,7 @@ void Dialogue::addInfo(const ESM::DialInfo& info, bool merge) { it = lookup->second; - mLookup[info.mId] = mInfo.insert(++it, info); + mLookup[id] = mInfo.insert(++it, info); return; } @@ -84,11 +103,11 @@ void Dialogue::addInfo(const ESM::DialInfo& info, bool merge) { it = lookup->second; - mLookup[info.mId] = mInfo.insert(it, info); + mLookup[id] = mInfo.insert(it, info); return; } - std::cerr << "Failed to insert info " << info.mId << std::endl; + std::cerr << "Failed to insert info " << id << std::endl; } } diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index 6ec5527f9f..fd46ad2109 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -47,8 +47,9 @@ struct Dialogue void load(ESMReader &esm); void save(ESMWriter &esm) const; + /// Read the next info record /// @param merge Merge with existing list, or just push each record to the end of the list? - void addInfo (const ESM::DialInfo& info, bool merge); + void readInfo (ESM::ESMReader& esm, bool merge); void blank(); ///< Set record to default state (does not touch the ID and does not change the type). diff --git a/components/terrain/chunk.cpp b/components/terrain/chunk.cpp index 7ecafda5e3..bb8710b872 100644 --- a/components/terrain/chunk.cpp +++ b/components/terrain/chunk.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -15,6 +16,7 @@ namespace Terrain Chunk::Chunk(Ogre::HardwareVertexBufferSharedPtr uvBuffer, const Ogre::AxisAlignedBox& bounds, const LoadResponseData& data) : mBounds(bounds) + , mOwnMaterial(false) { mVertexData = OGRE_NEW Ogre::VertexData; mVertexData->vertexStart = 0; @@ -70,7 +72,7 @@ namespace Terrain Chunk::~Chunk() { - if (!mMaterial.isNull()) + if (!mMaterial.isNull() && mOwnMaterial) { #if TERRAIN_USE_SHADER sh::Factory::getInstance().destroyMaterialInstance(mMaterial->getName()); @@ -81,9 +83,19 @@ namespace Terrain OGRE_DELETE mIndexData; } - void Chunk::setMaterial(const Ogre::MaterialPtr &material) + void Chunk::setMaterial(const Ogre::MaterialPtr &material, bool own) { + // Clean up the previous material, if we own it + if (!mMaterial.isNull() && mOwnMaterial) + { +#if TERRAIN_USE_SHADER + sh::Factory::getInstance().destroyMaterialInstance(mMaterial->getName()); +#endif + Ogre::MaterialManager::getSingleton().remove(mMaterial->getName()); + } + mMaterial = material; + mOwnMaterial = own; } const Ogre::AxisAlignedBox& Chunk::getBoundingBox(void) const diff --git a/components/terrain/chunk.hpp b/components/terrain/chunk.hpp index d037661aee..9550b30460 100644 --- a/components/terrain/chunk.hpp +++ b/components/terrain/chunk.hpp @@ -20,8 +20,8 @@ namespace Terrain virtual ~Chunk(); - /// @note Takes ownership of \a material - void setMaterial (const Ogre::MaterialPtr& material); + /// @param own Should we take ownership of the material? + void setMaterial (const Ogre::MaterialPtr& material, bool own=true); void setIndexBuffer(Ogre::HardwareIndexBufferSharedPtr buffer); @@ -43,6 +43,7 @@ namespace Terrain private: Ogre::AxisAlignedBox mBounds; Ogre::MaterialPtr mMaterial; + bool mOwnMaterial; // Should we remove mMaterial on destruction? Ogre::VertexData* mVertexData; Ogre::IndexData* mIndexData; diff --git a/components/terrain/material.cpp b/components/terrain/material.cpp index b56f706806..771dcdf91c 100644 --- a/components/terrain/material.cpp +++ b/components/terrain/material.cpp @@ -46,35 +46,28 @@ namespace Terrain } - Ogre::MaterialPtr MaterialGenerator::generate(Ogre::MaterialPtr mat) + Ogre::MaterialPtr MaterialGenerator::generate() { assert(!mLayerList.empty() && "Can't create material with no layers"); - return create(mat, false, false); + return create(false, false); } - Ogre::MaterialPtr MaterialGenerator::generateForCompositeMapRTT(Ogre::MaterialPtr mat) + Ogre::MaterialPtr MaterialGenerator::generateForCompositeMapRTT() { assert(!mLayerList.empty() && "Can't create material with no layers"); - return create(mat, true, false); + return create(true, false); } - Ogre::MaterialPtr MaterialGenerator::generateForCompositeMap(Ogre::MaterialPtr mat) + Ogre::MaterialPtr MaterialGenerator::generateForCompositeMap() { - return create(mat, false, true); + return create(false, true); } - Ogre::MaterialPtr MaterialGenerator::create(Ogre::MaterialPtr mat, bool renderCompositeMap, bool displayCompositeMap) + Ogre::MaterialPtr MaterialGenerator::create(bool renderCompositeMap, bool displayCompositeMap) { assert(!renderCompositeMap || !displayCompositeMap); - if (!mat.isNull()) - { -#if TERRAIN_USE_SHADER - sh::Factory::getInstance().destroyMaterialInstance(mat->getName()); -#endif - Ogre::MaterialManager::getSingleton().remove(mat->getName()); - } static int count = 0; std::stringstream name; @@ -82,7 +75,7 @@ namespace Terrain if (!mShaders) { - mat = Ogre::MaterialManager::getSingleton().create(name.str(), + Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(name.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::Technique* technique = mat->getTechnique(0); technique->removeAllPasses(); diff --git a/components/terrain/material.hpp b/components/terrain/material.hpp index e7e0678991..7f607a7af8 100644 --- a/components/terrain/material.hpp +++ b/components/terrain/material.hpp @@ -29,23 +29,17 @@ namespace Terrain void enableSplitShadows(bool splitShadows) { mSplitShadows = splitShadows; } /// Creates a material suitable for displaying a chunk of terrain using alpha-blending. - /// @param mat Material that will be replaced by the generated material. May be empty as well, in which case - /// a new material is created. - Ogre::MaterialPtr generate (Ogre::MaterialPtr mat); + Ogre::MaterialPtr generate (); /// Creates a material suitable for displaying a chunk of terrain using a ready-made composite map. - /// @param mat Material that will be replaced by the generated material. May be empty as well, in which case - /// a new material is created. - Ogre::MaterialPtr generateForCompositeMap (Ogre::MaterialPtr mat); + Ogre::MaterialPtr generateForCompositeMap (); /// Creates a material suitable for rendering composite maps, i.e. for "baking" several layer textures /// into one. The main difference compared to a normal material is that no shading is applied at this point. - /// @param mat Material that will be replaced by the generated material. May be empty as well, in which case - /// a new material is created. - Ogre::MaterialPtr generateForCompositeMapRTT (Ogre::MaterialPtr mat); + Ogre::MaterialPtr generateForCompositeMapRTT (); private: - Ogre::MaterialPtr create (Ogre::MaterialPtr mat, bool renderCompositeMap, bool displayCompositeMap); + Ogre::MaterialPtr create (bool renderCompositeMap, bool displayCompositeMap); std::vector mLayerList; std::vector mBlendmapList; diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index a14fe1f842..37c638da0c 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -400,13 +400,13 @@ void QuadTreeNode::load(const LoadResponseData &data) { if (mSize == 1) { - mChunk->setMaterial(mMaterialGenerator->generate(mChunk->getMaterial())); + mChunk->setMaterial(mMaterialGenerator->generate()); } else { ensureCompositeMap(); mMaterialGenerator->setCompositeMap(mCompositeMap->getName()); - mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap(mChunk->getMaterial())); + mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap()); } } // else: will be loaded in loadMaterials() after background thread has finished loading layers @@ -532,13 +532,13 @@ void QuadTreeNode::loadMaterials() { if (mSize == 1) { - mChunk->setMaterial(mMaterialGenerator->generate(mChunk->getMaterial())); + mChunk->setMaterial(mMaterialGenerator->generate()); } else { ensureCompositeMap(); mMaterialGenerator->setCompositeMap(mCompositeMap->getName()); - mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap(mChunk->getMaterial())); + mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap()); } } } @@ -554,7 +554,7 @@ void QuadTreeNode::prepareForCompositeMap(Ogre::TRect area) std::vector layer; layer.push_back(mTerrain->getStorage()->getDefaultLayer()); matGen.setLayerList(layer); - makeQuad(sceneMgr, area.left, area.top, area.right, area.bottom, matGen.generateForCompositeMapRTT(Ogre::MaterialPtr())); + makeQuad(sceneMgr, area.left, area.top, area.right, area.bottom, matGen.generateForCompositeMapRTT()); return; } if (mSize > 1) @@ -577,7 +577,7 @@ void QuadTreeNode::prepareForCompositeMap(Ogre::TRect area) else { // TODO: when to destroy? - Ogre::MaterialPtr material = mMaterialGenerator->generateForCompositeMapRTT(Ogre::MaterialPtr()); + Ogre::MaterialPtr material = mMaterialGenerator->generateForCompositeMapRTT(); makeQuad(sceneMgr, area.left, area.top, area.right, area.bottom, material); } } @@ -612,9 +612,9 @@ void QuadTreeNode::applyMaterials() mMaterialGenerator->enableShadows(mTerrain->getShadowsEnabled()); mMaterialGenerator->enableSplitShadows(mTerrain->getSplitShadowsEnabled()); if (mSize <= 1) - mChunk->setMaterial(mMaterialGenerator->generate(Ogre::MaterialPtr())); + mChunk->setMaterial(mMaterialGenerator->generate()); else - mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap(Ogre::MaterialPtr())); + mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap()); } if (hasChildren()) for (int i=0; i<4; ++i) diff --git a/files/mygui/openmw_console.skin.xml b/files/mygui/openmw_console.skin.xml index 470451a0ed..c6d60231ad 100644 --- a/files/mygui/openmw_console.skin.xml +++ b/files/mygui/openmw_console.skin.xml @@ -13,8 +13,8 @@ - + diff --git a/files/mygui/openmw_edit.skin.xml b/files/mygui/openmw_edit.skin.xml index b10854b19e..50f37dbfc3 100644 --- a/files/mygui/openmw_edit.skin.xml +++ b/files/mygui/openmw_edit.skin.xml @@ -10,14 +10,12 @@ - - - - - - + + + + @@ -26,11 +24,6 @@ - - - - - @@ -41,7 +34,7 @@ - + diff --git a/files/mygui/openmw_trade_window.layout b/files/mygui/openmw_trade_window.layout index 8a1be496f4..cb00d7d50c 100644 --- a/files/mygui/openmw_trade_window.layout +++ b/files/mygui/openmw_trade_window.layout @@ -44,7 +44,7 @@ - +