From f72f898bd9ea8c49c143ae650bcc94b0e45c5ef4 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 5 Nov 2012 11:07:43 +0100 Subject: [PATCH 01/25] implement barterOffer. It's used for travel only. I've started to implement disposition, but it's very basic for now. --- apps/openmw/mwbase/mechanicsmanager.hpp | 6 +++ apps/openmw/mwclass/npc.cpp | 2 + apps/openmw/mwgui/travelwindow.cpp | 2 + .../mwmechanics/mechanicsmanagerimp.cpp | 52 +++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 6 +++ apps/openmw/mwmechanics/npcstats.cpp | 12 ++++- apps/openmw/mwmechanics/npcstats.hpp | 5 ++ 7 files changed, 84 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 39d7e6e1a..bf8d8dee4 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -74,6 +74,12 @@ namespace MWBase virtual void restoreDynamicStats() = 0; ///< If the player is sleeping, this should be called every hour. + + virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; + ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. + + virtual int disposition(const MWWorld::Ptr& ptr) = 0; + ///< Calculate the diposition of an NPC toward the player. }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 03b5e56aa..4bf6c24b7 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -94,6 +94,8 @@ namespace MWClass data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue); data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel); + + data->mNpcStats.setDisposition(ref->base->mNpdt52.mDisposition); } else { diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index c19639aa6..7195ea725 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -66,6 +66,8 @@ namespace MWGui price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat(); } + price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; /// \todo price adjustment depending on merchantile skill diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 364e65321..9a3ff610b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -324,4 +324,56 @@ namespace MWMechanics buildPlayer(); mUpdatePlayer = true; } + + float min(float a,float b) + { + if(ab) return a; + else return b; + } + + int MechanicsManager::disposition(const MWWorld::Ptr& ptr) + { + MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); + return npcSkill.getDisposition(); + } + + int MechanicsManager::barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) + { + MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); + MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); + + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); + MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); + + int clampedDisposition = min(disposition(ptr),100); + float a = min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float b = min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float c = min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + float d = min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float e = min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float f = min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + + float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm(); + float npcTerm = (d + e + f) * sellerStats.getFatigueTerm(); + float buyTerm = 0.01 * (100 - 0.5 * (pcTerm - npcTerm)); + float sellTerm = 0.01 * (50 - 0.5 * (npcTerm - pcTerm)); + + float x; + if(buying) x = buyTerm; + else x = min(buyTerm, sellTerm); + std::cout << "x" << x; + int offerPrice; + if (x < 1) offerPrice = int(x * basePrice); + if (x >= 1) offerPrice = basePrice + int((x - 1) * basePrice); + offerPrice = max(1, offerPrice); + std::cout <<"barteroffer"<< offerPrice << " " << basePrice << "\n"; + return offerPrice; + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 3a41e8fa6..cdf418a81 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -76,6 +76,12 @@ namespace MWMechanics virtual void restoreDynamicStats(); ///< If the player is sleeping, this should be called every hour. + + virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying); + ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. + + virtual int disposition(const MWWorld::Ptr& ptr); + ///< Calculate the diposition of an NPC toward the player. }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index bbd42c147..f09b7b0bd 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -19,7 +19,7 @@ MWMechanics::NpcStats::NpcStats() : mMovementFlags (0), mDrawState (DrawState_Nothing) -, mLevelProgress(0) +, mLevelProgress(0), mDisposition(0) { mSkillIncreases.resize (ESM::Attribute::Length); for (int i=0; i mFactionRank; DrawState_ mDrawState; + unsigned int mDisposition; unsigned int mMovementFlags; Stat mSkill[27]; @@ -60,6 +61,10 @@ namespace MWMechanics void setDrawState (DrawState_ state); + unsigned int getDisposition() const; + + void setDisposition(unsigned int disposition); + bool getMovementFlag (Flag flag) const; void setMovementFlag (Flag flag, bool state); From aaf1b66c7ea47002b1110441b88bac435245d4d4 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 5 Nov 2012 19:53:55 +0100 Subject: [PATCH 02/25] BarterOffer is used in other trading services too --- apps/openmw/mwgui/spellbuyingwindow.cpp | 2 ++ apps/openmw/mwgui/spellcreationdialog.cpp | 3 ++- apps/openmw/mwgui/tradewindow.cpp | 8 +++++--- apps/openmw/mwgui/trainingwindow.cpp | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index ece19cdc3..0e7925e28 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -8,6 +8,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" @@ -51,6 +52,7 @@ namespace MWGui { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); int price = spell->mData.mCost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat(); + price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); MyGUI::Button* toAdd = mSpellsView->createWidget( diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 4ce056010..3abd4c31e 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -9,6 +9,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" @@ -388,7 +389,7 @@ namespace MWGui float fSpellMakingValueMult = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellMakingValueMult")->getFloat(); /// \todo mercantile - int price = int(y) * fSpellMakingValueMult; + int price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,int(y) * fSpellMakingValueMult,true); mPriceLabel->setCaption(boost::lexical_cast(int(price))); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 64710c279..cd66b46f5 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/manualref.hpp" @@ -318,16 +319,17 @@ namespace MWGui { /// \todo price adjustment depending on merchantile skill - mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count; + mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count + + MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); updateLabels(); } void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count) { - /// \todo price adjustment depending on merchantile skill - mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count; + mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count + - MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); updateLabels(); } diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index af61b3487..106df627e 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -7,6 +7,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" @@ -76,7 +77,7 @@ namespace MWGui for (int i=0; i<3; ++i) { /// \todo mercantile skill - int price = pcStats.getSkill (bestSkills[i].first).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt (); + int price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt (),true); std::string skin = (price > mWindowManager.getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton"; From 9ebe9cb40c3f23a195e783f4edf736c9e0f3defe Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 5 Nov 2012 19:55:06 +0100 Subject: [PATCH 03/25] Disposition is now calculated according to the Wiki. But: bouty and deacease are not implemented (for disposition at least), and there is still no temporary/permanent dispositons changes --- apps/openmw/mwgui/dialogue.cpp | 5 +- .../mwmechanics/mechanicsmanagerimp.cpp | 89 ++++++++++++++----- 2 files changed, 72 insertions(+), 22 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 23d2197b7..9725df7fe 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -12,6 +12,7 @@ #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "dialogue_history.hpp" #include "widgets.hpp" @@ -294,9 +295,9 @@ void DialogueWindow::updateOptions() mHistory->eraseText(0, mHistory->getTextLength()); mDispositionBar->setProgressRange(100); - mDispositionBar->setProgressPosition(40); + mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); mDispositionText->eraseText(0, mDispositionText->getTextLength()); - mDispositionText->addText("#B29154"+std::string("40/100")+"#B29154"); + mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); } void DialogueWindow::goodbye() diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 9a3ff610b..7f4ab600f 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -325,22 +325,71 @@ namespace MWMechanics mUpdatePlayer = true; } - float min(float a,float b) + std::string toLower (const std::string& name) { - if(ab) return a; - else return b; + std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), + (int(*)(int)) std::tolower); + + return lowerCase; } int MechanicsManager::disposition(const MWWorld::Ptr& ptr) { MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); - return npcSkill.getDisposition(); + float x = npcSkill.getDisposition(); + + MWWorld::LiveCellRef* npc = ptr.get(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::LiveCellRef* player = playerPtr.get(); + MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); + MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); + + if (toLower(npc->base->mRace) == toLower(player->base->mRace)) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispRaceMod")->getFloat(); + + x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispPersonalityMult")->getFloat() + * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispPersonalityBase")->getFloat()); + + float reaction = 0; + int rank = 0; + std::string npcFaction = npcSkill.getFactionRanks().begin()->first; + const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + + if (playerSkill.getFactionRanks().find(toLower(npcFaction)) != playerSkill.getFactionRanks().end()) + { + for(std::vector::const_iterator it = store.factions.find(toLower(npcFaction))->mReactions.begin();it != store.factions.find(toLower(npcFaction))->mReactions.end();it++) + { + if(toLower(it->mFaction) == toLower(npcFaction)) reaction = it->mReaction; + } + rank = playerSkill.getFactionRanks().find(toLower(npcFaction))->second; + } + else if (npcFaction != "") + { + std::cout << "npc has a faction!"; + for(std::vector::const_iterator it = store.factions.find(toLower(npcFaction))->mReactions.begin();it != store.factions.find(toLower(npcFaction))->mReactions.end();it++) + { + if(playerSkill.getFactionRanks().find(toLower(it->mFaction)) != playerSkill.getFactionRanks().end() ) + { + if(it->mReactionmReaction; + } + } + rank = 0; + } + else + { + reaction = 0; + rank = 0; + } + x += (MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankMult")->getFloat() * rank + + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankBase")->getFloat()) + * MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionMod")->getFloat() * reaction; + //x -= MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispCrimeMod") * pcBounty; + //if (pc has a disease) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispDiseaseMod"); + if (playerSkill.getDrawState() == MWMechanics::DrawState_::DrawState_Weapon) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispWeaponDrawn")->getFloat(); + + int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used + return effective_disposition; } int MechanicsManager::barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) @@ -352,13 +401,13 @@ namespace MWMechanics MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); - int clampedDisposition = min(disposition(ptr),100); - float a = min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float b = min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float c = min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); - float d = min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float e = min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float f = min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + int clampedDisposition = std::min(disposition(ptr),100); + float a = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float b = std::min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float c = std::min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + float d = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float e = std::min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float f = std::min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm(); float npcTerm = (d + e + f) * sellerStats.getFatigueTerm(); @@ -367,13 +416,13 @@ namespace MWMechanics float x; if(buying) x = buyTerm; - else x = min(buyTerm, sellTerm); - std::cout << "x" << x; + else x = std::min(buyTerm, sellTerm); + //std::cout << "x" << x; int offerPrice; if (x < 1) offerPrice = int(x * basePrice); if (x >= 1) offerPrice = basePrice + int((x - 1) * basePrice); - offerPrice = max(1, offerPrice); - std::cout <<"barteroffer"<< offerPrice << " " << basePrice << "\n"; + offerPrice = std::max(1, offerPrice); + //std::cout <<"barteroffer"<< offerPrice << " " << basePrice << "\n"; return offerPrice; } } From 2841d831a63875824ef055c65e7bc43433ba50bd Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 5 Nov 2012 23:16:37 +0100 Subject: [PATCH 04/25] Disposition is now updated everyframe --- apps/openmw/mwgui/dialogue.cpp | 13 ++++++++++++- apps/openmw/mwgui/dialogue.hpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 2 ++ apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 1 - 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 9725df7fe..f3cc66f38 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -51,7 +51,7 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_dialogue_window.layout", parWindowManager) - , mEnabled(true) + , mEnabled(false) , mServices(0) { // Centre dialog @@ -311,3 +311,14 @@ void DialogueWindow::onReferenceUnavailable() { mWindowManager.removeGuiMode(GM_Dialogue); } + +void DialogueWindow::onFrame() +{ + if(mEnabled) + { + mDispositionBar->setProgressRange(100); + mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); + mDispositionText->eraseText(0, mDispositionText->getTextLength()); + mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); + } +} diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 3a89409ca..bb9acf5db 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -47,6 +47,7 @@ namespace MWGui void addTitle(std::string text); void askQuestion(std::string question); void goodbye(); + void onFrame(); // make sure to call these before setKeywords() void setServices(int services) { mServices = services; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 0350581e4..bf95c6ae7 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -582,6 +582,8 @@ void WindowManager::onFrame (float frameDuration) mDragAndDrop->mDraggedWidget->setPosition(MyGUI::InputManager::getInstance().getMousePosition()); } + mDialogueWindow->onFrame(); + mInventoryWindow->onFrame(); mStatsWindow->onFrame(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 7f4ab600f..3f76f48a6 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -366,7 +366,6 @@ namespace MWMechanics } else if (npcFaction != "") { - std::cout << "npc has a faction!"; for(std::vector::const_iterator it = store.factions.find(toLower(npcFaction))->mReactions.begin();it != store.factions.find(toLower(npcFaction))->mReactions.end();it++) { if(playerSkill.getFactionRanks().find(toLower(it->mFaction)) != playerSkill.getFactionRanks().end() ) From bf98b95955fd66f758fb7d1e73ae9d22f40c437b Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 6 Nov 2012 13:10:54 +0100 Subject: [PATCH 05/25] bugfix --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3f76f48a6..b65b7573b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -353,7 +353,8 @@ namespace MWMechanics float reaction = 0; int rank = 0; - std::string npcFaction = npcSkill.getFactionRanks().begin()->first; + std::string npcFaction = ""; + if(!npcSkill.getFactionRanks().empty()) npcFaction = npcSkill.getFactionRanks().begin()->first; const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); if (playerSkill.getFactionRanks().find(toLower(npcFaction)) != playerSkill.getFactionRanks().end()) From 78740306db6aecdb345174cbdef9faa7d13d1697 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 00:45:45 +0400 Subject: [PATCH 06/25] non-const access to Store from ESMStore --- apps/openmw/mwworld/esmstore.hpp | 230 +++++++++++++++++++++++++++++++ apps/openmw/mwworld/worldimp.cpp | 4 +- 2 files changed, 232 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 0a6ea01b3..dfe2ac03a 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -145,6 +145,11 @@ namespace MWWorld throw std::runtime_error("Storage for this type not exist"); } + template + Store &get() { + throw std::runtime_error("Storage for this type not exist (non-const)"); + } + template T *insert(const T &x) { Store &store = const_cast &>(get()); @@ -396,6 +401,231 @@ namespace MWWorld inline const Store &ESMStore::get() const { return mAttributes; } + + template <> + inline Store &ESMStore::get() { + return mActivators; + } + + template <> + inline Store &ESMStore::get() { + return mPotions; + } + + template <> + inline Store &ESMStore::get() { + return mAppas; + } + + template <> + inline Store &ESMStore::get() { + return mArmors; + } + + template <> + inline Store &ESMStore::get() { + return mBodyParts; + } + + template <> + inline Store &ESMStore::get() { + return mBooks; + } + + template <> + inline Store &ESMStore::get() { + return mBirthSigns; + } + + template <> + inline Store &ESMStore::get() { + return mClasses; + } + + template <> + inline Store &ESMStore::get() { + return mClothes; + } + + template <> + inline Store &ESMStore::get() { + return mContChange; + } + + template <> + inline Store &ESMStore::get() { + return mContainers; + } + + template <> + inline Store &ESMStore::get() { + return mCreatures; + } + + template <> + inline Store &ESMStore::get() { + return mCreaChange; + } + + template <> + inline Store &ESMStore::get() { + return mDialogs; + } + + template <> + inline Store &ESMStore::get() { + return mDoors; + } + + template <> + inline Store &ESMStore::get() { + return mEnchants; + } + + template <> + inline Store &ESMStore::get() { + return mFactions; + } + + template <> + inline Store &ESMStore::get() { + return mGlobals; + } + + template <> + inline Store &ESMStore::get() { + return mIngreds; + } + + template <> + inline Store &ESMStore::get() { + return mCreatureLists; + } + + template <> + inline Store &ESMStore::get() { + return mItemLists; + } + + template <> + inline Store &ESMStore::get() { + return mLights; + } + + template <> + inline Store &ESMStore::get() { + return mLockpicks; + } + + template <> + inline Store &ESMStore::get() { + return mMiscItems; + } + + template <> + inline Store &ESMStore::get() { + return mNpcs; + } + + template <> + inline Store &ESMStore::get() { + return mNpcChange; + } + + template <> + inline Store &ESMStore::get() { + return mProbes; + } + + template <> + inline Store &ESMStore::get() { + return mRaces; + } + + template <> + inline Store &ESMStore::get() { + return mRegions; + } + + template <> + inline Store &ESMStore::get() { + return mRepairs; + } + + template <> + inline Store &ESMStore::get() { + return mSoundGens; + } + + template <> + inline Store &ESMStore::get() { + return mSounds; + } + + template <> + inline Store &ESMStore::get() { + return mSpells; + } + + template <> + inline Store &ESMStore::get() { + return mStartScripts; + } + + template <> + inline Store &ESMStore::get() { + return mStatics; + } + + template <> + inline Store &ESMStore::get() { + return mWeapons; + } + + template <> + inline Store &ESMStore::get() { + return mGameSettings; + } + + template <> + inline Store &ESMStore::get() { + return mScripts; + } + + template <> + inline Store &ESMStore::get() { + return mCells; + } + + template <> + inline Store &ESMStore::get() { + return mLands; + } + + template <> + inline Store &ESMStore::get() { + return mLandTextures; + } + + template <> + inline Store &ESMStore::get() { + return mPathgrids; + } + + template <> + inline Store &ESMStore::get() { + return mMagicEffects; + } + + template <> + inline Store &ESMStore::get() { + return mSkills; + } + + template <> + inline Store &ESMStore::get() { + return mAttributes; + } } #endif diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9f5b7520c..532d335c3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1058,12 +1058,12 @@ namespace MWWorld // door leads to exterior, use cell name (if any), otherwise translated region name int x,y; positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y); - const ESM::Cell* cell = mStore.get().find(x,y); + const ESM::Cell* cell = ((const ESMStore &) mStore).get().find(x,y); if (cell->mName != "") dest = cell->mName; else { - dest = mStore.get().find(cell->mRegion)->mName; + dest = ((const ESMStore &) mStore).get().find(cell->mRegion)->mName; } } From 9ab2c16055ccd4c1ef35742f289d5392f83125f2 Mon Sep 17 00:00:00 2001 From: greye Date: Wed, 7 Nov 2012 17:49:45 +0400 Subject: [PATCH 07/25] store created character classes as dynamic records --- apps/openmw/mwgui/charactercreation.cpp | 9 ++++++--- apps/openmw/mwgui/windowmanagerimp.cpp | 4 +--- apps/openmw/mwgui/windowmanagerimp.hpp | 1 - apps/openmw/mwworld/player.cpp | 10 +--------- apps/openmw/mwworld/player.hpp | 8 ++++---- 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 253e0779c..cdfa43b3b 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -559,9 +559,12 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) klass.mData.mSkills[i][1] = majorSkills[i]; klass.mData.mSkills[i][0] = minorSkills[i]; } - MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); - mPlayerClass = klass; - mWM->setPlayerClass(klass); + std::pair res = + MWBase::Environment::get().getWorld()->createRecord(klass); + + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(*res.second); + mPlayerClass = *res.second; + mWM->setPlayerClass(*res.second); mWM->removeDialog(mCreateClassDialog); mCreateClassDialog = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8e4187f7f..dfca04948 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -83,7 +83,6 @@ WindowManager::WindowManager( , mSpellCreationDialog(NULL) , mEnchantingDialog(NULL) , mTrainingWindow(NULL) - , mPlayerClass() , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() @@ -499,8 +498,7 @@ void WindowManager::setValue (const std::string& id, int value) void WindowManager::setPlayerClass (const ESM::Class &class_) { - mPlayerClass = class_; - mStatsWindow->setValue("class", mPlayerClass.mName); + mStatsWindow->setValue("class", class_.mName); } void WindowManager::configureSkills (const SkillList& major, const SkillList& minor) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index aa796343e..2e684b5da 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -261,7 +261,6 @@ namespace MWGui /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed. // Various stats about player as needed by window manager - ESM::Class mPlayerClass; std::string mPlayerName; std::string mPlayerRaceId; std::map > mPlayerAttributes; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index a1318f727..5cf1fa379 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -26,8 +26,7 @@ namespace MWWorld float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; - /// \todo Do not make a copy of classes defined in esm/p records. - mClass = new ESM::Class (*world.getStore().get().find (player->mClass)); + mClass = world.getStore().get().find (player->mClass); } Player::~Player() @@ -35,13 +34,6 @@ namespace MWWorld delete mClass; } - void Player::setClass (const ESM::Class& class_) - { - ESM::Class *new_class = new ESM::Class (class_); - delete mClass; - mClass = new_class; - } - void Player::setDrawState (MWMechanics::DrawState_ state) { MWWorld::Ptr ptr = getPlayer(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 68df2ec6d..a7a0ec430 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -1,8 +1,6 @@ #ifndef GAME_MWWORLD_PLAYER_H #define GAME_MWWORLD_PLAYER_H -#include "OgreCamera.h" - #include "../mwworld/cellstore.hpp" #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" @@ -27,7 +25,7 @@ namespace MWWorld bool mMale; std::string mRace; std::string mBirthsign; - ESM::Class *mClass; + const ESM::Class *mClass; bool mAutoMove; int mForwardBackward; public: @@ -67,7 +65,9 @@ namespace MWWorld mBirthsign = birthsign; } - void setClass (const ESM::Class& class_); + void setClass (const ESM::Class& class_) { + mClass = &class_; + } void setDrawState (MWMechanics::DrawState_ state); From 5b9621bca585ab22e3f121346d1a9213d3a254c6 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 01:36:43 +0400 Subject: [PATCH 08/25] store player record data in ESMStore --- apps/openmw/mwbase/world.hpp | 6 ++ apps/openmw/mwgui/charactercreation.cpp | 8 +- apps/openmw/mwgui/levelupdialog.cpp | 2 +- apps/openmw/mwgui/stats_window.cpp | 16 ++-- .../mwmechanics/mechanicsmanagerimp.cpp | 50 +++++++------ apps/openmw/mwworld/player.cpp | 50 ++++++++++--- apps/openmw/mwworld/player.hpp | 74 +++++++++---------- apps/openmw/mwworld/store.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 46 ++++++++++++ apps/openmw/mwworld/worldimp.hpp | 6 ++ 10 files changed, 172 insertions(+), 88 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 3a7cb0874..f28ff0184 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -296,6 +296,12 @@ namespace MWBase /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) + + /// Update player record part with given value + virtual void updatePlayer(int flag, const std::string &value) = 0; + + /// Update player record part with given value + virtual void updatePlayer(int flag, bool value) = 0; }; } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index cdfa43b3b..a054f34dd 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -559,12 +559,10 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) klass.mData.mSkills[i][1] = majorSkills[i]; klass.mData.mSkills[i][0] = minorSkills[i]; } - std::pair res = - MWBase::Environment::get().getWorld()->createRecord(klass); - MWBase::Environment::get().getMechanicsManager()->setPlayerClass(*res.second); - mPlayerClass = *res.second; - mWM->setPlayerClass(*res.second); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); + mPlayerClass = klass; + mWM->setPlayerClass(klass); mWM->removeDialog(mCreateClassDialog); mCreateClassDialog = 0; diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 399ff74a3..d8f12bcbb 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -120,7 +120,7 @@ namespace MWGui setAttributeValues(); // set class image - const ESM::Class& playerClass = MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); + const ESM::Class& playerClass = *MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); // retrieve the ID to this class std::string classId; const MWWorld::Store &classes = diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 9d6842068..ae86cbf1a 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -253,7 +253,10 @@ void StatsWindow::onFrame () setFactions(PCstats.getFactionRanks()); - setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); + const ESM::BirthSign *sign = + MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); + + setBirthSign((sign != 0) ? sign->mId : ""); if (mChanged) updateSkillArea(); @@ -430,7 +433,7 @@ void StatsWindow::updateSkillArea() // race tooltip const ESM::Race* playerRace = - store.get().find (MWBase::Environment::get().getWorld()->getPlayer().getRace()); + MWBase::Environment::get().getWorld()->getPlayer().getRace(); MyGUI::Widget* raceWidget; getWidget(raceWidget, "RaceText"); @@ -440,11 +443,14 @@ void StatsWindow::updateSkillArea() // class tooltip MyGUI::Widget* classWidget; - const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass(); + + const ESM::Class *playerClass = + MWBase::Environment::get().getWorld()->getPlayer().getClass(); + getWidget(classWidget, "ClassText"); - ToolTips::createClassToolTip(classWidget, playerClass); + ToolTips::createClassToolTip(classWidget, *playerClass); getWidget(classWidget, "Class_str"); - ToolTips::createClassToolTip(classWidget, playerClass); + ToolTips::createClassToolTip(classWidget, *playerClass); if (!mFactions.empty()) { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 94418c522..7fc7635a4 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -42,9 +42,7 @@ namespace MWMechanics if (mRaceSelected) { const ESM::Race *race = - MWBase::Environment::get().getWorld()->getStore().get().find ( - MWBase::Environment::get().getWorld()->getPlayer().getRace() - ); + MWBase::Environment::get().getWorld()->getPlayer().getRace(); bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale(); @@ -89,12 +87,11 @@ namespace MWMechanics } // birthsign - if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty()) - { - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getStore().get().find ( - MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); + const ESM::BirthSign *sign = + MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); + if (sign != 0) + { for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); iter!=sign->mPowers.mList.end(); ++iter) { @@ -105,11 +102,12 @@ namespace MWMechanics // class if (mClassSelected) { - const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass(); + const ESM::Class *class_ = + MWBase::Environment::get().getWorld()->getPlayer().getClass(); for (int i=0; i<2; ++i) { - int attribute = class_.mData.mAttribute[i]; + int attribute = class_->mData.mAttribute[i]; if (attribute>=0 && attribute<8) { creatureStats.getAttribute(attribute).setBase ( @@ -123,7 +121,7 @@ namespace MWMechanics for (int i2=0; i2<5; ++i2) { - int index = class_.mData.mSkills[i2][i]; + int index = class_->mData.mSkills[i2][i]; if (index>=0 && index<27) { @@ -139,7 +137,7 @@ namespace MWMechanics MWWorld::Store::iterator iter = skills.begin(); for (; iter != skills.end(); ++iter) { - if (iter->mData.mSpecialization==class_.mData.mSpecialization) + if (iter->mData.mSpecialization==class_->mData.mSpecialization) { int index = iter->mIndex; @@ -266,12 +264,12 @@ namespace MWMechanics MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Player &player = world->getPlayer(); + MWWorld::Player &player = + MWBase::Environment::get().getWorld()->getPlayer(); winMgr->setValue ("name", player.getName()); - winMgr->setValue ("race", world->getStore().get().find (player.getRace())->mName); - winMgr->setValue ("class", player.getClass().mName); + winMgr->setValue ("race", player.getRace()->mName); + winMgr->setValue ("class", player.getClass()->mName); mUpdatePlayer = false; @@ -280,8 +278,8 @@ namespace MWMechanics for (int i=0; i<5; ++i) { - minorSkills[i] = player.getClass().mData.mSkills[i][0]; - majorSkills[i] = player.getClass().mData.mSkills[i][1]; + minorSkills[i] = player.getClass()->mData.mSkills[i][0]; + majorSkills[i] = player.getClass()->mData.mSkills[i][1]; } winMgr->configureSkills (majorSkills, minorSkills); @@ -319,22 +317,26 @@ namespace MWMechanics void MechanicsManager::setPlayerClass (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setClass ( - *MWBase::Environment::get().getWorld()->getStore().get().find (id) - ); + MWBase::Environment::get().getWorld()->getPlayer().setClass(id); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; } - void MechanicsManager::setPlayerClass (const ESM::Class& class_) + void MechanicsManager::setPlayerClass (const ESM::Class &cls) { - MWBase::Environment::get().getWorld()->getPlayer().setClass (class_); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + std::pair res = + world->createRecord(cls); + + world->getPlayer().setClass(res.second->mId); + mClassSelected = true; buildPlayer(); mUpdatePlayer = true; } - + int MechanicsManager::countDeaths (const std::string& id) const { return mActors.countDeaths (id); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5cf1fa379..48767a1a1 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -13,25 +13,22 @@ namespace MWWorld { - Player::Player (const ESM::NPC *player, const MWBase::World& world) : - mCellStore (0), mClass (0), - mAutoMove (false), mForwardBackward (0) + Player::Player (const ESM::NPC *player, const MWBase::World& world) + : mCellStore(0), + mClass(0), + mRace(0), + mSign(0), + mAutoMove(false), + mForwardBackward (0) { mPlayer.mBase = player; mPlayer.mRef.mRefID = "player"; - mName = player->mName; - mMale = !(player->mFlags & ESM::NPC::Female); - mRace = player->mRace; float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; mClass = world.getStore().get().find (player->mClass); - } - - Player::~Player() - { - delete mClass; + mRace = world.getStore().get().find(player->mRace); } void Player::setDrawState (MWMechanics::DrawState_ state) @@ -95,4 +92,35 @@ namespace MWWorld return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); } + void Player::setName(const std::string &value) + { + MWBase::Environment::get().getWorld()->updatePlayer(Data_Name, value); + } + + void Player::setGender(bool value) + { + MWBase::Environment::get().getWorld()->updatePlayer(Data_Male, value); + } + + void Player::setRace(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->updatePlayer(Data_Race, value); + + mRace = world->getStore().get().find(value); + } + + void Player::setBirthsign(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + mSign = world->getStore().get().find(value); + } + + void Player::setClass(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->updatePlayer(Data_Class, value); + + mClass = world->getStore().get().find(value); + } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index a7a0ec430..1e6dae2c2 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -19,21 +19,31 @@ namespace MWWorld /// \brief NPC object representing the player and additional player data class Player { - LiveCellRef mPlayer; - MWWorld::CellStore *mCellStore; - std::string mName; - bool mMale; - std::string mRace; - std::string mBirthsign; - const ESM::Class *mClass; - bool mAutoMove; - int mForwardBackward; + LiveCellRef mPlayer; + MWWorld::CellStore *mCellStore; + + // cached referenced data + const ESM::Class *mClass; + const ESM::Race *mRace; + const ESM::BirthSign *mSign; + + bool mAutoMove; + int mForwardBackward; + public: + enum { + Data_Male, + Data_Name, + Data_Race, + Data_Class, + Data_Sign, + Data_Model, + Data_Head, + Data_Hair + }; Player(const ESM::NPC *player, const MWBase::World& world); - ~Player(); - void setCell (MWWorld::CellStore *cellStore) { mCellStore = cellStore; @@ -45,55 +55,37 @@ namespace MWWorld return ptr; } - void setName (const std::string& name) - { - mName = name; - } - - void setGender (bool male) - { - mMale = male; - } - - void setRace (const std::string& race) - { - mRace = race; - } - - void setBirthsign (const std::string& birthsign) - { - mBirthsign = birthsign; - } - - void setClass (const ESM::Class& class_) { - mClass = &class_; - } + void setName (const std::string& name); + void setGender (bool male); + void setRace (const std::string& race); + void setBirthsign (const std::string& birthsign); + void setClass (const std::string &cls); void setDrawState (MWMechanics::DrawState_ state); std::string getName() const { - return mName; + return mPlayer.mBase->mName; } bool isMale() const { - return mMale; + return (mPlayer.mBase->mFlags & 0x1) == 0; } - std::string getRace() const + const ESM::Race *getRace() const { return mRace; } - std::string getBirthsign() const + const ESM::BirthSign *getBirthsign() const { - return mBirthsign; + return mSign; } - const ESM::Class& getClass() const + const ESM::Class *getClass() const { - return *mClass; + return mClass; } bool getAutoMove() const diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 395abcd83..c645f6613 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -554,7 +554,7 @@ namespace MWWorld ESM::Cell *ptr = search(x, y); if (ptr == 0) { std::ostringstream msg; - msg << "Exterior at (" << x << ", " << y << ") not found (non-const"; + msg << "Exterior at (" << x << ", " << y << ") not found (non-const)"; throw std::runtime_error(msg.str()); } return ptr; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 532d335c3..1c1a3939d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1252,4 +1252,50 @@ namespace MWWorld return 0; } + + void World::updatePlayer(int flag, const std::string &value) + { + ESM::NPC *player = mStore.get().find("player"); + + switch (flag) { + case Player::Data_Name: + player->mName = value; + break; + + case Player::Data_Class: + player->mClass = value; + break; + + case Player::Data_Race: + player->mRace = value; + break; + + case Player::Data_Model: + player->mModel = value; + break; + + case Player::Data_Head: + player->mHead = value; + break; + + case Player::Data_Hair: + player->mHair = value; + break; + + default: + break; + } + } + + void World::updatePlayer(int flag, bool value) + { + ESM::NPC *player = mStore.get().find("player"); + + if (flag == Player::Data_Male) { + player->mFlags |= 0x1; + if (value) { + player->mFlags ^= 0x1; + } + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 2b2ad7821..fe9e96110 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -327,6 +327,12 @@ namespace MWWorld /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) + + /// Update player record part with given value + virtual void updatePlayer(int flag, const std::string &value); + + /// Update player record part with given value + virtual void updatePlayer(int flag, bool value); }; } From f818fa1ebfa84a54948b31f9ce4c6de145f036d3 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 01:39:24 +0400 Subject: [PATCH 09/25] minor update since records contains own id --- apps/openmw/mwgui/levelupdialog.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index d8f12bcbb..099132b8b 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -120,19 +120,10 @@ namespace MWGui setAttributeValues(); // set class image - const ESM::Class& playerClass = *MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); - // retrieve the ID to this class - std::string classId; - const MWWorld::Store &classes = - MWBase::Environment::get().getWorld()->getStore().get(); + const ESM::Class *cls = + MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); - MWWorld::Store::iterator it = classes.begin(); - for (; it != classes.end(); ++it) - { - if (playerClass.mName == it->mName) - classId = it->mId; - } - mClassImage->setImageTexture ("textures\\levelup\\" + classId + ".dds"); + mClassImage->setImageTexture ("textures\\levelup\\" + cls->mId + ".dds"); /// \todo replace this with INI-imported texts int level = creatureStats.getLevel ()+1; From 9dc9098fa7a2254f3baeee2acf004babba164551 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 01:52:34 +0400 Subject: [PATCH 10/25] update MWBase::World interface since records contains own id --- apps/openmw/mwbase/world.hpp | 6 +++--- apps/openmw/mwgui/spellcreationdialog.cpp | 4 ++-- apps/openmw/mwmechanics/alchemy.cpp | 2 +- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 5 ++--- apps/openmw/mwworld/worldimp.cpp | 15 ++++++--------- apps/openmw/mwworld/worldimp.hpp | 6 +++--- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f28ff0184..611e70fe0 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -230,17 +230,17 @@ namespace MWBase ///< Toggle a render mode. ///< \return Resulting mode - virtual std::pair createRecord (const ESM::Potion& record) + virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0; ///< Create a new recrod (of type potion) in the ESM store. /// \return ID, pointer to created record - virtual std::pair createRecord (const ESM::Spell& record) + virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0; ///< Create a new recrod (of type spell) in the ESM store. /// \return ID, pointer to created record - virtual std::pair createRecord (const ESM::Class& record) + virtual const ESM::Class *createRecord (const ESM::Class& record) = 0; ///< Create a new recrod (of type class) in the ESM store. /// \return ID, pointer to created record diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 2ece05cb6..25af72c50 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -336,12 +336,12 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); - std::pair result = MWBase::Environment::get().getWorld()->createRecord(mSpell); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->createRecord(mSpell); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); - spells.add (result.first); + spells.add (spell->mId); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 5ccdc5750..c07c60209 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -279,7 +279,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) newRecord.mEffects.mList = mEffects; - record = MWBase::Environment::get().getWorld()->createRecord (newRecord).second; + record = MWBase::Environment::get().getWorld()->createRecord (newRecord); } MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 7fc7635a4..3ca3a4ba0 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -327,10 +327,9 @@ namespace MWMechanics { MWBase::World *world = MWBase::Environment::get().getWorld(); - std::pair res = - world->createRecord(cls); + const ESM::Class *ptr = world->createRecord(cls); - world->getPlayer().setClass(res.second->mId); + world->getPlayer().setClass(ptr->mId); mClassSelected = true; buildPlayer(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1c1a3939d..e2122aa2d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -779,22 +779,19 @@ namespace MWWorld return mRendering->toggleRenderMode (mode); } - std::pair World::createRecord (const ESM::Potion& record) + const ESM::Potion *World::createRecord (const ESM::Potion& record) { - const ESM::Potion *ptr = mStore.insert(record); - return std::make_pair(ptr->mId, ptr); + return mStore.insert(record); } - std::pair World::createRecord (const ESM::Class& record) + const ESM::Class *World::createRecord (const ESM::Class& record) { - const ESM::Class *ptr = mStore.insert(record); - return std::make_pair(ptr->mId, ptr); + return mStore.insert(record); } - std::pair World::createRecord (const ESM::Spell& record) + const ESM::Spell *World::createRecord (const ESM::Spell& record) { - const ESM::Spell *ptr = mStore.insert(record); - return std::make_pair(ptr->mId, ptr); + return mStore.insert(record); } const ESM::Cell *World::createRecord (const ESM::Cell& record) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index fe9e96110..123ad1f87 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -250,15 +250,15 @@ namespace MWWorld ///< Toggle a render mode. ///< \return Resulting mode - virtual std::pair createRecord (const ESM::Potion& record); + virtual const ESM::Potion *createRecord (const ESM::Potion& record); ///< Create a new recrod (of type potion) in the ESM store. /// \return ID, pointer to created record - virtual std::pair createRecord (const ESM::Spell& record); + virtual const ESM::Spell *createRecord (const ESM::Spell& record); ///< Create a new recrod (of type spell) in the ESM store. /// \return ID, pointer to created record - virtual std::pair createRecord (const ESM::Class& record); + virtual const ESM::Class *createRecord (const ESM::Class& record); ///< Create a new recrod (of type class) in the ESM store. /// \return ID, pointer to created record From 2a06d72e32b6fdcb6698d48a89b1703b736a74d7 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 02:27:01 +0400 Subject: [PATCH 11/25] remove unused custom character classes --- 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 e2122aa2d..26013e4ff 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1260,6 +1260,7 @@ namespace MWWorld break; case Player::Data_Class: + mStore.get().erase(player->mClass); player->mClass = value; break; From 83e758ee500a5975b6f1d2c09986b6ffb750cf4f Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 16:37:57 +0400 Subject: [PATCH 12/25] clean up interfaces --- apps/openmw/mwbase/world.hpp | 12 +- apps/openmw/mwgui/levelupdialog.cpp | 7 +- apps/openmw/mwgui/stats_window.cpp | 14 +- .../mwmechanics/mechanicsmanagerimp.cpp | 83 ++++-- .../mwmechanics/mechanicsmanagerimp.hpp | 1 + apps/openmw/mwworld/esmstore.hpp | 259 ++---------------- apps/openmw/mwworld/player.cpp | 38 --- apps/openmw/mwworld/player.hpp | 46 ---- apps/openmw/mwworld/store.hpp | 57 ---- apps/openmw/mwworld/worldimp.cpp | 56 +--- apps/openmw/mwworld/worldimp.hpp | 12 +- 11 files changed, 121 insertions(+), 464 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 611e70fe0..54cb12c59 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -29,6 +29,7 @@ namespace ESM struct Class; struct Potion; struct Spell; + struct NPC; } namespace MWRender @@ -249,6 +250,11 @@ namespace MWBase ///< Create a new recrod (of type cell) in the ESM store. /// \return ID, pointer to created record + virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; + ///< Create a new recrod (of type npc) in the ESM store. + ///< \note special treatment for 'player' record + /// \return ID, pointer to created record + virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number = 1) = 0; ///< Run animation for a MW-reference. Calls to this function for references that are @@ -296,12 +302,6 @@ namespace MWBase /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) - - /// Update player record part with given value - virtual void updatePlayer(int flag, const std::string &value) = 0; - - /// Update player record part with given value - virtual void updatePlayer(int flag, bool value) = 0; }; } diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 099132b8b..45890b89f 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -108,7 +108,8 @@ namespace MWGui void LevelupDialog::open() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); @@ -119,9 +120,11 @@ namespace MWGui setAttributeValues(); + const ESM::NPC *playerData = player.get()->mBase; + // set class image const ESM::Class *cls = - MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); + world->getStore().get().find(playerData->mClass); mClassImage->setImageTexture ("textures\\levelup\\" + cls->mId + ".dds"); diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index ae86cbf1a..a557539b7 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -252,12 +252,12 @@ void StatsWindow::onFrame () } setFactions(PCstats.getFactionRanks()); - +/* const ESM::BirthSign *sign = MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); setBirthSign((sign != 0) ? sign->mId : ""); - +*/ if (mChanged) updateSkillArea(); } @@ -429,11 +429,13 @@ void StatsWindow::updateSkillArea() if (!mMiscSkills.empty()) addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::ESMStore &store = world->getStore(); + const ESM::NPC *player = + world->getPlayer().getPlayer().get()->mBase; // race tooltip - const ESM::Race* playerRace = - MWBase::Environment::get().getWorld()->getPlayer().getRace(); + const ESM::Race* playerRace = store.get().find(player->mRace); MyGUI::Widget* raceWidget; getWidget(raceWidget, "RaceText"); @@ -445,7 +447,7 @@ void StatsWindow::updateSkillArea() MyGUI::Widget* classWidget; const ESM::Class *playerClass = - MWBase::Environment::get().getWorld()->getPlayer().getClass(); + store.get().find(player->mClass); getWidget(classWidget, "ClassText"); ToolTips::createClassToolTip(classWidget, *playerClass); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3ca3a4ba0..be675d1bd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -37,14 +37,17 @@ namespace MWMechanics creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance); creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality); creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck); + + const MWWorld::ESMStore &esmStore = + MWBase::Environment::get().getWorld()->getStore(); // race if (mRaceSelected) { const ESM::Race *race = - MWBase::Environment::get().getWorld()->getPlayer().getRace(); + esmStore.get().find(player->mRace); - bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale(); + bool male = (player->mFlags & ESM::NPC::Female) == 0; for (int i=0; i<8; ++i) { @@ -87,11 +90,11 @@ namespace MWMechanics } // birthsign - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); - - if (sign != 0) + if (!mSign.empty()) { + const ESM::BirthSign *sign = + esmStore.get().find(mSign); + for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); iter!=sign->mPowers.mList.end(); ++iter) { @@ -103,7 +106,7 @@ namespace MWMechanics if (mClassSelected) { const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getPlayer().getClass(); + esmStore.get().find(player->mClass); for (int i=0; i<2; ++i) { @@ -132,7 +135,7 @@ namespace MWMechanics } const MWWorld::Store &skills = - MWBase::Environment::get().getWorld()->getStore().get(); + esmStore.get(); MWWorld::Store::iterator iter = skills.begin(); for (; iter != skills.end(); ++iter) @@ -263,13 +266,19 @@ namespace MWMechanics // basic player profile; should not change anymore after the creation phase is finished. MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - - MWWorld::Player &player = - MWBase::Environment::get().getWorld()->getPlayer(); + + MWBase::World *world = MWBase::Environment::get().getWorld(); + const ESM::NPC *player = + world->getPlayer().getPlayer().get()->mBase; - winMgr->setValue ("name", player.getName()); - winMgr->setValue ("race", player.getRace()->mName); - winMgr->setValue ("class", player.getClass()->mName); + const ESM::Race *race = + world->getStore().get().find(player->mRace); + const ESM::Class *cls = + world->getStore().get().find(player->mClass); + + winMgr->setValue ("name", player->mName); + winMgr->setValue ("race", race->mName); + winMgr->setValue ("class", cls->mName); mUpdatePlayer = false; @@ -278,8 +287,8 @@ namespace MWMechanics for (int i=0; i<5; ++i) { - minorSkills[i] = player.getClass()->mData.mSkills[i][0]; - majorSkills[i] = player.getClass()->mData.mSkills[i][1]; + minorSkills[i] = cls->mData.mSkills[i][0]; + majorSkills[i] = cls->mData.mSkills[i][1]; } winMgr->configureSkills (majorSkills, minorSkills); @@ -295,14 +304,33 @@ namespace MWMechanics void MechanicsManager::setPlayerName (const std::string& name) { - MWBase::Environment::get().getWorld()->getPlayer().setName (name); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mName = name; + + world->createRecord(player); + mUpdatePlayer = true; } void MechanicsManager::setPlayerRace (const std::string& race, bool male) { - MWBase::Environment::get().getWorld()->getPlayer().setGender (male); - MWBase::Environment::get().getWorld()->getPlayer().setRace (race); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + + player.mRace = race; + + player.mFlags |= ESM::NPC::Female; + if (male) { + player.mFlags ^= ESM::NPC::Female; + } + + world->createRecord(player); + mRaceSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -310,14 +338,21 @@ namespace MWMechanics void MechanicsManager::setPlayerBirthsign (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setBirthsign (id); + mSign = id; buildPlayer(); mUpdatePlayer = true; } void MechanicsManager::setPlayerClass (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setClass(id); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mClass = id; + + world->createRecord(player); + mClassSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -329,7 +364,11 @@ namespace MWMechanics const ESM::Class *ptr = world->createRecord(cls); - world->getPlayer().setClass(ptr->mId); + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mClass = ptr->mId; + + world->createRecord(player); mClassSelected = true; buildPlayer(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 38536d3bd..cc4d8c46a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -29,6 +29,7 @@ namespace MWMechanics bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; + std::string mSign; Actors mActors; void buildPlayer(); diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index dfe2ac03a..9917254ee 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -146,13 +146,13 @@ namespace MWWorld } template - Store &get() { - throw std::runtime_error("Storage for this type not exist (non-const)"); - } - - template - T *insert(const T &x) { + const T *insert(const T &x) { Store &store = const_cast &>(get()); + if (store.search(x.mId) != 0) { + std::ostringstream msg; + msg << "Try to override existing record '" << x.mId << "'"; + throw std::runtime_error(msg.str()); + } T record = x; std::ostringstream id; @@ -173,10 +173,30 @@ namespace MWWorld }; template <> - inline ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { + inline const ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { return mCells.insert(cell); } + template <> + inline const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) { + if (StringUtils::ciEqual(npc.mId, "player")) { + return mNpcs.insert(npc); + } else if (mNpcs.search(npc.mId) != 0) { + std::ostringstream msg; + msg << "Try to override existing record '" << npc.mId << "'"; + throw std::runtime_error(msg.str()); + } + ESM::NPC record = npc; + + std::ostringstream id; + id << "$dynamic" << mDynamicCount++; + record.mId = id.str(); + + ESM::NPC *ptr = mNpcs.insert(record); + mIds[ptr->mId] = ESM::REC_NPC_; + return ptr; + } + template <> inline const Store &ESMStore::get() const { return mActivators; @@ -401,231 +421,6 @@ namespace MWWorld inline const Store &ESMStore::get() const { return mAttributes; } - - template <> - inline Store &ESMStore::get() { - return mActivators; - } - - template <> - inline Store &ESMStore::get() { - return mPotions; - } - - template <> - inline Store &ESMStore::get() { - return mAppas; - } - - template <> - inline Store &ESMStore::get() { - return mArmors; - } - - template <> - inline Store &ESMStore::get() { - return mBodyParts; - } - - template <> - inline Store &ESMStore::get() { - return mBooks; - } - - template <> - inline Store &ESMStore::get() { - return mBirthSigns; - } - - template <> - inline Store &ESMStore::get() { - return mClasses; - } - - template <> - inline Store &ESMStore::get() { - return mClothes; - } - - template <> - inline Store &ESMStore::get() { - return mContChange; - } - - template <> - inline Store &ESMStore::get() { - return mContainers; - } - - template <> - inline Store &ESMStore::get() { - return mCreatures; - } - - template <> - inline Store &ESMStore::get() { - return mCreaChange; - } - - template <> - inline Store &ESMStore::get() { - return mDialogs; - } - - template <> - inline Store &ESMStore::get() { - return mDoors; - } - - template <> - inline Store &ESMStore::get() { - return mEnchants; - } - - template <> - inline Store &ESMStore::get() { - return mFactions; - } - - template <> - inline Store &ESMStore::get() { - return mGlobals; - } - - template <> - inline Store &ESMStore::get() { - return mIngreds; - } - - template <> - inline Store &ESMStore::get() { - return mCreatureLists; - } - - template <> - inline Store &ESMStore::get() { - return mItemLists; - } - - template <> - inline Store &ESMStore::get() { - return mLights; - } - - template <> - inline Store &ESMStore::get() { - return mLockpicks; - } - - template <> - inline Store &ESMStore::get() { - return mMiscItems; - } - - template <> - inline Store &ESMStore::get() { - return mNpcs; - } - - template <> - inline Store &ESMStore::get() { - return mNpcChange; - } - - template <> - inline Store &ESMStore::get() { - return mProbes; - } - - template <> - inline Store &ESMStore::get() { - return mRaces; - } - - template <> - inline Store &ESMStore::get() { - return mRegions; - } - - template <> - inline Store &ESMStore::get() { - return mRepairs; - } - - template <> - inline Store &ESMStore::get() { - return mSoundGens; - } - - template <> - inline Store &ESMStore::get() { - return mSounds; - } - - template <> - inline Store &ESMStore::get() { - return mSpells; - } - - template <> - inline Store &ESMStore::get() { - return mStartScripts; - } - - template <> - inline Store &ESMStore::get() { - return mStatics; - } - - template <> - inline Store &ESMStore::get() { - return mWeapons; - } - - template <> - inline Store &ESMStore::get() { - return mGameSettings; - } - - template <> - inline Store &ESMStore::get() { - return mScripts; - } - - template <> - inline Store &ESMStore::get() { - return mCells; - } - - template <> - inline Store &ESMStore::get() { - return mLands; - } - - template <> - inline Store &ESMStore::get() { - return mLandTextures; - } - - template <> - inline Store &ESMStore::get() { - return mPathgrids; - } - - template <> - inline Store &ESMStore::get() { - return mMagicEffects; - } - - template <> - inline Store &ESMStore::get() { - return mSkills; - } - - template <> - inline Store &ESMStore::get() { - return mAttributes; - } } #endif diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 48767a1a1..3414ba448 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -15,9 +15,6 @@ namespace MWWorld { Player::Player (const ESM::NPC *player, const MWBase::World& world) : mCellStore(0), - mClass(0), - mRace(0), - mSign(0), mAutoMove(false), mForwardBackward (0) { @@ -26,9 +23,6 @@ namespace MWWorld float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; - - mClass = world.getStore().get().find (player->mClass); - mRace = world.getStore().get().find(player->mRace); } void Player::setDrawState (MWMechanics::DrawState_ state) @@ -91,36 +85,4 @@ namespace MWWorld MWWorld::Ptr ptr = getPlayer(); return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); } - - void Player::setName(const std::string &value) - { - MWBase::Environment::get().getWorld()->updatePlayer(Data_Name, value); - } - - void Player::setGender(bool value) - { - MWBase::Environment::get().getWorld()->updatePlayer(Data_Male, value); - } - - void Player::setRace(const std::string &value) - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - world->updatePlayer(Data_Race, value); - - mRace = world->getStore().get().find(value); - } - - void Player::setBirthsign(const std::string &value) - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - mSign = world->getStore().get().find(value); - } - - void Player::setClass(const std::string &value) - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - world->updatePlayer(Data_Class, value); - - mClass = world->getStore().get().find(value); - } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 1e6dae2c2..7c5ac0018 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -22,25 +22,10 @@ namespace MWWorld LiveCellRef mPlayer; MWWorld::CellStore *mCellStore; - // cached referenced data - const ESM::Class *mClass; - const ESM::Race *mRace; - const ESM::BirthSign *mSign; - bool mAutoMove; int mForwardBackward; public: - enum { - Data_Male, - Data_Name, - Data_Race, - Data_Class, - Data_Sign, - Data_Model, - Data_Head, - Data_Hair - }; Player(const ESM::NPC *player, const MWBase::World& world); @@ -55,39 +40,8 @@ namespace MWWorld return ptr; } - void setName (const std::string& name); - void setGender (bool male); - void setRace (const std::string& race); - void setBirthsign (const std::string& birthsign); - void setClass (const std::string &cls); - void setDrawState (MWMechanics::DrawState_ state); - std::string getName() const - { - return mPlayer.mBase->mName; - } - - bool isMale() const - { - return (mPlayer.mBase->mFlags & 0x1) == 0; - } - - const ESM::Race *getRace() const - { - return mRace; - } - - const ESM::BirthSign *getBirthsign() const - { - return mSign; - } - - const ESM::Class *getClass() const - { - return mClass; - } - bool getAutoMove() const { return mAutoMove; diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index c645f6613..00f67c8ea 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -168,26 +168,6 @@ namespace MWWorld } } - T *search(const std::string &id) { - std::string key = StringUtils::lowerCase(id); - typename Dynamic::iterator dit = mDynamic.find(key); - - if (dit != mDynamic.end()) { - return &dit->second; - } - return 0; - } - - T *find(const std::string &id) { - T *ptr = search(id); - if (ptr == 0) { - std::ostringstream msg; - msg << "Object '" << id << "' not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - T *insert(const T &item) { std::string id = StringUtils::lowerCase(item.mId); std::pair result = @@ -523,43 +503,6 @@ namespace MWWorld } } - ESM::Cell *search(const std::string &id) { - std::string key = StringUtils::lowerCase(id); - DynamicInt::iterator it = mDynamicInt.find(key); - if (it != mDynamicInt.end()) { - return &it->second; - } - return 0; - } - - ESM::Cell *find(const std::string &id) { - ESM::Cell *ptr = search(id); - if (ptr == 0) { - std::ostringstream msg; - msg << "Interior '" << id << "' not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - - ESM::Cell *search(int x, int y) { - DynamicExt::iterator it = mDynamicExt.find(std::make_pair(x, y)); - if (it != mDynamicExt.end()) { - return &it->second; - } - return 0; - } - - ESM::Cell *find(int x, int y) { - ESM::Cell *ptr = search(x, y); - if (ptr == 0) { - std::ostringstream msg; - msg << "Exterior at (" << x << ", " << y << ") not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - ESM::Cell *insert(const ESM::Cell &cell) { if (search(cell) != 0) { std::ostringstream msg; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 26013e4ff..af5745744 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -799,6 +799,11 @@ namespace MWWorld return mStore.insert(record); } + const ESM::NPC *World::createRecord(const ESM::NPC &record) + { + return mStore.insert(record); + } + void World::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) { @@ -1055,12 +1060,12 @@ namespace MWWorld // door leads to exterior, use cell name (if any), otherwise translated region name int x,y; positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y); - const ESM::Cell* cell = ((const ESMStore &) mStore).get().find(x,y); + const ESM::Cell* cell = mStore.get().find(x,y); if (cell->mName != "") dest = cell->mName; else { - dest = ((const ESMStore &) mStore).get().find(cell->mRegion)->mName; + dest = mStore.get().find(cell->mRegion)->mName; } } @@ -1249,51 +1254,4 @@ namespace MWWorld return 0; } - - void World::updatePlayer(int flag, const std::string &value) - { - ESM::NPC *player = mStore.get().find("player"); - - switch (flag) { - case Player::Data_Name: - player->mName = value; - break; - - case Player::Data_Class: - mStore.get().erase(player->mClass); - player->mClass = value; - break; - - case Player::Data_Race: - player->mRace = value; - break; - - case Player::Data_Model: - player->mModel = value; - break; - - case Player::Data_Head: - player->mHead = value; - break; - - case Player::Data_Hair: - player->mHair = value; - break; - - default: - break; - } - } - - void World::updatePlayer(int flag, bool value) - { - ESM::NPC *player = mStore.get().find("player"); - - if (flag == Player::Data_Male) { - player->mFlags |= 0x1; - if (value) { - player->mFlags ^= 0x1; - } - } - } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 123ad1f87..20590ff0a 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -266,6 +266,12 @@ namespace MWWorld ///< Create a new recrod (of type cell) in the ESM store. /// \return ID, pointer to created record + virtual const ESM::NPC *createRecord(const ESM::NPC &record); + ///< Create a new recrod (of type npc) in the ESM store. + ///< \note special treatment for 'player' record + /// \return ID, pointer to created record + + virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number = 1); ///< Run animation for a MW-reference. Calls to this function for references that are @@ -327,12 +333,6 @@ namespace MWWorld /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) - - /// Update player record part with given value - virtual void updatePlayer(int flag, const std::string &value); - - /// Update player record part with given value - virtual void updatePlayer(int flag, bool value); }; } From 0a883f4492247dfb7e80ebcf000b9aa8c679a8f2 Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 8 Nov 2012 13:38:20 +0100 Subject: [PATCH 13/25] The player can now barter with merchants --- apps/openmw/mwgui/tradewindow.cpp | 76 +++++++++++++++++-- apps/openmw/mwgui/tradewindow.hpp | 3 + .../mwmechanics/mechanicsmanagerimp.cpp | 2 + 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index cd66b46f5..91247a886 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -11,6 +11,11 @@ #include "../mwworld/inventorystore.hpp" #include "../mwworld/manualref.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" + +#include "../mwworld/player.hpp" + #include "inventorywindow.hpp" namespace MWGui @@ -53,6 +58,8 @@ namespace MWGui mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked); mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked); + mIncreaseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onIncreaseButtonClicked); + mDecreaseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonClicked); setCoord(400, 0, 400, 300); @@ -64,6 +71,7 @@ namespace MWGui setTitle(MWWorld::Class::get(actor).getName(actor)); mCurrentBalance = 0; + mCurrentMerchantOffer = 0; mWindowManager.getInventoryWindow()->startTrade(); @@ -175,6 +183,49 @@ namespace MWGui return; } + if(mCurrentBalance > mCurrentMerchantOffer) + { + /// \todo : if creature.... + //if npc is a creature: reject (no haggle) + + int a = abs(mCurrentMerchantOffer); + int b = abs(mCurrentBalance); + int d = 0; + if (mCurrentMerchantOffer<0) d = int(100 * (a - b) / a); + else d = int(100 * (b - a) / a); + + float clampedDisposition = std::max(0,std::min(int(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)),100)); + + MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr); + MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); + MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); + + float a1 = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float b1 = std::min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float c1 = std::min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + float d1 = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); + float e1 = std::min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); + float f1 = std::min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + + float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm(); + float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm(); + float x = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fBargainOfferMulti")->getFloat() * d + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fBargainOfferBase")->getFloat(); + if (mCurrentMerchantOffer<0) x += abs(int(pcTerm - npcTerm)); + else x += abs(int(npcTerm - pcTerm)); + + int roll = std::rand()%100 + 1; + if(roll > x) //trade refused + { + /// \todo adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition + return ; + } + } + + +/// \todo adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition + // success! make the item transfer. transferBoughtItems(); mWindowManager.getInventoryWindow()->transferBoughtItems(); @@ -199,6 +250,20 @@ namespace MWGui mWindowManager.removeGuiMode(GM_Barter); } + void TradeWindow::onIncreaseButtonClicked(MyGUI::Widget* _sender) + { + if(mCurrentBalance<=-1) mCurrentBalance -= 1; + if(mCurrentBalance>=1) mCurrentBalance += 1; + updateLabels(); + } + + void TradeWindow::onDecreaseButtonClicked(MyGUI::Widget* _sender) + { + if(mCurrentBalance<-1) mCurrentBalance += 1; + if(mCurrentBalance>1) mCurrentBalance -= 1; + updateLabels(); + } + void TradeWindow::updateLabels() { mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); @@ -317,20 +382,17 @@ namespace MWGui void TradeWindow::sellToNpc(MWWorld::Ptr item, int count) { - /// \todo price adjustment depending on merchantile skill - - mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count - + MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); + mCurrentBalance -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); + mCurrentMerchantOffer -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); updateLabels(); } void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count) { - mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count - - MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); - + mCurrentBalance += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); + mCurrentMerchantOffer += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); updateLabels(); } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 4ec55045c..db386d8b6 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -55,11 +55,14 @@ namespace MWGui MyGUI::TextBox* mMerchantGold; int mCurrentBalance; + int mCurrentMerchantOffer; void onWindowResize(MyGUI::Window* _sender); void onFilterChanged(MyGUI::Widget* _sender); void onOfferButtonClicked(MyGUI::Widget* _sender); void onCancelButtonClicked(MyGUI::Widget* _sender); + void onIncreaseButtonClicked(MyGUI::Widget* _sender); + void onDecreaseButtonClicked(MyGUI::Widget* _sender); // don't show items that the NPC has equipped in his trade-window. virtual bool ignoreEquippedItems() { return true; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b65b7573b..240937b7c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -384,6 +384,8 @@ namespace MWMechanics x += (MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankMult")->getFloat() * rank + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankBase")->getFloat()) * MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionMod")->getFloat() * reaction; + + /// \todo implement bounty and disease //x -= MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispCrimeMod") * pcBounty; //if (pc has a disease) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispDiseaseMod"); if (playerSkill.getDrawState() == MWMechanics::DrawState_::DrawState_Weapon) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispWeaponDrawn")->getFloat(); From 2a86432887545756c52cd627f7681ab280df3b23 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 18:50:18 +0400 Subject: [PATCH 14/25] store birthsign in MWWorld::Player --- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwgui/stats_window.cpp | 10 +++++----- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 9 ++++++--- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 1 - apps/openmw/mwworld/player.hpp | 9 +++++++++ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 54cb12c59..199b563da 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -252,7 +252,7 @@ namespace MWBase virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; ///< Create a new recrod (of type npc) in the ESM store. - ///< \note special treatment for 'player' record + /// \note special treatment for 'player' record /// \return ID, pointer to created record virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index a557539b7..4b47bb025 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -252,12 +252,12 @@ void StatsWindow::onFrame () } setFactions(PCstats.getFactionRanks()); -/* - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); - setBirthSign((sign != 0) ? sign->mId : ""); -*/ + const std::string &signId = + MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); + + setBirthSign(signId); + if (mChanged) updateSkillArea(); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index be675d1bd..50868eeb3 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -90,10 +90,13 @@ namespace MWMechanics } // birthsign - if (!mSign.empty()) + const std::string &signId = + MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); + + if (!signId.empty()) { const ESM::BirthSign *sign = - esmStore.get().find(mSign); + esmStore.get().find(signId); for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); iter!=sign->mPowers.mList.end(); ++iter) @@ -338,7 +341,7 @@ namespace MWMechanics void MechanicsManager::setPlayerBirthsign (const std::string& id) { - mSign = id; + MWBase::Environment::get().getWorld()->getPlayer().setBirthSign(id); buildPlayer(); mUpdatePlayer = true; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index cc4d8c46a..38536d3bd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -29,7 +29,6 @@ namespace MWMechanics bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; - std::string mSign; Actors mActors; void buildPlayer(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 7c5ac0018..1c1ef76cf 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -21,6 +21,7 @@ namespace MWWorld { LiveCellRef mPlayer; MWWorld::CellStore *mCellStore; + std::string mSign; bool mAutoMove; int mForwardBackward; @@ -40,6 +41,14 @@ namespace MWWorld return ptr; } + void setBirthSign(const std::string &sign) { + mSign = sign; + } + + const std::string &getBirthSign() const { + return mSign; + } + void setDrawState (MWMechanics::DrawState_ state); bool getAutoMove() const From b5a59c3a07a5b8b2453a3528c21e34cb07db1269 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 8 Nov 2012 19:01:42 +0400 Subject: [PATCH 15/25] minor doxygen comments update --- apps/openmw/mwbase/world.hpp | 11 +++++------ apps/openmw/mwworld/worldimp.hpp | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 199b563da..5416945e7 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -234,26 +234,25 @@ namespace MWBase virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0; ///< Create a new recrod (of type potion) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0; ///< Create a new recrod (of type spell) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Class *createRecord (const ESM::Class& record) = 0; ///< Create a new recrod (of type class) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0; ///< Create a new recrod (of type cell) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; ///< Create a new recrod (of type npc) in the ESM store. - /// \note special treatment for 'player' record - /// \return ID, pointer to created record + /// \return pointer to created record virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number = 1) = 0; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 20590ff0a..0962c292c 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -252,24 +252,23 @@ namespace MWWorld virtual const ESM::Potion *createRecord (const ESM::Potion& record); ///< Create a new recrod (of type potion) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Spell *createRecord (const ESM::Spell& record); ///< Create a new recrod (of type spell) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Class *createRecord (const ESM::Class& record); ///< Create a new recrod (of type class) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::Cell *createRecord (const ESM::Cell& record); ///< Create a new recrod (of type cell) in the ESM store. - /// \return ID, pointer to created record + /// \return pointer to created record virtual const ESM::NPC *createRecord(const ESM::NPC &record); ///< Create a new recrod (of type npc) in the ESM store. - ///< \note special treatment for 'player' record - /// \return ID, pointer to created record + /// \return pointer to created record virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, From 00a2de432ab6904e993eb7f86be2cb4848cb10d6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 18:48:07 +0100 Subject: [PATCH 16/25] fix BulletShapeLoader namespace --- .gitignore | 1 + components/nifbullet/bullet_nif_loader.cpp | 6 +++--- components/nifbullet/bullet_nif_loader.hpp | 4 ++-- libs/openengine/bullet/BulletShapeLoader.cpp | 16 +++++++++++----- libs/openengine/bullet/BulletShapeLoader.h | 13 ++++++++++--- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 26ba80e1a..9734ac35c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ Makefile makefile data *.kdev4 +CMakeLists.txt.user diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index d2ec7ca82..42f6a8e68 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -69,7 +69,7 @@ btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v) void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) { - cShape = static_cast(resource); + cShape = static_cast(resource); resourceName = cShape->getName(); cShape->mCollide = false; mBoundingBox = NULL; @@ -314,8 +314,8 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags void ManualBulletShapeLoader::load(const std::string &name,const std::string &group) { // Check if the resource already exists - Ogre::ResourcePtr ptr = BulletShapeManager::getSingleton().getByName(name, group); + Ogre::ResourcePtr ptr = OEngine::Physic::BulletShapeManager::getSingleton().getByName(name, group); if (!ptr.isNull()) return; - BulletShapeManager::getSingleton().create(name,group,true,this); + OEngine::Physic::BulletShapeManager::getSingleton().create(name,group,true,this); } diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 82ac227a0..2190fda1b 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -48,7 +48,7 @@ namespace NifBullet /** *Load bulletShape from NIF files. */ -class ManualBulletShapeLoader : public BulletShapeLoader +class ManualBulletShapeLoader : public OEngine::Physic::BulletShapeLoader { public: @@ -104,7 +104,7 @@ private: - BulletShape* cShape;//current shape + OEngine::Physic::BulletShape* cShape;//current shape btTriangleMesh *mTriMesh; btBoxShape *mBoundingBox; btBvhTriangleMeshShape* currentShape;//the shape curently under construction diff --git a/libs/openengine/bullet/BulletShapeLoader.cpp b/libs/openengine/bullet/BulletShapeLoader.cpp index dd3bca692..1e626f088 100644 --- a/libs/openengine/bullet/BulletShapeLoader.cpp +++ b/libs/openengine/bullet/BulletShapeLoader.cpp @@ -1,6 +1,8 @@ #include "BulletShapeLoader.h" - +namespace OEngine { +namespace Physic +{ BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual, @@ -64,17 +66,18 @@ size_t BulletShape::calculateSize() const //============================================================================================================= -template<> BulletShapeManager *Ogre::Singleton::msSingleton = 0; +BulletShapeManager *BulletShapeManager::sThis = 0; BulletShapeManager *BulletShapeManager::getSingletonPtr() { - return msSingleton; + assert(sThis); + return sThis; } BulletShapeManager &BulletShapeManager::getSingleton() { - assert(msSingleton); - return(*msSingleton); + assert(sThis); + return(*sThis); } BulletShapeManager::BulletShapeManager() @@ -124,3 +127,6 @@ void BulletShapeLoader::loadResource(Ogre::Resource *resource) void BulletShapeLoader::load(const std::string &name,const std::string &group) {} + +} +} diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index 21d21777a..5c70aeab9 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -5,8 +5,10 @@ #include #include #include -//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here. -//But the risk of name collision seems pretty low here. + +namespace OEngine { +namespace Physic +{ /** *Define a new resource which describe a Shape usable by bullet.See BulletShapeManager for how to get/use them. @@ -107,7 +109,7 @@ public: *Important Note: i have no idea of what happen if you try to load two time the same resource without unloading. *It won't crash, but it might lead to memory leaks(I don't know how Ogre handle this). So don't do it! */ -class BulletShapeManager : public Ogre::ResourceManager, public Ogre::Singleton +class BulletShapeManager : public Ogre::ResourceManager { protected: @@ -116,6 +118,8 @@ protected: const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams); + static BulletShapeManager *sThis; + public: BulletShapeManager(); @@ -139,4 +143,7 @@ public: virtual void load(const std::string &name,const std::string &group); }; +} +} + #endif From 867fb620c3c56f3c159e08299797bce559792cc5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 19:25:06 +0100 Subject: [PATCH 17/25] part 2 --- libs/openengine/bullet/BulletShapeLoader.cpp | 6 +++++- libs/openengine/bullet/BulletShapeLoader.h | 8 ++++++++ libs/openengine/bullet/physic.cpp | 3 ++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/BulletShapeLoader.cpp b/libs/openengine/bullet/BulletShapeLoader.cpp index 1e626f088..071a5ee8a 100644 --- a/libs/openengine/bullet/BulletShapeLoader.cpp +++ b/libs/openengine/bullet/BulletShapeLoader.cpp @@ -70,7 +70,6 @@ BulletShapeManager *BulletShapeManager::sThis = 0; BulletShapeManager *BulletShapeManager::getSingletonPtr() { - assert(sThis); return sThis; } @@ -82,6 +81,9 @@ BulletShapeManager &BulletShapeManager::getSingleton() BulletShapeManager::BulletShapeManager() { + assert(!sThis); + sThis = this; + mResourceType = "BulletShape"; // low, because it will likely reference other resources @@ -95,6 +97,8 @@ BulletShapeManager::~BulletShapeManager() { // and this is how we unregister it Ogre::ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + + sThis = 0; } BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::String &group) diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index 5c70aeab9..d9bd5879a 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -120,6 +120,14 @@ protected: static BulletShapeManager *sThis; +private: + /** \brief Explicit private copy constructor. This is a forbidden operation.*/ + BulletShapeManager(const BulletShapeManager &); + + /** \brief Private operator= . This is a forbidden operation. */ + BulletShapeManager& operator=(const BulletShapeManager &); + + public: BulletShapeManager(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index d78e25ce7..b39ba53a2 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -251,7 +251,6 @@ namespace Physic PhysicEngine::~PhysicEngine() { - HeightFieldContainer::iterator hf_it = mHeightFieldMap.begin(); for (; hf_it != mHeightFieldMap.end(); ++hf_it) { @@ -293,6 +292,8 @@ namespace Physic delete broadphase; delete pairCache; delete mShapeLoader; + + delete BulletShapeManager::getSingletonPtr(); } void PhysicEngine::addHeightField(float* heights, From 3d7146cd5023c8910d6bd4584a57bf57bf053a47 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 19:34:54 +0100 Subject: [PATCH 18/25] don't allow opening a window multiple times, primarily the console --- apps/openmw/mwgui/windowmanagerimp.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index dfca04948..95356f77f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -772,6 +772,13 @@ void WindowManager::pushGuiMode(GuiMode mode) if (mode==GM_Inventory && mAllowed==GW_None) return; + + // If this mode already exists somewhere in the stack, just bring it to the front. + if (std::find(mGuiModes.begin(), mGuiModes.end(), mode) != mGuiModes.end()) + { + mGuiModes.erase(std::find(mGuiModes.begin(), mGuiModes.end(), mode)); + } + mGuiModes.push_back(mode); bool gameMode = !isGuiMode(); From 4634227f1cbda02c50f0423fc209fadb51447ee0 Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 8 Nov 2012 21:50:56 +0100 Subject: [PATCH 19/25] notify the user when the merchant doesn't accept the offer --- apps/openmw/mwgui/tradewindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 91247a886..2c4201506 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -218,6 +218,8 @@ namespace MWGui int roll = std::rand()%100 + 1; if(roll > x) //trade refused { + MWBase::Environment::get().getWindowManager()-> + messageBox("#{sNotifyMessage9}", std::vector()); /// \todo adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition return ; } From bf4e855260f75b57b9746a721ee0d04fab68bb1a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 22:31:08 +0100 Subject: [PATCH 20/25] fixed creatures --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 2 +- apps/openmw/mwgui/dialogue.cpp | 13 ++++++++----- apps/openmw/mwgui/tradewindow.cpp | 19 ++++++++++++------- .../mwmechanics/mechanicsmanagerimp.cpp | 5 +++-- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 62f7df679..2024c287d 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -795,7 +795,7 @@ namespace MWDialogue || services & ESM::NPC::Misc) windowServices |= MWGui::DialogueWindow::Service_Trade; - if( !mActor.get()->base->mTransport.empty()) + if(mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get()->base->mTransport.empty()) windowServices |= MWGui::DialogueWindow::Service_Travel; if (services & ESM::NPC::Spells) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index f3cc66f38..190a7ddf8 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -294,10 +294,13 @@ void DialogueWindow::updateOptions() mTopicsList->clear(); mHistory->eraseText(0, mHistory->getTextLength()); - mDispositionBar->setProgressRange(100); - mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); - mDispositionText->eraseText(0, mDispositionText->getTextLength()); - mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); + if (mPtr.getTypeName() == typeid(ESM::NPC).name()) + { + mDispositionBar->setProgressRange(100); + mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); + mDispositionText->eraseText(0, mDispositionText->getTextLength()); + mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); + } } void DialogueWindow::goodbye() @@ -314,7 +317,7 @@ void DialogueWindow::onReferenceUnavailable() void DialogueWindow::onFrame() { - if(mEnabled) + if(mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name()) { mDispositionBar->setProgressRange(100); mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 2c4201506..5fe58c790 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -185,8 +185,13 @@ namespace MWGui if(mCurrentBalance > mCurrentMerchantOffer) { - /// \todo : if creature.... //if npc is a creature: reject (no haggle) + if (mPtr.getTypeName() != typeid(ESM::NPC).name()) + { + MWBase::Environment::get().getWindowManager()-> + messageBox("#{sNotifyMessage9}", std::vector()); + return; + } int a = abs(mCurrentMerchantOffer); int b = abs(mCurrentBalance); @@ -202,12 +207,12 @@ namespace MWGui MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); - float a1 = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float b1 = std::min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float c1 = std::min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); - float d1 = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float e1 = std::min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float f1 = std::min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + float a1 = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); + float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); + float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); + float d1 = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); + float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); + float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 240937b7c..3d49e32c5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -396,6 +396,9 @@ namespace MWMechanics int MechanicsManager::barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) { + if (ptr.getTypeName() == typeid(ESM::Creature).name()) + return basePrice; + MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); @@ -419,12 +422,10 @@ namespace MWMechanics float x; if(buying) x = buyTerm; else x = std::min(buyTerm, sellTerm); - //std::cout << "x" << x; int offerPrice; if (x < 1) offerPrice = int(x * basePrice); if (x >= 1) offerPrice = basePrice + int((x - 1) * basePrice); offerPrice = std::max(1, offerPrice); - //std::cout <<"barteroffer"<< offerPrice << " " << basePrice << "\n"; return offerPrice; } } From 322faf13e49bd31f6d6e0ac2e0338d141639f513 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 22:37:59 +0100 Subject: [PATCH 21/25] cleanup --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3d49e32c5..648b8b668 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -407,12 +407,12 @@ namespace MWMechanics MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); int clampedDisposition = std::min(disposition(ptr),100); - float a = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float b = std::min(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float c = std::min(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); - float d = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100); - float e = std::min(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10); - float f = std::min(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10); + float a = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); + float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); + float c = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); + float d = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); + float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); + float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm(); float npcTerm = (d + e + f) * sellerStats.getFatigueTerm(); From ae78eaeb28f8c746e0771c7be0ed3cab1d735095 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 8 Nov 2012 23:21:03 +0100 Subject: [PATCH 22/25] fixed training, fixed todo comments --- apps/openmw/mwgui/spellbuyingwindow.cpp | 1 - apps/openmw/mwgui/spellcreationdialog.cpp | 1 - apps/openmw/mwgui/trainingwindow.cpp | 3 +-- apps/openmw/mwgui/travelwindow.cpp | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index b346939b3..c6e5eb399 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -68,7 +68,6 @@ namespace MWGui ); mCurrentY += sLineHeight; - /// \todo price adjustment depending on merchantile skill toAdd->setUserData(price); toAdd->setCaptionWithReplacing(spell->mName+" - "+boost::lexical_cast(price)+"#{sgp}"); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 562a48c74..1d9737936 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -400,7 +400,6 @@ namespace MWGui float fSpellMakingValueMult = store.get().find("fSpellMakingValueMult")->getFloat(); - /// \todo mercantile int price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,int(y) * fSpellMakingValueMult,true); mPriceLabel->setCaption(boost::lexical_cast(int(price))); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 63bd64721..81f58fbe1 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -79,7 +79,6 @@ namespace MWGui for (int i=0; i<3; ++i) { - /// \todo mercantile skill int price = MWBase::Environment::get().getMechanicsManager()->barterOffer (mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); @@ -121,8 +120,8 @@ namespace MWGui const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - /// \todo mercantile skill int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); + price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); if (mWindowManager.getInventoryWindow()->getPlayerGold()createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; - /// \todo price adjustment depending on merchantile skill if(interior) toAdd->setUserString("interior","y"); else From 39ff2f06ce9567b425070a13e6146f7e2272572f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Nov 2012 14:31:38 +0100 Subject: [PATCH 23/25] added bounty to NpcStats --- apps/openmw/mwmechanics/npcstats.cpp | 12 +++++++++++- apps/openmw/mwmechanics/npcstats.hpp | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index c0da99aaf..c330cccc8 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -18,7 +18,7 @@ #include "../mwbase/soundmanager.hpp" MWMechanics::NpcStats::NpcStats() -: mMovementFlags (0), mDrawState (DrawState_Nothing) +: mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) , mLevelProgress(0) { mSkillIncreases.resize (ESM::Attribute::Length); @@ -238,3 +238,13 @@ bool MWMechanics::NpcStats::hasBeenUsed (const std::string& id) const { return mUsedIds.find (id)!=mUsedIds.end(); } + +int MWMechanics::NpcStats::getBounty() const +{ + return mBounty; +} + +void MWMechanics::NpcStats::setBounty (int bounty) +{ + mBounty = bounty; +} diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 48e63d7b6..66f20a676 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -45,6 +45,7 @@ namespace MWMechanics DrawState_ mDrawState; unsigned int mMovementFlags; Stat mSkill[27]; + int mBounty; int mLevelProgress; // 0-10 @@ -92,6 +93,10 @@ namespace MWMechanics void flagAsUsed (const std::string& id); bool hasBeenUsed (const std::string& id) const; + + int getBounty() const; + + void setBounty (int bounty); }; } From d53a7ade1ec4accbbd087440d24447ee57775098 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 9 Nov 2012 14:42:09 +0100 Subject: [PATCH 24/25] method names, disposition uint->int --- apps/openmw/mwbase/mechanicsmanager.hpp | 4 ++-- apps/openmw/mwgui/dialogue.cpp | 8 ++++---- apps/openmw/mwgui/spellbuyingwindow.cpp | 2 +- apps/openmw/mwgui/spellcreationdialog.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 10 +++++----- apps/openmw/mwgui/trainingwindow.cpp | 4 ++-- apps/openmw/mwgui/travelwindow.cpp | 2 +- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 6 +++--- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 4 ++-- apps/openmw/mwmechanics/npcstats.cpp | 4 ++-- apps/openmw/mwmechanics/npcstats.hpp | 6 +++--- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 2f2906541..9f9b5af70 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -77,10 +77,10 @@ namespace MWBase virtual void restoreDynamicStats() = 0; ///< If the player is sleeping, this should be called every hour. - virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; + virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - virtual int disposition(const MWWorld::Ptr& ptr) = 0; + virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0; ///< Calculate the diposition of an NPC toward the player. virtual int countDeaths (const std::string& id) const = 0; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 577d1d110..e1baaf8e0 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -303,9 +303,9 @@ void DialogueWindow::updateOptions() if (mPtr.getTypeName() == typeid(ESM::NPC).name()) { mDispositionBar->setProgressRange(100); - mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); + mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)); mDispositionText->eraseText(0, mDispositionText->getTextLength()); - mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); + mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154"); } } @@ -326,8 +326,8 @@ void DialogueWindow::onFrame() if(mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name()) { mDispositionBar->setProgressRange(100); - mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)); + mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)); mDispositionText->eraseText(0, mDispositionText->getTextLength()); - mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr))+std::string("/100")+"#B29154"); + mDispositionText->addText("#B29154"+boost::lexical_cast(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154"); } } diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index c6e5eb399..a41f401a5 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -55,7 +55,7 @@ namespace MWGui const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); int price = spell->mData.mCost*store.get().find("fSpellValueMult")->getFloat(); - price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); MyGUI::Button* toAdd = mSpellsView->createWidget( diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 1d9737936..69d69519f 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -400,7 +400,7 @@ namespace MWGui float fSpellMakingValueMult = store.get().find("fSpellMakingValueMult")->getFloat(); - int price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,int(y) * fSpellMakingValueMult,true); + int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,int(y) * fSpellMakingValueMult,true); mPriceLabel->setCaption(boost::lexical_cast(int(price))); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 3ec0451a2..0707ad985 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -206,7 +206,7 @@ namespace MWGui if (mCurrentMerchantOffer<0) d = int(100 * (a - b) / a); else d = int(100 * (b - a) / a); - float clampedDisposition = std::max(0,std::min(int(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)),100)); + float clampedDisposition = std::max(0,std::min(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)),100)); MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr); MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr); @@ -397,16 +397,16 @@ namespace MWGui void TradeWindow::sellToNpc(MWWorld::Ptr item, int count) { - mCurrentBalance -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); - mCurrentMerchantOffer -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); + mCurrentBalance -= MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); + mCurrentMerchantOffer -= MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true); updateLabels(); } void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count) { - mCurrentBalance += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); - mCurrentMerchantOffer += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); + mCurrentBalance += MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); + mCurrentMerchantOffer += MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false); updateLabels(); } diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 81f58fbe1..ba39ee601 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -79,7 +79,7 @@ namespace MWGui for (int i=0; i<3; ++i) { - int price = MWBase::Environment::get().getMechanicsManager()->barterOffer + int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer (mPtr,pcStats.getSkill (bestSkills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); std::string skin = (price > mWindowManager.getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton"; @@ -121,7 +121,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->getStore(); int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); - price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); if (mWindowManager.getInventoryWindow()->getPlayerGold()getFloat(); } - price = MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr,price,true); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 897398f08..3b5a80ef3 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -388,7 +388,7 @@ namespace MWMechanics return lowerCase; } - int MechanicsManager::disposition(const MWWorld::Ptr& ptr) + int MechanicsManager::getDerivedDisposition(const MWWorld::Ptr& ptr) { MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); float x = npcSkill.getDisposition(); @@ -448,7 +448,7 @@ namespace MWMechanics return effective_disposition; } - int MechanicsManager::barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) + int MechanicsManager::getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) { if (ptr.getTypeName() == typeid(ESM::Creature).name()) return basePrice; @@ -460,7 +460,7 @@ namespace MWMechanics MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); - int clampedDisposition = std::min(disposition(ptr),100); + int clampedDisposition = std::min(getDerivedDisposition(ptr),100); float a = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float c = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 4f46bd5e3..0344d951c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -79,10 +79,10 @@ namespace MWMechanics virtual void restoreDynamicStats(); ///< If the player is sleeping, this should be called every hour. - virtual int barterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying); + virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying); ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - virtual int disposition(const MWWorld::Ptr& ptr); + virtual int getDerivedDisposition(const MWWorld::Ptr& ptr); ///< Calculate the diposition of an NPC toward the player. virtual int countDeaths (const std::string& id) const; diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 003d073e7..02e5139ed 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -36,12 +36,12 @@ void MWMechanics::NpcStats::setDrawState (DrawState_ state) mDrawState = state; } -unsigned int MWMechanics::NpcStats::getDisposition() const +int MWMechanics::NpcStats::getDisposition() const { return mDisposition; } -void MWMechanics::NpcStats::setDisposition(unsigned int disposition) +void MWMechanics::NpcStats::setDisposition(int disposition) { mDisposition = disposition; } diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 1fc173f90..893f00648 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -43,7 +43,7 @@ namespace MWMechanics std::map mFactionRank; DrawState_ mDrawState; - unsigned int mDisposition; + int mDisposition; unsigned int mMovementFlags; Stat mSkill[27]; @@ -61,9 +61,9 @@ namespace MWMechanics void setDrawState (DrawState_ state); - unsigned int getDisposition() const; + int getDisposition() const; - void setDisposition(unsigned int disposition); + void setDisposition(int disposition); bool getMovementFlag (Flag flag) const; From be1334b202d219995869b5d0eedba08c6f2aca22 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Nov 2012 18:16:29 +0100 Subject: [PATCH 25/25] disease tests --- apps/openmw/mwmechanics/creaturestats.cpp | 10 ++++++++ apps/openmw/mwmechanics/creaturestats.hpp | 4 ++++ apps/openmw/mwmechanics/spells.cpp | 28 +++++++++++++++++++++++ apps/openmw/mwmechanics/spells.hpp | 4 ++++ 4 files changed, 46 insertions(+) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 95e721c01..e94adf458 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -232,4 +232,14 @@ namespace MWMechanics mDead = false; } } + + bool CreatureStats::hasCommonDisease() const + { + return mSpells.hasCommonDisease(); + } + + bool CreatureStats::hasBlightDisease() const + { + return mSpells.hasBlightDisease(); + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 671dcd439..cdeee6853 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -109,6 +109,10 @@ namespace MWMechanics bool isDead() const; void resurrect(); + + bool hasCommonDisease() const; + + bool hasBlightDisease() const; }; } diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 3ff10cdb8..ef084f479 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -75,4 +75,32 @@ namespace MWMechanics { return mSelectedSpell; } + + bool Spells::hasCommonDisease() const + { + for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + { + const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().find (*iter); + + if (spell->mData.mFlags & ESM::Spell::ST_Disease) + return true; + } + + return false; + } + + bool Spells::hasBlightDisease() const + { + for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + { + const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().find (*iter); + + if (spell->mData.mFlags & ESM::Spell::ST_Blight) + return true; + } + + return false; + } } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index d90f5b502..12308661b 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -55,6 +55,10 @@ namespace MWMechanics const std::string getSelectedSpell() const; ///< May return an empty string. + + bool hasCommonDisease() const; + + bool hasBlightDisease() const; }; }