From 9d7c35ae4872f15682b0c0f34345ae05e1ecce90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 23 Sep 2012 00:36:20 +0200 Subject: [PATCH 001/255] and go --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/windowmanager.hpp | 2 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 24 ++-- apps/openmw/mwgui/dialogue.cpp | 22 +++- apps/openmw/mwgui/dialogue.hpp | 12 +- apps/openmw/mwgui/list.cpp | 5 + apps/openmw/mwgui/list.hpp | 3 + apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/spellbuyingwindow.cpp | 5 +- apps/openmw/mwgui/spellbuyingwindow.hpp | 8 +- apps/openmw/mwgui/spellcreationdialog.cpp | 120 ++++++++++++++++++ apps/openmw/mwgui/spellcreationdialog.hpp | 40 ++++++ apps/openmw/mwgui/tooltips.cpp | 34 ++++- apps/openmw/mwgui/tooltips.hpp | 1 + apps/openmw/mwgui/widgets.hpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 14 ++ apps/openmw/mwgui/windowmanagerimp.hpp | 5 + files/mygui/CMakeLists.txt | 1 + .../mygui/openmw_spellcreation_dialog.layout | 80 ++++++++++++ files/mygui/openmw_tooltips.layout | 25 ++++ 20 files changed, 375 insertions(+), 31 deletions(-) create mode 100644 apps/openmw/mwgui/spellcreationdialog.cpp create mode 100644 apps/openmw/mwgui/spellcreationdialog.hpp create mode 100644 files/mygui/openmw_spellcreation_dialog.layout diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66844b280..fabbf3749 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu - itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog + itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 429163136..9f251476a 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -226,6 +226,8 @@ namespace MWBase virtual bool getRestEnabled() = 0; virtual bool getPlayerSleeping() = 0; + + virtual void startSpellMaking(MWWorld::Ptr actor) = 0; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 1b7532d0a..daff8c67a 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -145,16 +145,17 @@ namespace return false; } -} - -namespace MWDialogue -{ //helper function std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos) { return toLower(str).find(toLower(substr),pos); } +} + +namespace MWDialogue +{ + bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice) { @@ -779,6 +780,8 @@ namespace MWDialogue services = ref->base->mAiData.mServices; } + int windowServices = 0; + if (services & ESM::NPC::Weapon || services & ESM::NPC::Armor || services & ESM::NPC::Clothing @@ -790,14 +793,15 @@ namespace MWDialogue || services & ESM::NPC::Apparatus || services & ESM::NPC::RepairItem || services & ESM::NPC::Misc) - win->setShowTrade(true); - else - win->setShowTrade(false); + windowServices |= MWGui::DialogueWindow::Service_Trade; if (services & ESM::NPC::Spells) - win->setShowSpells(true); - else - win->setShowSpells(false); + windowServices |= MWGui::DialogueWindow::Service_BuySpells; + + if (services & ESM::NPC::Spellmaking) + windowServices |= MWGui::DialogueWindow::Service_CreateSpells; + + win->setServices (windowServices); // sort again, because the previous sort was case-sensitive keywordList.sort(stringCompareNoCase); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index a01da7f9f..476379c5d 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -27,6 +27,8 @@ using namespace Widgets; *Copied from the internet. */ +namespace { + std::string lower_string(const std::string& str) { std::string lowerCase; @@ -42,12 +44,13 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su return lower_string(str).find(lower_string(substr),pos); } +} + DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_dialogue_window.layout", parWindowManager) , mEnabled(true) - , mShowTrade(false) - , mShowSpells(false) + , mServices(0) { // Centre dialog center(); @@ -134,7 +137,11 @@ void DialogueWindow::onSelectTopic(std::string topic) mWindowManager.pushGuiMode(GM_SpellBuying); mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); } - + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSpellMakingMenuTitle")->str) + { + mWindowManager.pushGuiMode(GM_SpellCreation); + mWindowManager.startSpellMaking (mPtr); + } else MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -155,14 +162,17 @@ void DialogueWindow::setKeywords(std::list keyWords) { mTopicsList->clear(); - bool anyService = mShowTrade||mShowSpells; + bool anyService = mServices > 0; - if (mShowTrade) + if (mServices & Service_Trade) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str); - if (mShowSpells) + if (mServices & Service_BuySpells) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSpells")->str); + if (mServices & Service_CreateSpells) + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSpellmakingMenuTitle")->str); + if (anyService) mTopicsList->addSeparator(); diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index a43b0d5a7..8074d9b86 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -50,8 +50,14 @@ namespace MWGui // various service button visibilities, depending if the npc/creature talked to has these services // make sure to call these before setKeywords() - void setShowTrade(bool show) { mShowTrade = show; } - void setShowSpells(bool show) { mShowSpells = show; } + void setServices(int services) { mServices = services; } + + enum Services + { + Service_Trade = 0x01, + Service_BuySpells = 0x02, + Service_CreateSpells = 0x04 + }; protected: void onSelectTopic(std::string topic); @@ -73,6 +79,8 @@ namespace MWGui bool mShowTrade; bool mShowSpells; + int mServices; + bool mEnabled; DialogueHistory* mHistory; diff --git a/apps/openmw/mwgui/list.cpp b/apps/openmw/mwgui/list.cpp index 661fb2e68..ff23f8b31 100644 --- a/apps/openmw/mwgui/list.cpp +++ b/apps/openmw/mwgui/list.cpp @@ -129,3 +129,8 @@ void MWList::onItemSelected(MyGUI::Widget* _sender) eventItemSelected(name); } + +MyGUI::Widget* MWList::getItemWidget(const std::string& name) +{ + return mScrollView->findWidget (getName() + "_item_" + name); +} diff --git a/apps/openmw/mwgui/list.hpp b/apps/openmw/mwgui/list.hpp index 2b765c2e1..c1f2d83b5 100644 --- a/apps/openmw/mwgui/list.hpp +++ b/apps/openmw/mwgui/list.hpp @@ -38,6 +38,9 @@ namespace MWGui std::string getItemNameAt(unsigned int at); ///< \attention if there are separators, this method will return "" at the place where the separator is void clear(); + MyGUI::Widget* getItemWidget(const std::string& name); + ///< get widget for an item name, useful to set up tooltip + protected: void initialiseOverride(); diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 64aa1dc21..042505209 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -22,6 +22,7 @@ namespace MWGui GM_Rest, GM_RestBed, GM_SpellBuying, + GM_SpellCreation, GM_Levelup, diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index a41869e32..3a492ce90 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -24,7 +24,6 @@ namespace MWGui SpellBuyingWindow::SpellBuyingWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_spell_buying_window.layout", parWindowManager) - , ContainerBase(NULL) // no drag&drop , mCurrentY(0) , mLastPos(0) { @@ -77,7 +76,7 @@ namespace MWGui void SpellBuyingWindow::startSpellBuying(const MWWorld::Ptr& actor) { center(); - mActor = actor; + mPtr = actor; clearSpells(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -114,7 +113,7 @@ namespace MWGui MWMechanics::Spells& spells = stats.getSpells(); spells.add (mSpellsWidgetMap.find(_sender)->second); mWindowManager.getTradeWindow()->addOrRemoveGold(-price); - startSpellBuying(mActor); + startSpellBuying(mPtr); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); } diff --git a/apps/openmw/mwgui/spellbuyingwindow.hpp b/apps/openmw/mwgui/spellbuyingwindow.hpp index 970498cd9..1d0ac28e0 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.hpp +++ b/apps/openmw/mwgui/spellbuyingwindow.hpp @@ -1,10 +1,8 @@ #ifndef MWGUI_SpellBuyingWINDOW_H #define MWGUI_SpellBuyingWINDOW_H -#include "container.hpp" #include "window_base.hpp" - -#include "../mwworld/ptr.hpp" +#include "referenceinterface.hpp" namespace MyGUI { @@ -20,7 +18,7 @@ namespace MWGui namespace MWGui { - class SpellBuyingWindow : public ContainerBase, public WindowBase + class SpellBuyingWindow : public ReferenceInterface, public WindowBase { public: SpellBuyingWindow(MWBase::WindowManager& parWindowManager); @@ -35,8 +33,6 @@ namespace MWGui MyGUI::ScrollView* mSpellsView; - MWWorld::Ptr mActor; - std::map mSpellsWidgetMap; void onCancelButtonClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp new file mode 100644 index 000000000..fd5e9594c --- /dev/null +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -0,0 +1,120 @@ +#include "spellcreationdialog.hpp" + +#include + +#include "../mwbase/windowmanager.hpp" + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/class.hpp" + +#include "../mwmechanics/spells.hpp" +#include "../mwmechanics/creaturestats.hpp" + +#include "tooltips.hpp" +#include "widgets.hpp" + +namespace +{ + + bool sortMagicEffects (short id1, short id2) + { + return MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(MWGui::Widgets::MWSpellEffect::effectIDToString (id1))->getString() + < MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(MWGui::Widgets::MWSpellEffect::effectIDToString (id2))->getString(); + } +} + +namespace MWGui +{ + + SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) + : WindowBase("openmw_spellcreation_dialog.layout", parWindowManager) + { + getWidget(mNameEdit, "NameEdit"); + getWidget(mMagickaCost, "MagickaCost"); + getWidget(mSuccessChance, "SuccessChance"); + getWidget(mAvailableEffectsList, "AvailableEffects"); + getWidget(mUsedEffectsView, "UsedEffects"); + getWidget(mPriceLabel, "PriceLabel"); + getWidget(mBuyButton, "BuyButton"); + getWidget(mCancelButton, "CancelButton"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onCancelButtonClicked); + mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onBuyButtonClicked); + } + + + void SpellCreationDialog::open() + { + center(); + } + + void SpellCreationDialog::onReferenceUnavailable () + { + mWindowManager.removeGuiMode (GM_Dialogue); + mWindowManager.removeGuiMode (GM_SpellCreation); + } + + void SpellCreationDialog::startSpellMaking (MWWorld::Ptr actor) + { + mPtr = actor; + + // get the list of magic effects that are known to the player + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); + MWMechanics::Spells& spells = stats.getSpells(); + + std::vector knownEffects; + + for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it); + + // only normal spells count + if (spell->data.type != ESM::Spell::ST_Spell) + continue; + + const std::vector& list = spell->effects.list; + for (std::vector::const_iterator it2 = list.begin(); it2 != list.end(); ++it2) + { + if (std::find(knownEffects.begin(), knownEffects.end(), it2->effectID) == knownEffects.end()) + knownEffects.push_back(it2->effectID); + } + } + + std::sort(knownEffects.begin(), knownEffects.end(), sortMagicEffects); + + mAvailableEffectsList->clear (); + + for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) + { + mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find( + MWGui::Widgets::MWSpellEffect::effectIDToString (*it))->getString()); + } + mAvailableEffectsList->adjustSize (); + + for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) + { + std::string name = MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find( + MWGui::Widgets::MWSpellEffect::effectIDToString (*it))->getString(); + MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); + + ToolTips::createMagicEffectToolTip (w, *it); + } + + } + + void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender) + { + mWindowManager.removeGuiMode (MWGui::GM_SpellCreation); + } + + void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) + { + + } + +} diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp new file mode 100644 index 000000000..d0919ced0 --- /dev/null +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -0,0 +1,40 @@ +#ifndef MWGUI_SPELLCREATION_H +#define MWGUI_SPELLCREATION_H + +#include "window_base.hpp" +#include "referenceinterface.hpp" +#include "list.hpp" + +namespace MWGui +{ + + class SpellCreationDialog : public WindowBase, public ReferenceInterface + { + public: + SpellCreationDialog(MWBase::WindowManager& parWindowManager); + + virtual void open(); + + void startSpellMaking(MWWorld::Ptr actor); + + protected: + virtual void onReferenceUnavailable (); + + void onCancelButtonClicked (MyGUI::Widget* sender); + void onBuyButtonClicked (MyGUI::Widget* sender); + + + MyGUI::EditBox* mNameEdit; + MyGUI::TextBox* mMagickaCost; + MyGUI::TextBox* mSuccessChance; + Widgets::MWList* mAvailableEffectsList; + MyGUI::ScrollView* mUsedEffectsView; + MyGUI::Button* mBuyButton; + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPriceLabel; + + }; + +} + +#endif diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 8186279d1..9beca795e 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -586,8 +586,6 @@ void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId) widget->setUserString("Caption_SkillNoProgressDescription", skill->description); widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}"); widget->setUserString("ImageTexture_SkillNoProgressImage", icon); - widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); - widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); } void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId) @@ -713,6 +711,38 @@ void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playe widget->setUserString("ToolTipLayout", "ClassToolTip"); } +void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id) +{ + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld ()->getStore ().magicEffects.find(id); + const std::string &name = Widgets::MWSpellEffect::effectIDToString (id); + + std::string icon = effect->icon; + + int slashPos = icon.find("\\"); + icon.insert(slashPos+1, "b_"); + + icon[icon.size()-3] = 'd'; + icon[icon.size()-2] = 'd'; + icon[icon.size()-1] = 's'; + + icon = "icons\\" + icon; + + std::vector schools; + schools.push_back ("#{sSchoolAlteration}"); + schools.push_back ("#{sSchoolConjuration}"); + schools.push_back ("#{sSchoolDestruction}"); + schools.push_back ("#{sSchoolIllusion}"); + schools.push_back ("#{sSchoolMysticism}"); + schools.push_back ("#{sSchoolRestoration}"); + + widget->setUserString("ToolTipType", "Layout"); + widget->setUserString("ToolTipLayout", "MagicEffectToolTip"); + widget->setUserString("Caption_MagicEffectName", "#{" + name + "}"); + widget->setUserString("Caption_MagicEffectDescription", effect->description); + widget->setUserString("Caption_MagicEffectSchool", "#{sSchool}: " + schools[effect->data.school]); + widget->setUserString("ImageTexture_MagicEffectImage", icon); +} + void ToolTips::setDelay(float delay) { mDelay = delay; diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index f67b6ea5c..270df4ae2 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -71,6 +71,7 @@ namespace MWGui static void createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId); static void createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace); static void createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass); + static void createMagicEffectToolTip(MyGUI::Widget* widget, short id); private: MyGUI::Widget* mDynamicToolTipBox; diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 6298ea77d..899ceadd9 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -249,7 +249,7 @@ namespace MWGui void setWindowManager(MWBase::WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellEffect(const SpellEffectParams& params); - std::string effectIDToString(const short effectID); + static std::string effectIDToString(const short effectID); bool effectHasMagnitude (const std::string& effect); bool effectHasDuration (const std::string& effect); bool effectInvolvesAttribute (const std::string& effect); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e6f9e8565..890b3bc13 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -46,6 +46,7 @@ #include "loadingscreen.hpp" #include "levelupdialog.hpp" #include "waitdialog.hpp" +#include "spellcreationdialog.hpp" using namespace MWGui; @@ -75,6 +76,7 @@ WindowManager::WindowManager( , mCharGen(NULL) , mLevelupDialog(NULL) , mWaitDialog(NULL) + , mSpellCreationDialog(NULL) , mPlayerClass() , mPlayerName() , mPlayerRaceId() @@ -155,6 +157,7 @@ WindowManager::WindowManager( mQuickKeysMenu = new QuickKeysMenu(*this); mLevelupDialog = new LevelupDialog(*this); mWaitDialog = new WaitDialog(*this); + mSpellCreationDialog = new SpellCreationDialog(*this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -210,6 +213,7 @@ WindowManager::~WindowManager() delete mLoadingScreen; delete mLevelupDialog; delete mWaitDialog; + delete mSpellCreationDialog; cleanupGarbage(); @@ -259,6 +263,7 @@ void WindowManager::updateVisible() mQuickKeysMenu->setVisible(false); mLevelupDialog->setVisible(false); mWaitDialog->setVisible(false); + mSpellCreationDialog->setVisible(false); mHud->setVisible(true); @@ -359,6 +364,9 @@ void WindowManager::updateVisible() case GM_SpellBuying: mSpellBuyingWindow->setVisible(true); break; + case GM_SpellCreation: + mSpellCreationDialog->setVisible(true); + break; case GM_InterMessageBox: break; case GM_Journal: @@ -561,6 +569,7 @@ void WindowManager::onFrame (float frameDuration) mDialogueWindow->checkReferenceAvailable(); mTradeWindow->checkReferenceAvailable(); mSpellBuyingWindow->checkReferenceAvailable(); + mSpellCreationDialog->checkReferenceAvailable(); mContainerWindow->checkReferenceAvailable(); mConsole->checkReferenceAvailable(); } @@ -960,3 +969,8 @@ void WindowManager::addVisitedLocation(const std::string& name, int x, int y) { mMap->addVisitedLocation (name, x, y); } + +void WindowManager::startSpellMaking(MWWorld::Ptr actor) +{ + mSpellCreationDialog->startSpellMaking (actor); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index d7773e261..ec9fe8fae 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -64,6 +64,8 @@ namespace MWGui class LoadingScreen; class LevelupDialog; class WaitDialog; + class SpellCreationDialog; + class WindowManager : public MWBase::WindowManager { @@ -210,6 +212,8 @@ namespace MWGui virtual bool getPlayerSleeping(); + virtual void startSpellMaking(MWWorld::Ptr actor); + private: OEngine::GUI::MyGUIManager *mGuiManager; HUD *mHud; @@ -237,6 +241,7 @@ namespace MWGui LoadingScreen* mLoadingScreen; LevelupDialog* mLevelupDialog; WaitDialog* mWaitDialog; + SpellCreationDialog* mSpellCreationDialog; CharacterCreation* mCharGen; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index ae8d3afbe..2a1bf7510 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -75,6 +75,7 @@ set(MYGUI_FILES openmw_levelup_dialog.layout openmw_wait_dialog.layout openmw_wait_dialog_progressbar.layout + openmw_spellcreation_dialog.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_spellcreation_dialog.layout b/files/mygui/openmw_spellcreation_dialog.layout new file mode 100644 index 000000000..2013fece8 --- /dev/null +++ b/files/mygui/openmw_spellcreation_dialog.layout @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/mygui/openmw_tooltips.layout b/files/mygui/openmw_tooltips.layout index 148e98064..514d1a25b 100644 --- a/files/mygui/openmw_tooltips.layout +++ b/files/mygui/openmw_tooltips.layout @@ -196,6 +196,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + From d393f551ed4b3e4bc242676da87cebf63fcbbb71 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 24 Sep 2012 08:09:16 +0200 Subject: [PATCH 002/255] edit effect dialog --- apps/openmw/mwgui/list.cpp | 1 + apps/openmw/mwgui/list.hpp | 8 ++ apps/openmw/mwgui/spellcreationdialog.cpp | 92 +++++++++++++++++++++++ apps/openmw/mwgui/spellcreationdialog.hpp | 44 +++++++++++ files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_edit_effect.layout | 88 ++++++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 files/mygui/openmw_edit_effect.layout diff --git a/apps/openmw/mwgui/list.cpp b/apps/openmw/mwgui/list.cpp index ff23f8b31..0bafced97 100644 --- a/apps/openmw/mwgui/list.cpp +++ b/apps/openmw/mwgui/list.cpp @@ -128,6 +128,7 @@ void MWList::onItemSelected(MyGUI::Widget* _sender) std::string name = static_cast(_sender)->getCaption(); eventItemSelected(name); + eventWidgetSelected(_sender); } MyGUI::Widget* MWList::getItemWidget(const std::string& name) diff --git a/apps/openmw/mwgui/list.hpp b/apps/openmw/mwgui/list.hpp index c1f2d83b5..d07d49de6 100644 --- a/apps/openmw/mwgui/list.hpp +++ b/apps/openmw/mwgui/list.hpp @@ -18,6 +18,7 @@ namespace MWGui MWList(); typedef MyGUI::delegates::CMultiDelegate1 EventHandle_String; + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Widget; /** * Event: Item selected with the mouse. @@ -25,6 +26,13 @@ namespace MWGui */ EventHandle_String eventItemSelected; + /** + * Event: Item selected with the mouse. + * signature: void method(MyGUI::Widget* sender) + */ + EventHandle_Widget eventWidgetSelected; + + /** * Call after the size of the list changed, or items were inserted/removed */ diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index fd5e9594c..b1748edf8 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -29,8 +29,86 @@ namespace namespace MWGui { + EditEffectDialog::EditEffectDialog(MWBase::WindowManager &parWindowManager) + : WindowModal("openmw_edit_effect.layout", parWindowManager) + , mRange(ESM::RT_Touch) + { + getWidget(mCancelButton, "CancelButton"); + getWidget(mOkButton, "OkButton"); + getWidget(mDeleteButton, "DeleteButton"); + getWidget(mRangeButton, "RangeButton"); + getWidget(mMagnitudeMinValue, "MagnitudeMinValue"); + getWidget(mMagnitudeMaxValue, "MagnitudeMaxValue"); + getWidget(mDurationValue, "DurationValue"); + getWidget(mAreaValue, "AreaValue"); + getWidget(mMagnitudeMinSlider, "MagnitudeMinSlider"); + getWidget(mMagnitudeMaxSlider, "MagnitudeMaxSlider"); + getWidget(mDurationSlider, "DurationSlider"); + getWidget(mAreaSlider, "AreaSlider"); + getWidget(mEffectImage, "EffectImage"); + getWidget(mEffectName, "EffectName"); + getWidget(mAreaText, "AreaText"); + + mRangeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onRangeButtonClicked); + mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onOkButtonClicked); + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onCancelButtonClicked); + mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onDeleteButtonClicked); + } + + void EditEffectDialog::open() + { + WindowModal::open(); + center(); + } + + void EditEffectDialog::setEffect (const ESM::MagicEffect *effect) + { + std::string icon = effect->icon; + icon[icon.size()-3] = 'd'; + icon[icon.size()-2] = 'd'; + icon[icon.size()-1] = 's'; + icon = "icons\\" + icon; + + mEffectImage->setImageTexture (icon); + + mEffectName->setCaptionWithReplacing("#{"+Widgets::MWSpellEffect::effectIDToString (effect->index)+"}"); + } + + void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) + { + mRange = (mRange+1)%3; + + if (mRange == ESM::RT_Self) + mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}"); + else if (mRange == ESM::RT_Target) + mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}"); + else if (mRange == ESM::RT_Touch) + mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}"); + + mAreaSlider->setVisible (mRange != ESM::RT_Self); + mAreaText->setVisible (mRange != ESM::RT_Self); + } + + void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender) + { + + } + + void EditEffectDialog::onOkButtonClicked (MyGUI::Widget* sender) + { + setVisible(false); + } + + void EditEffectDialog::onCancelButtonClicked (MyGUI::Widget* sender) + { + setVisible(false); + } + + // ------------------------------------------------------------------------------------------------ + SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_spellcreation_dialog.layout", parWindowManager) + , mAddEffectDialog(parWindowManager) { getWidget(mNameEdit, "NameEdit"); getWidget(mMagickaCost, "MagickaCost"); @@ -41,8 +119,12 @@ namespace MWGui getWidget(mBuyButton, "BuyButton"); getWidget(mCancelButton, "CancelButton"); + mAddEffectDialog.setVisible(false); + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onCancelButtonClicked); mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onBuyButtonClicked); + + mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onAvailableEffectClicked); } @@ -101,6 +183,7 @@ namespace MWGui std::string name = MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find( MWGui::Widgets::MWSpellEffect::effectIDToString (*it))->getString(); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); + w->setUserData(*it); ToolTips::createMagicEffectToolTip (w, *it); } @@ -117,4 +200,13 @@ namespace MWGui } + void SpellCreationDialog::onAvailableEffectClicked (MyGUI::Widget* sender) + { + mAddEffectDialog.setVisible(true); + + short effectId = *sender->getUserData(); + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId); + mAddEffectDialog.setEffect (effect); + } + } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index d0919ced0..8ea8ebb2d 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -8,6 +8,47 @@ namespace MWGui { + class EditEffectDialog : public WindowModal + { + public: + EditEffectDialog(MWBase::WindowManager& parWindowManager); + + virtual void open(); + + void setEffect (const ESM::MagicEffect* effect); + + protected: + MyGUI::Button* mCancelButton; + MyGUI::Button* mOkButton; + MyGUI::Button* mDeleteButton; + + MyGUI::Button* mRangeButton; + + MyGUI::TextBox* mMagnitudeMinValue; + MyGUI::TextBox* mMagnitudeMaxValue; + MyGUI::TextBox* mDurationValue; + MyGUI::TextBox* mAreaValue; + + MyGUI::ScrollBar* mMagnitudeMinSlider; + MyGUI::ScrollBar* mMagnitudeMaxSlider; + MyGUI::ScrollBar* mDurationSlider; + MyGUI::ScrollBar* mAreaSlider; + + MyGUI::ScrollBar* mAreaText; + + MyGUI::ImageBox* mEffectImage; + MyGUI::TextBox* mEffectName; + + protected: + void onRangeButtonClicked (MyGUI::Widget* sender); + void onDeleteButtonClicked (MyGUI::Widget* sender); + void onOkButtonClicked (MyGUI::Widget* sender); + void onCancelButtonClicked (MyGUI::Widget* sender); + + protected: + int mRange; + }; + class SpellCreationDialog : public WindowBase, public ReferenceInterface { public: @@ -22,6 +63,7 @@ namespace MWGui void onCancelButtonClicked (MyGUI::Widget* sender); void onBuyButtonClicked (MyGUI::Widget* sender); + void onAvailableEffectClicked (MyGUI::Widget* sender); MyGUI::EditBox* mNameEdit; @@ -33,6 +75,8 @@ namespace MWGui MyGUI::Button* mCancelButton; MyGUI::TextBox* mPriceLabel; + EditEffectDialog mAddEffectDialog; + }; } diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 2a1bf7510..d948a4cf7 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -76,6 +76,7 @@ set(MYGUI_FILES openmw_wait_dialog.layout openmw_wait_dialog_progressbar.layout openmw_spellcreation_dialog.layout + openmw_edit_effect.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_edit_effect.layout b/files/mygui/openmw_edit_effect.layout new file mode 100644 index 000000000..884723feb --- /dev/null +++ b/files/mygui/openmw_edit_effect.layout @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b63d205c6e5dcb8ff36377a91ad831913bdb6000 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 24 Sep 2012 22:09:38 +0200 Subject: [PATCH 003/255] change the select attribute/skill dialogs to be reusable --- apps/openmw/mwgui/class.cpp | 18 ++++++++---------- apps/openmw/mwgui/class.hpp | 10 +++------- apps/openmw/mwgui/spellcreationdialog.cpp | 23 +++++++++++++++-------- apps/openmw/mwgui/spellcreationdialog.hpp | 10 ++++++++-- apps/openmw/mwgui/widgets.hpp | 10 ++++++---- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 309aa5a5d..06fa325b6 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -565,7 +565,7 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) { delete mAttribDialog; mAttribDialog = new SelectAttributeDialog(mWindowManager); - mAttribDialog->setAffectedWidget(_sender); + mAffectedAttribute = _sender; mAttribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); mAttribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); mAttribDialog->setVisible(true); @@ -574,18 +574,17 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) void CreateClassDialog::onAttributeSelected() { ESM::Attribute::AttributeID id = mAttribDialog->getAttributeId(); - Widgets::MWAttributePtr attribute = mAttribDialog->getAffectedWidget(); - if (attribute == mFavoriteAttribute0) + if (mAffectedAttribute == mFavoriteAttribute0) { if (mFavoriteAttribute1->getAttributeId() == id) mFavoriteAttribute1->setAttributeId(mFavoriteAttribute0->getAttributeId()); } - else if (attribute == mFavoriteAttribute1) + else if (mAffectedAttribute == mFavoriteAttribute1) { if (mFavoriteAttribute0->getAttributeId() == id) mFavoriteAttribute0->setAttributeId(mFavoriteAttribute1->getAttributeId()); } - attribute->setAttributeId(id); + mAffectedAttribute->setAttributeId(id); mWindowManager.removeDialog(mAttribDialog); mAttribDialog = 0; @@ -596,7 +595,7 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) { delete mSkillDialog; mSkillDialog = new SelectSkillDialog(mWindowManager); - mSkillDialog->setAffectedWidget(_sender); + mAffectedSkill = _sender; mSkillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); mSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); mSkillDialog->setVisible(true); @@ -605,22 +604,21 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) void CreateClassDialog::onSkillSelected() { ESM::Skill::SkillEnum id = mSkillDialog->getSkillId(); - Widgets::MWSkillPtr skill = mSkillDialog->getAffectedWidget(); // Avoid duplicate skills by swapping any skill field that matches the selected one std::vector::const_iterator end = mSkills.end(); for (std::vector::const_iterator it = mSkills.begin(); it != end; ++it) { - if (*it == skill) + if (*it == mAffectedSkill) continue; if ((*it)->getSkillId() == id) { - (*it)->setSkillId(skill->getSkillId()); + (*it)->setSkillId(mAffectedSkill->getSkillId()); break; } } - skill->setSkillId(mSkillDialog->getSkillId()); + mAffectedSkill->setSkillId(mSkillDialog->getSkillId()); mWindowManager.removeDialog(mSkillDialog); mSkillDialog = 0; update(); diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 94e8558d0..c7699b308 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -167,8 +167,6 @@ namespace MWGui ~SelectAttributeDialog(); ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; } - Widgets::MWAttributePtr getAffectedWidget() const { return mAffectedWidget; } - void setAffectedWidget(Widgets::MWAttributePtr widget) { mAffectedWidget = widget; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -188,8 +186,6 @@ namespace MWGui void onCancelClicked(MyGUI::Widget* _sender); private: - Widgets::MWAttributePtr mAffectedWidget; - ESM::Attribute::AttributeID mAttributeId; }; @@ -200,8 +196,6 @@ namespace MWGui ~SelectSkillDialog(); ESM::Skill::SkillEnum getSkillId() const { return mSkillId; } - Widgets::MWSkillPtr getAffectedWidget() const { return mAffectedWidget; } - void setAffectedWidget(Widgets::MWSkillPtr widget) { mAffectedWidget = widget; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -224,7 +218,6 @@ namespace MWGui Widgets::MWSkillPtr mCombatSkill[9]; Widgets::MWSkillPtr mMagicSkill[9]; Widgets::MWSkillPtr mStealthSkill[9]; - Widgets::MWSkillPtr mAffectedWidget; ESM::Skill::SkillEnum mSkillId; }; @@ -301,6 +294,9 @@ namespace MWGui DescriptionDialog *mDescDialog; ESM::Class::Specialization mSpecializationId; + + Widgets::MWAttributePtr mAffectedAttribute; + Widgets::MWSkillPtr mAffectedSkill; }; } #endif diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index b1748edf8..637e99d34 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -31,7 +31,6 @@ namespace MWGui EditEffectDialog::EditEffectDialog(MWBase::WindowManager &parWindowManager) : WindowModal("openmw_edit_effect.layout", parWindowManager) - , mRange(ESM::RT_Touch) { getWidget(mCancelButton, "CancelButton"); getWidget(mOkButton, "OkButton"); @@ -59,6 +58,10 @@ namespace MWGui { WindowModal::open(); center(); + + mEffect.range = ESM::RT_Self; + + onRangeButtonClicked(mRangeButton); } void EditEffectDialog::setEffect (const ESM::MagicEffect *effect) @@ -76,17 +79,17 @@ namespace MWGui void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) { - mRange = (mRange+1)%3; + mEffect.range = (mEffect.range+1)%3; - if (mRange == ESM::RT_Self) + if (mEffect.range == ESM::RT_Self) mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}"); - else if (mRange == ESM::RT_Target) + else if (mEffect.range == ESM::RT_Target) mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}"); - else if (mRange == ESM::RT_Touch) + else if (mEffect.range == ESM::RT_Touch) mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}"); - mAreaSlider->setVisible (mRange != ESM::RT_Self); - mAreaText->setVisible (mRange != ESM::RT_Self); + mAreaSlider->setVisible (mEffect.range != ESM::RT_Self); + mAreaText->setVisible (mEffect.range != ESM::RT_Self); } void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender) @@ -109,6 +112,8 @@ namespace MWGui SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_spellcreation_dialog.layout", parWindowManager) , mAddEffectDialog(parWindowManager) + , mSelectAttributeDialog(NULL) + , mSelectSkillDialog(NULL) { getWidget(mNameEdit, "NameEdit"); getWidget(mMagickaCost, "MagickaCost"); @@ -202,10 +207,12 @@ namespace MWGui void SpellCreationDialog::onAvailableEffectClicked (MyGUI::Widget* sender) { - mAddEffectDialog.setVisible(true); short effectId = *sender->getUserData(); const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId); + + + mAddEffectDialog.setVisible(true); mAddEffectDialog.setEffect (effect); } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 8ea8ebb2d..a2db719a7 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -8,6 +8,9 @@ namespace MWGui { + class SelectSkillDialog; + class SelectAttributeDialog; + class EditEffectDialog : public WindowModal { public: @@ -34,7 +37,7 @@ namespace MWGui MyGUI::ScrollBar* mDurationSlider; MyGUI::ScrollBar* mAreaSlider; - MyGUI::ScrollBar* mAreaText; + MyGUI::TextBox* mAreaText; MyGUI::ImageBox* mEffectImage; MyGUI::TextBox* mEffectName; @@ -46,7 +49,7 @@ namespace MWGui void onCancelButtonClicked (MyGUI::Widget* sender); protected: - int mRange; + ESM::ENAMstruct mEffect; }; class SpellCreationDialog : public WindowBase, public ReferenceInterface @@ -77,6 +80,9 @@ namespace MWGui EditEffectDialog mAddEffectDialog; + SelectAttributeDialog* mSelectAttributeDialog; + SelectSkillDialog* mSelectSkillDialog; + }; } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 899ceadd9..cc733122c 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -250,10 +250,12 @@ namespace MWGui void setSpellEffect(const SpellEffectParams& params); static std::string effectIDToString(const short effectID); - bool effectHasMagnitude (const std::string& effect); - bool effectHasDuration (const std::string& effect); - bool effectInvolvesAttribute (const std::string& effect); - bool effectInvolvesSkill (const std::string& effect); + + /// \todo Remove all of these! The information can be obtained via the ESM::MagicEffect's flags! + static bool effectHasMagnitude (const std::string& effect); + static bool effectHasDuration (const std::string& effect); + static bool effectInvolvesAttribute (const std::string& effect); + static bool effectInvolvesSkill (const std::string& effect); int getRequestedWidth() const { return mRequestedWidth; } From 3060fbee603cc8b4dcaff65a00b70b9da722a200 Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 26 Sep 2012 18:30:47 +0200 Subject: [PATCH 004/255] TravelGUI, not completly finished. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/windowmanager.hpp | 2 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 4 + apps/openmw/mwgui/dialogue.cpp | 14 +- apps/openmw/mwgui/dialogue.hpp | 2 + apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/travelwindow.cpp | 159 ++++++++++++++++++ apps/openmw/mwgui/travelwindow.hpp | 57 +++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 9 + apps/openmw/mwgui/windowmanagerimp.hpp | 2 + 10 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 apps/openmw/mwgui/travelwindow.cpp create mode 100644 apps/openmw/mwgui/travelwindow.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66844b280..e140f0db2 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu - itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog + itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog travelwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 429163136..e6b9c6455 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -42,6 +42,7 @@ namespace MWGui class Console; class SpellWindow; class TradeWindow; + class TravelWindow; class SpellBuyingWindow; class ConfirmationDialog; class CountDialog; @@ -108,6 +109,7 @@ namespace MWBase virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0; virtual MWGui::TradeWindow* getTradeWindow() = 0; virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow() = 0; + virtual MWGui::TravelWindow* getTravelWindow() = 0; virtual MWGui::SpellWindow* getSpellWindow() = 0; virtual MWGui::Console* getConsole() = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 1b7532d0a..34d4a7981 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -798,6 +798,10 @@ namespace MWDialogue win->setShowSpells(true); else win->setShowSpells(false); + if( !mActor.get()->base->mTransport.empty()) + win->setShowTravel(true); + else + win->setShowTravel(false); // sort again, because the previous sort was case-sensitive keywordList.sort(stringCompareNoCase); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 245487a04..860da5125 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -19,6 +19,7 @@ #include "tradewindow.hpp" #include "spellbuyingwindow.hpp" #include "inventorywindow.hpp" +#include "travelwindow.hpp" using namespace MWGui; using namespace Widgets; @@ -134,7 +135,13 @@ void DialogueWindow::onSelectTopic(std::string topic) mWindowManager.pushGuiMode(GM_SpellBuying); mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); } - + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()) + { + std::cout << "travel!"; + mWindowManager.pushGuiMode(GM_Travel); + mWindowManager.getTravelWindow()->startTravel(mPtr); + //mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); + } else MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -163,7 +170,10 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mShowSpells) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString()); - if (anyService) + if(mShowTravel) + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()); + + if (anyService || mShowTravel) mTopicsList->addSeparator(); for(std::list::iterator it = keyWords.begin(); it != keyWords.end(); ++it) diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index a43b0d5a7..caa5c7dc4 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -52,6 +52,7 @@ namespace MWGui // make sure to call these before setKeywords() void setShowTrade(bool show) { mShowTrade = show; } void setShowSpells(bool show) { mShowSpells = show; } + void setShowTravel(bool show) { mShowTravel = show; } protected: void onSelectTopic(std::string topic); @@ -72,6 +73,7 @@ namespace MWGui // various service button visibilities, depending if the npc/creature talked to has these services bool mShowTrade; bool mShowSpells; + bool mShowTravel; bool mEnabled; diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 64aa1dc21..4dd642f6d 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -22,6 +22,7 @@ namespace MWGui GM_Rest, GM_RestBed, GM_SpellBuying, + GM_Travel, GM_Levelup, diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp new file mode 100644 index 000000000..91966e19b --- /dev/null +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -0,0 +1,159 @@ +#include "travelwindow.hpp" + +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/manualref.hpp" + +#include "../mwmechanics/spells.hpp" +#include "../mwmechanics/creaturestats.hpp" + +#include "inventorywindow.hpp" +#include "tradewindow.hpp" + +namespace MWGui +{ + const int TravelWindow::sLineHeight = 18; + + TravelWindow::TravelWindow(MWBase::WindowManager& parWindowManager) : + WindowBase("openmw_spell_buying_window.layout", parWindowManager) + , ContainerBase(NULL) // no drag&drop + , mCurrentY(0) + , mLastPos(0) + { + setCoord(0, 0, 450, 300); + + getWidget(mCancelButton, "CancelButton"); + getWidget(mPlayerGold, "PlayerGold"); + getWidget(mSelect, "Select"); + getWidget(mDestinations, "Spells"); + getWidget(mDestinationsView, "SpellsView"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked); + + mDestinations->setCoord(450/2-mDestinations->getTextSize().width/2, + mDestinations->getTop(), + mDestinations->getTextSize().width, + mDestinations->getHeight()); + mSelect->setCoord(8, + mSelect->getTop(), + mSelect->getTextSize().width, + mSelect->getHeight()); + } + + void TravelWindow::addDestination(const std::string& travelId) + { + //std::cout << "travel to" << travelId; + /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); + int price = spell->data.cost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat();*/ + int price = 0; + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + mCurrentY += sLineHeight; + /// \todo price adjustment depending on merchantile skill + toAdd->setUserData(price); + toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); + toAdd->setSize(toAdd->getTextSize().width,sLineHeight); + toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); + toAdd->setUserString("ToolTipType", "Spell"); + toAdd->setUserString("Spell", travelId); + toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); + mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); + } + + void TravelWindow::clearDestinations() + { + mDestinationsView->setViewOffset(MyGUI::IntPoint(0,0)); + mCurrentY = 0; + while (mDestinationsView->getChildCount()) + MyGUI::Gui::getInstance().destroyWidget(mDestinationsView->getChildAt(0)); + mDestinationsWidgetMap.clear(); + } + + void TravelWindow::startTravel(const MWWorld::Ptr& actor) + { + center(); + mActor = actor; + clearDestinations(); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + /*MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells(); + MWMechanics::Spells& merchantSpells = MWWorld::Class::get (actor).getCreatureStats (actor).getSpells(); + + for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find (*iter); + + if (spell->data.type!=ESM::Spell::ST_Spell) + continue; // don't try to sell diseases, curses or powers + + if (std::find (playerSpells.begin(), playerSpells.end(), *iter)!=playerSpells.end()) + continue; // we have that spell already + + addDestination (*iter); + }*/ + + for(int i = 0;i()->base->mTransport.size();i++) + { + addDestination(mActor.get()->base->mTransport[i].mCellName); + } + + updateLabels(); + + mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); + } + + void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) + { + /*int price = *_sender->getUserData(); + + if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) + { + 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 (mSpellsWidgetMap.find(_sender)->second); + mWindowManager.getTradeWindow()->addOrRemoveGold(-price); + startSpellBuying(mActor); + + MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); + }*/ + } + + void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) + { + mWindowManager.removeGuiMode(GM_Travel); + } + + void TravelWindow::updateLabels() + { + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + mPlayerGold->setCoord(8, + mPlayerGold->getTop(), + mPlayerGold->getTextSize().width, + mPlayerGold->getHeight()); + } + + void TravelWindow::onReferenceUnavailable() + { + // remove both Spells and Dialogue (since you always trade with the NPC/creature that you have previously talked to) + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + } + + void TravelWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) + { + if (mDestinationsView->getViewOffset().top + _rel*0.3 > 0) + mDestinationsView->setViewOffset(MyGUI::IntPoint(0, 0)); + else + mDestinationsView->setViewOffset(MyGUI::IntPoint(0, mDestinationsView->getViewOffset().top + _rel*0.3)); + } +} + diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp new file mode 100644 index 000000000..07a516ce8 --- /dev/null +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -0,0 +1,57 @@ +#ifndef MWGUI_TravelWINDOW_H +#define MWGUI_TravelWINDOW_H + +#include "container.hpp" +#include "window_base.hpp" + +#include "../mwworld/ptr.hpp" + +namespace MyGUI +{ + class Gui; + class Widget; +} + +namespace MWGui +{ + class WindowManager; +} + + +namespace MWGui +{ + class TravelWindow : public ContainerBase, public WindowBase + { + public: + TravelWindow(MWBase::WindowManager& parWindowManager); + + void startTravel(const MWWorld::Ptr& actor); + + protected: + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; + MyGUI::TextBox* mDestinations; + MyGUI::TextBox* mSelect; + + MyGUI::ScrollView* mDestinationsView; + + MWWorld::Ptr mActor; + + std::map mDestinationsWidgetMap; + + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onTravelButtonClick(MyGUI::Widget* _sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void addDestination(const std::string& destinationID); + void clearDestinations(); + int mLastPos,mCurrentY; + + static const int sLineHeight; + + void updateLabels(); + + virtual void onReferenceUnavailable(); + }; +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5a04a90c0..811edcba0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -38,6 +38,7 @@ #include "countdialog.hpp" #include "tradewindow.hpp" #include "spellbuyingwindow.hpp" +#include "travelwindow.hpp" #include "settingswindow.hpp" #include "confirmationdialog.hpp" #include "alchemywindow.hpp" @@ -67,6 +68,7 @@ WindowManager::WindowManager( , mCountDialog(NULL) , mTradeWindow(NULL) , mSpellBuyingWindow(NULL) + , mTravelWindow(NULL) , mSettingsWindow(NULL) , mConfirmationDialog(NULL) , mAlchemyWindow(NULL) @@ -141,6 +143,7 @@ WindowManager::WindowManager( mInventoryWindow = new InventoryWindow(*this,mDragAndDrop); mTradeWindow = new TradeWindow(*this); mSpellBuyingWindow = new SpellBuyingWindow(*this); + mTravelWindow = new TravelWindow(*this); mDialogueWindow = new DialogueWindow(*this); mContainerWindow = new ContainerWindow(*this,mDragAndDrop); mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop); @@ -203,6 +206,7 @@ WindowManager::~WindowManager() delete mScrollWindow; delete mTradeWindow; delete mSpellBuyingWindow; + delete mTravelWindow; delete mSettingsWindow; delete mConfirmationDialog; delete mAlchemyWindow; @@ -253,6 +257,7 @@ void WindowManager::updateVisible() mBookWindow->setVisible(false); mTradeWindow->setVisible(false); mSpellBuyingWindow->setVisible(false); + mTravelWindow->setVisible(false); mSettingsWindow->setVisible(false); mAlchemyWindow->setVisible(false); mSpellWindow->setVisible(false); @@ -359,6 +364,9 @@ void WindowManager::updateVisible() case GM_SpellBuying: mSpellBuyingWindow->setVisible(true); break; + case GM_Travel: + mTravelWindow->setVisible(true); + break; case GM_InterMessageBox: break; case GM_Journal: @@ -844,6 +852,7 @@ MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; } MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; } MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; } MWGui::SpellBuyingWindow* WindowManager::getSpellBuyingWindow() { return mSpellBuyingWindow; } +MWGui::TravelWindow* WindowManager::getTravelWindow() { return mTravelWindow; } MWGui::SpellWindow* WindowManager::getSpellWindow() { return mSpellWindow; } MWGui::Console* WindowManager::getConsole() { return mConsole; } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index d7773e261..635a7483c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -111,6 +111,7 @@ namespace MWGui virtual MWGui::ConfirmationDialog* getConfirmationDialog(); virtual MWGui::TradeWindow* getTradeWindow(); virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow(); + virtual MWGui::TravelWindow* getTravelWindow(); virtual MWGui::SpellWindow* getSpellWindow(); virtual MWGui::Console* getConsole(); @@ -229,6 +230,7 @@ namespace MWGui CountDialog* mCountDialog; TradeWindow* mTradeWindow; SpellBuyingWindow* mSpellBuyingWindow; + TravelWindow* mTravelWindow; SettingsWindow* mSettingsWindow; ConfirmationDialog* mConfirmationDialog; AlchemyWindow* mAlchemyWindow; From cd343c4fbd5a99d12126fdc99fa61c03e60e0409 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 27 Sep 2012 11:59:40 +0200 Subject: [PATCH 005/255] Issue #61: Basic alchemy class (doesn't do anything yet) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/alchemywindow.cpp | 4 +++- apps/openmw/mwgui/alchemywindow.hpp | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66844b280..69cfb2fd5 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -61,7 +61,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells - activespells npcstats aipackage aisequence + activespells npcstats aipackage aisequence alchemy ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 308029810..6fd88d5ca 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -253,8 +253,10 @@ namespace MWGui void AlchemyWindow::open() { - openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr setFilter(ContainerBase::Filter_Ingredients); + + mAlchemy.setAlchemist (mPtr); // pick the best available apparatus MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 53e7178d5..67378d7de 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -1,6 +1,8 @@ #ifndef MWGUI_ALCHEMY_H #define MWGUI_ALCHEMY_H +#include "../mwmechanics/alchemy.hpp" + #include "window_base.hpp" #include "container.hpp" #include "widgets.hpp" @@ -46,6 +48,10 @@ namespace MWGui virtual void onReferenceUnavailable() { ; } void update(); + + private: + + MWMechanics::Alchemy mAlchemy; }; } From 1971ba66f18cccd06b60b63b7b29c06e46ebf7de Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 27 Sep 2012 13:08:38 +0200 Subject: [PATCH 006/255] destination name is now OK for every trave services --- apps/openmw/mwgui/travelwindow.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 91966e19b..9e7b0a975 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -102,7 +102,12 @@ namespace MWGui for(int i = 0;i()->base->mTransport.size();i++) { - addDestination(mActor.get()->base->mTransport[i].mCellName); + std::string cellname = mActor.get()->base->mTransport[i].mCellName; + int x,y; + MWBase::Environment::get().getWorld()->positionToIndex(mActor.get()->base->mTransport[i].mPos.pos[0], + mActor.get()->base->mTransport[i].mPos.pos[1],x,y); + if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; + addDestination(cellname); } updateLabels(); From 636f297f10fd41e5c083a0b02f2edda7ff3de22e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 28 Sep 2012 16:52:42 +0200 Subject: [PATCH 007/255] enchant --- files/mygui/core_layouteditor.xml | 2 +- files/mygui/openmw_enchanting_dialog.layout | 88 +++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/files/mygui/core_layouteditor.xml b/files/mygui/core_layouteditor.xml index 740f129cc..db917b6ef 100644 --- a/files/mygui/core_layouteditor.xml +++ b/files/mygui/core_layouteditor.xml @@ -3,7 +3,7 @@ - + diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index 1d622244a..ea8156056 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -3,6 +3,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4d496c11880d8f41dda20e5e2c0e36e60ab052e3 Mon Sep 17 00:00:00 2001 From: gugus Date: Fri, 28 Sep 2012 17:02:27 +0200 Subject: [PATCH 008/255] correction1 --- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwgui/tradewindow.hpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 14 +++++++------- apps/openmw/mwrender/globalmap.cpp | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index fc4220fc3..74cae380b 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -16,7 +16,7 @@ namespace MWGui { TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_trade_window.layout", parWindowManager) - , ContainerBase(NULL) // no drag&drop + , ReferenceInterface(NULL) // no drag&drop , mCurrentBalance(0) { MyGUI::ScrollView* itemView; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 4ec55045c..7ca3a97b4 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TradeWindow : public ContainerBase, public WindowBase + class TradeWindow : public ReferenceInterface, public WindowBase { public: TradeWindow(MWBase::WindowManager& parWindowManager); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 9e7b0a975..f561a2c99 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -79,7 +79,7 @@ namespace MWGui void TravelWindow::startTravel(const MWWorld::Ptr& actor) { center(); - mActor = actor; + mPtr = actor; clearDestinations(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -100,18 +100,18 @@ namespace MWGui addDestination (*iter); }*/ - for(int i = 0;i()->base->mTransport.size();i++) + for(int i = 0;i()->base->mTransport.size();i++) { - std::string cellname = mActor.get()->base->mTransport[i].mCellName; + std::string cellname = mPtr.get()->base->mTransport[i].mCellName; int x,y; - MWBase::Environment::get().getWorld()->positionToIndex(mActor.get()->base->mTransport[i].mPos.pos[0], - mActor.get()->base->mTransport[i].mPos.pos[1],x,y); + MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->base->mTransport[i].mPos.pos[0], + mPtr.get()->base->mTransport[i].mPos.pos[1],x,y); if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; addDestination(cellname); } updateLabels(); - + mPtr.get()->base->mTransport[0]. mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); } @@ -126,7 +126,7 @@ namespace MWGui MWMechanics::Spells& spells = stats.getSpells(); spells.add (mSpellsWidgetMap.find(_sender)->second); mWindowManager.getTradeWindow()->addOrRemoveGold(-price); - startSpellBuying(mActor); + startSpellBuying(mPtr); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); }*/ diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 5e0a63c77..dd30a68f7 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -53,7 +53,8 @@ namespace MWRender { Ogre::Image image; - Ogre::uchar data[mWidth * mHeight * 3]; + std::vector data; + data.resize(mWidth * mHeight * 3); for (int x = mMinX; x <= mMaxX; ++x) { @@ -150,7 +151,7 @@ namespace MWRender } } - image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8); + image.loadDynamicImage (data.data(), mWidth, mHeight, Ogre::PF_B8G8R8); //image.save (mCacheDir + "/GlobalMap.png"); From c6fd864a76e010807a512e85f4a1c4a5078de4db Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 29 Sep 2012 10:02:46 +0200 Subject: [PATCH 009/255] Issue #61: Forgot to add some files --- apps/openmw/mwmechanics/alchemy.cpp | 7 +++++++ apps/openmw/mwmechanics/alchemy.hpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 apps/openmw/mwmechanics/alchemy.cpp create mode 100644 apps/openmw/mwmechanics/alchemy.hpp diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp new file mode 100644 index 000000000..ea5cbe965 --- /dev/null +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -0,0 +1,7 @@ + +#include "alchemy.hpp" + +void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) +{ + mNpc = npc; +} diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp new file mode 100644 index 000000000..93c50f1ff --- /dev/null +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -0,0 +1,22 @@ +#ifndef GAME_MWMECHANICS_ALCHEMY_H +#define GAME_MWMECHANICS_ALCHEMY_H + +#include "../mwworld/ptr.hpp" + +namespace MWMechanics +{ + /// \brief Potion creatin via alchemy skill + class Alchemy + { + MWWorld::Ptr mNpc; + + public: + + void setAlchemist (const MWWorld::Ptr& npc); + ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that + /// there is no alchemist (alchemy session has ended). + }; +} + +#endif + From 42f02f3ccd2b11e06868587871174661448865e3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 30 Sep 2012 18:54:20 +0200 Subject: [PATCH 010/255] Issue #61: Re-implemented tool selection in Alchemy class --- apps/openmw/mwmechanics/alchemy.cpp | 39 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 14 +++++++++++ 2 files changed, 53 insertions(+) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index ea5cbe965..0a0189190 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,7 +1,46 @@ #include "alchemy.hpp" +#include +#include + +#include "../mwworld/containerstore.hpp" +#include "../mwworld/class.hpp" + void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mNpc = npc; + + mTools.resize (4); + + std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); + + MWWorld::ContainerStore& store = MWWorld::Class::get (npc).getContainerStore (npc); + + for (MWWorld::ContainerStoreIterator iter (store.begin (MWWorld::ContainerStore::Type_Apparatus)); + iter!=store.end(); ++iter) + { + MWWorld::LiveCellRef* ref = iter->get(); + + int type = ref->base->data.type; + + if (type<0 || type>=static_cast (mTools.size())) + throw std::runtime_error ("invalid apparatus type"); + + if (!mTools[type].isEmpty()) + if (ref->base->data.quality<=mTools[type].get()->base->data.quality) + continue; + + mTools[type] = *iter; + } +} + +MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::beginTools() const +{ + return mTools.begin(); +} + +MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::endTools() const +{ + return mTools.end(); } diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 93c50f1ff..fcaba9012 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_ALCHEMY_H #define GAME_MWMECHANICS_ALCHEMY_H +#include + #include "../mwworld/ptr.hpp" namespace MWMechanics @@ -8,13 +10,25 @@ namespace MWMechanics /// \brief Potion creatin via alchemy skill class Alchemy { + public: + + typedef std::vector TToolsContainer; + typedef TToolsContainer::const_iterator TToolsIterator; + + private: + MWWorld::Ptr mNpc; + TToolsContainer mTools; public: void setAlchemist (const MWWorld::Ptr& npc); ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that /// there is no alchemist (alchemy session has ended). + + TToolsIterator beginTools() const; + + TToolsIterator endTools() const; }; } From 10c8360e07c1a31862f162d234c731829a0aba52 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 30 Sep 2012 19:05:45 +0200 Subject: [PATCH 011/255] Issue #61: Replaced apparatus handling in alchemy GUI with new implementation in Alchemy class --- apps/openmw/mwgui/alchemywindow.cpp | 72 +++++++---------------------- apps/openmw/mwgui/alchemywindow.hpp | 9 ++-- 2 files changed, 21 insertions(+), 60 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 6fd88d5ca..26bd9668e 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -28,7 +28,7 @@ namespace MWGui { AlchemyWindow::AlchemyWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_alchemy_window.layout", parWindowManager) - , ContainerBase(0) + , ContainerBase(0), mApparatus (4) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); @@ -36,10 +36,10 @@ namespace MWGui getWidget(mIngredient2, "Ingredient2"); getWidget(mIngredient3, "Ingredient3"); getWidget(mIngredient4, "Ingredient4"); - getWidget(mApparatus1, "Apparatus1"); - getWidget(mApparatus2, "Apparatus2"); - getWidget(mApparatus3, "Apparatus3"); - getWidget(mApparatus4, "Apparatus4"); + getWidget(mApparatus[0], "Apparatus1"); + getWidget(mApparatus[1], "Apparatus2"); + getWidget(mApparatus[2], "Apparatus3"); + getWidget(mApparatus[3], "Apparatus4"); getWidget(mEffectsBox, "CreatedEffects"); getWidget(mNameEdit, "NameEdit"); @@ -70,7 +70,7 @@ namespace MWGui { // check if mortar & pestle is available (always needed) /// \todo check albemic, calcinator, retort (sometimes needed) - if (!mApparatus1->isUserString("ToolTipType")) + if (!mApparatus[0]->isUserString("ToolTipType")) { mWindowManager.messageBox("#{sNotifyMessage45}", std::vector()); return; @@ -253,60 +253,22 @@ namespace MWGui void AlchemyWindow::open() { - openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr - setFilter(ContainerBase::Filter_Ingredients); + openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr + setFilter (ContainerBase::Filter_Ingredients); mAlchemy.setAlchemist (mPtr); - // pick the best available apparatus - MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); + int index = 0; - MWWorld::Ptr bestAlbemic; - MWWorld::Ptr bestMortarPestle; - MWWorld::Ptr bestCalcinator; - MWWorld::Ptr bestRetort; - - for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus)); - it != store.end(); ++it) + for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools()); + iter!=mAlchemy.endTools() && index (mApparatus.size()); ++iter, ++index) { - MWWorld::LiveCellRef* ref = it->get(); - if (ref->base->data.type == ESM::Apparatus::Albemic - && (bestAlbemic.isEmpty() || ref->base->data.quality > bestAlbemic.get()->base->data.quality)) - bestAlbemic = *it; - else if (ref->base->data.type == ESM::Apparatus::MortarPestle - && (bestMortarPestle.isEmpty() || ref->base->data.quality > bestMortarPestle.get()->base->data.quality)) - bestMortarPestle = *it; - else if (ref->base->data.type == ESM::Apparatus::Calcinator - && (bestCalcinator.isEmpty() || ref->base->data.quality > bestCalcinator.get()->base->data.quality)) - bestCalcinator = *it; - else if (ref->base->data.type == ESM::Apparatus::Retort - && (bestRetort.isEmpty() || ref->base->data.quality > bestRetort.get()->base->data.quality)) - bestRetort = *it; - } - - if (!bestMortarPestle.isEmpty()) - { - mApparatus1->setUserString("ToolTipType", "ItemPtr"); - mApparatus1->setUserData(bestMortarPestle); - mApparatus1->setImageTexture(getIconPath(bestMortarPestle)); - } - if (!bestAlbemic.isEmpty()) - { - mApparatus2->setUserString("ToolTipType", "ItemPtr"); - mApparatus2->setUserData(bestAlbemic); - mApparatus2->setImageTexture(getIconPath(bestAlbemic)); - } - if (!bestCalcinator.isEmpty()) - { - mApparatus3->setUserString("ToolTipType", "ItemPtr"); - mApparatus3->setUserData(bestCalcinator); - mApparatus3->setImageTexture(getIconPath(bestCalcinator)); - } - if (!bestRetort.isEmpty()) - { - mApparatus4->setUserString("ToolTipType", "ItemPtr"); - mApparatus4->setUserData(bestRetort); - mApparatus4->setImageTexture(getIconPath(bestRetort)); + if (!iter->isEmpty()) + { + mApparatus[index]->setUserString ("ToolTipType", "ItemPtr"); + mApparatus[index]->setUserData (*iter); + mApparatus[index]->setImageTexture (getIconPath (*iter)); + } } } diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 67378d7de..5091fb57a 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -1,6 +1,8 @@ #ifndef MWGUI_ALCHEMY_H #define MWGUI_ALCHEMY_H +#include + #include "../mwmechanics/alchemy.hpp" #include "window_base.hpp" @@ -25,11 +27,6 @@ namespace MWGui MyGUI::ImageBox* mIngredient3; MyGUI::ImageBox* mIngredient4; - MyGUI::ImageBox* mApparatus1; - MyGUI::ImageBox* mApparatus2; - MyGUI::ImageBox* mApparatus3; - MyGUI::ImageBox* mApparatus4; - MyGUI::Widget* mEffectsBox; MyGUI::EditBox* mNameEdit; @@ -52,6 +49,8 @@ namespace MWGui private: MWMechanics::Alchemy mAlchemy; + + std::vector mApparatus; }; } From 21493c2dbd9979e51673c589e88e95c6962be8b8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 1 Oct 2012 23:33:07 +0200 Subject: [PATCH 012/255] added magic effect flags from Research wiki page --- apps/openmw/mwgui/spellcreationdialog.cpp | 10 +- apps/openmw/mwgui/tooltips.cpp | 2 +- apps/openmw/mwgui/widgets.cpp | 271 +--------------------- apps/openmw/mwgui/widgets.hpp | 8 - apps/openmw/mwrender/renderingmanager.cpp | 2 + components/esm/loadmgef.cpp | 157 +++++++++++++ components/esm/loadmgef.hpp | 21 +- 7 files changed, 186 insertions(+), 285 deletions(-) diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 982416588..133a01fe0 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -21,8 +21,8 @@ namespace bool sortMagicEffects (short id1, short id2) { - return MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(MWGui::Widgets::MWSpellEffect::effectIDToString (id1))->getString() - < MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(MWGui::Widgets::MWSpellEffect::effectIDToString (id2))->getString(); + return MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(ESM::MagicEffect::effectIdToString (id1))->getString() + < MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(ESM::MagicEffect::effectIdToString (id2))->getString(); } } @@ -74,7 +74,7 @@ namespace MWGui mEffectImage->setImageTexture (icon); - mEffectName->setCaptionWithReplacing("#{"+Widgets::MWSpellEffect::effectIDToString (effect->mIndex)+"}"); + mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}"); } void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) @@ -179,14 +179,14 @@ namespace MWGui for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) { mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find( - MWGui::Widgets::MWSpellEffect::effectIDToString (*it))->getString()); + ESM::MagicEffect::effectIdToString (*it))->getString()); } mAvailableEffectsList->adjustSize (); for (std::vector::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) { std::string name = MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find( - MWGui::Widgets::MWSpellEffect::effectIDToString (*it))->getString(); + ESM::MagicEffect::effectIdToString (*it))->getString(); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); w->setUserData(*it); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 0ab242b62..39afba749 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -716,7 +716,7 @@ void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playe void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id) { const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld ()->getStore ().magicEffects.find(id); - const std::string &name = Widgets::MWSpellEffect::effectIDToString (id); + const std::string &name = ESM::MagicEffect::effectIdToString (id); std::string icon = effect->mIcon; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 33aa1886c..62e65be35 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -400,13 +400,13 @@ void MWSpellEffect::updateWidgets() std::string sec = " " + mWindowManager->getGameSettingString("ssecond", ""); std::string secs = " " + mWindowManager->getGameSettingString("sseconds", ""); - std::string effectIDStr = effectIDToString(mEffectParams.mEffectID); + std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); - if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length) + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) { spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); } - if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8) + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { static const char *attributes[8] = { "sAttributeStrength", @@ -421,7 +421,7 @@ void MWSpellEffect::updateWidgets() spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); } - if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr)) + if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); @@ -434,7 +434,7 @@ void MWSpellEffect::updateWidgets() // constant effects have no duration and no target if (!mEffectParams.mIsConstant) { - if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr)) + if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) { spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); } @@ -463,267 +463,6 @@ void MWSpellEffect::updateWidgets() } } -std::string MWSpellEffect::effectIDToString(const short effectID) -{ - // Map effect ID to GMST name - // http://www.uesp.net/morrow/hints/mweffects.shtml - std::map names; - names[85] ="sEffectAbsorbAttribute"; - names[88] ="sEffectAbsorbFatigue"; - names[86] ="sEffectAbsorbHealth"; - names[87] ="sEffectAbsorbSpellPoints"; - names[89] ="sEffectAbsorbSkill"; - names[63] ="sEffectAlmsiviIntervention"; - names[47] ="sEffectBlind"; - names[123] ="sEffectBoundBattleAxe"; - names[129] ="sEffectBoundBoots"; - names[127] ="sEffectBoundCuirass"; - names[120] ="sEffectBoundDagger"; - names[131] ="sEffectBoundGloves"; - names[128] ="sEffectBoundHelm"; - names[125] ="sEffectBoundLongbow"; - names[121] ="sEffectBoundLongsword"; - names[122] ="sEffectBoundMace"; - names[130] ="sEffectBoundShield"; - names[124] ="sEffectBoundSpear"; - names[7] ="sEffectBurden"; - names[50] ="sEffectCalmCreature"; - names[49] ="sEffectCalmHumanoid"; - names[40] ="sEffectChameleon"; - names[44] ="sEffectCharm"; - names[118] ="sEffectCommandCreatures"; - names[119] ="sEffectCommandHumanoids"; - names[132] ="sEffectCorpus"; // NB this typo. (bethesda made it) - names[70] ="sEffectCureBlightDisease"; - names[69] ="sEffectCureCommonDisease"; - names[71] ="sEffectCureCorprusDisease"; - names[73] ="sEffectCureParalyzation"; - names[72] ="sEffectCurePoison"; - names[22] ="sEffectDamageAttribute"; - names[25] ="sEffectDamageFatigue"; - names[23] ="sEffectDamageHealth"; - names[24] ="sEffectDamageMagicka"; - names[26] ="sEffectDamageSkill"; - names[54] ="sEffectDemoralizeCreature"; - names[53] ="sEffectDemoralizeHumanoid"; - names[64] ="sEffectDetectAnimal"; - names[65] ="sEffectDetectEnchantment"; - names[66] ="sEffectDetectKey"; - names[38] ="sEffectDisintegrateArmor"; - names[37] ="sEffectDisintegrateWeapon"; - names[57] ="sEffectDispel"; - names[62] ="sEffectDivineIntervention"; - names[17] ="sEffectDrainAttribute"; - names[20] ="sEffectDrainFatigue"; - names[18] ="sEffectDrainHealth"; - names[19] ="sEffectDrainSpellpoints"; - names[21] ="sEffectDrainSkill"; - names[8] ="sEffectFeather"; - names[14] ="sEffectFireDamage"; - names[4] ="sEffectFireShield"; - names[117] ="sEffectFortifyAttackBonus"; - names[79] ="sEffectFortifyAttribute"; - names[82] ="sEffectFortifyFatigue"; - names[80] ="sEffectFortifyHealth"; - names[81] ="sEffectFortifySpellpoints"; - names[84] ="sEffectFortifyMagickaMultiplier"; - names[83] ="sEffectFortifySkill"; - names[52] ="sEffectFrenzyCreature"; - names[51] ="sEffectFrenzyHumanoid"; - names[16] ="sEffectFrostDamage"; - names[6] ="sEffectFrostShield"; - names[39] ="sEffectInvisibility"; - names[9] ="sEffectJump"; - names[10] ="sEffectLevitate"; - names[41] ="sEffectLight"; - names[5] ="sEffectLightningShield"; - names[12] ="sEffectLock"; - names[60] ="sEffectMark"; - names[43] ="sEffectNightEye"; - names[13] ="sEffectOpen"; - names[45] ="sEffectParalyze"; - names[27] ="sEffectPoison"; - names[56] ="sEffectRallyCreature"; - names[55] ="sEffectRallyHumanoid"; - names[61] ="sEffectRecall"; - names[68] ="sEffectReflect"; - names[100] ="sEffectRemoveCurse"; - names[95] ="sEffectResistBlightDisease"; - names[94] ="sEffectResistCommonDisease"; - names[96] ="sEffectResistCorprusDisease"; - names[90] ="sEffectResistFire"; - names[91] ="sEffectResistFrost"; - names[93] ="sEffectResistMagicka"; - names[98] ="sEffectResistNormalWeapons"; - names[99] ="sEffectResistParalysis"; - names[97] ="sEffectResistPoison"; - names[92] ="sEffectResistShock"; - names[74] ="sEffectRestoreAttribute"; - names[77] ="sEffectRestoreFatigue"; - names[75] ="sEffectRestoreHealth"; - names[76] ="sEffectRestoreSpellPoints"; - names[78] ="sEffectRestoreSkill"; - names[42] ="sEffectSanctuary"; - names[3] ="sEffectShield"; - names[15] ="sEffectShockDamage"; - names[46] ="sEffectSilence"; - names[11] ="sEffectSlowFall"; - names[58] ="sEffectSoultrap"; - names[48] ="sEffectSound"; - names[67] ="sEffectSpellAbsorption"; - names[136] ="sEffectStuntedMagicka"; - names[106] ="sEffectSummonAncestralGhost"; - names[110] ="sEffectSummonBonelord"; - names[108] ="sEffectSummonLeastBonewalker"; - names[134] ="sEffectSummonCenturionSphere"; - names[103] ="sEffectSummonClannfear"; - names[104] ="sEffectSummonDaedroth"; - names[105] ="sEffectSummonDremora"; - names[114] ="sEffectSummonFlameAtronach"; - names[115] ="sEffectSummonFrostAtronach"; - names[113] ="sEffectSummonGoldenSaint"; - names[109] ="sEffectSummonGreaterBonewalker"; - names[112] ="sEffectSummonHunger"; - names[102] ="sEffectSummonScamp"; - names[107] ="sEffectSummonSkeletalMinion"; - names[116] ="sEffectSummonStormAtronach"; - names[111] ="sEffectSummonWingedTwilight"; - names[135] ="sEffectSunDamage"; - names[1] ="sEffectSwiftSwim"; - names[59] ="sEffectTelekinesis"; - names[101] ="sEffectTurnUndead"; - names[133] ="sEffectVampirism"; - names[0] ="sEffectWaterBreathing"; - names[2] ="sEffectWaterWalking"; - names[33] ="sEffectWeaknesstoBlightDisease"; - names[32] ="sEffectWeaknesstoCommonDisease"; - names[34] ="sEffectWeaknesstoCorprusDisease"; - names[28] ="sEffectWeaknesstoFire"; - names[29] ="sEffectWeaknesstoFrost"; - names[31] ="sEffectWeaknesstoMagicka"; - names[36] ="sEffectWeaknesstoNormalWeapons"; - names[35] ="sEffectWeaknesstoPoison"; - names[30] ="sEffectWeaknesstoShock"; - - // bloodmoon - names[138] ="sEffectSummonCreature01"; - names[139] ="sEffectSummonCreature02"; - names[140] ="sEffectSummonCreature03"; - names[141] ="sEffectSummonCreature04"; - names[142] ="sEffectSummonCreature05"; - - // tribunal - names[137] ="sEffectSummonFabricant"; - - assert(names.find(effectID) != names.end() && "Unimplemented effect type"); - - return names[effectID]; -} - -bool MWSpellEffect::effectHasDuration(const std::string& effect) -{ - // lists effects that have no duration (e.g. open lock) - std::vector effectsWithoutDuration; - effectsWithoutDuration.push_back("sEffectOpen"); - effectsWithoutDuration.push_back("sEffectLock"); - effectsWithoutDuration.push_back("sEffectDispel"); - effectsWithoutDuration.push_back("sEffectSunDamage"); - effectsWithoutDuration.push_back("sEffectCorpus"); - effectsWithoutDuration.push_back("sEffectVampirism"); - effectsWithoutDuration.push_back("sEffectMark"); - effectsWithoutDuration.push_back("sEffectRecall"); - effectsWithoutDuration.push_back("sEffectDivineIntervention"); - effectsWithoutDuration.push_back("sEffectAlmsiviIntervention"); - effectsWithoutDuration.push_back("sEffectCureCommonDisease"); - effectsWithoutDuration.push_back("sEffectCureBlightDisease"); - effectsWithoutDuration.push_back("sEffectCureCorprusDisease"); - effectsWithoutDuration.push_back("sEffectCurePoison"); - effectsWithoutDuration.push_back("sEffectCureParalyzation"); - effectsWithoutDuration.push_back("sEffectRemoveCurse"); - effectsWithoutDuration.push_back("sEffectRestoreAttribute"); - - return (std::find(effectsWithoutDuration.begin(), effectsWithoutDuration.end(), effect) == effectsWithoutDuration.end()); -} - -bool MWSpellEffect::effectHasMagnitude(const std::string& effect) -{ - // lists effects that have no magnitude (e.g. invisiblity) - std::vector effectsWithoutMagnitude; - effectsWithoutMagnitude.push_back("sEffectInvisibility"); - effectsWithoutMagnitude.push_back("sEffectStuntedMagicka"); - effectsWithoutMagnitude.push_back("sEffectParalyze"); - effectsWithoutMagnitude.push_back("sEffectSoultrap"); - effectsWithoutMagnitude.push_back("sEffectSilence"); - effectsWithoutMagnitude.push_back("sEffectParalyze"); - effectsWithoutMagnitude.push_back("sEffectInvisibility"); - effectsWithoutMagnitude.push_back("sEffectWaterWalking"); - effectsWithoutMagnitude.push_back("sEffectWaterBreathing"); - effectsWithoutMagnitude.push_back("sEffectSummonScamp"); - effectsWithoutMagnitude.push_back("sEffectSummonClannfear"); - effectsWithoutMagnitude.push_back("sEffectSummonDaedroth"); - effectsWithoutMagnitude.push_back("sEffectSummonDremora"); - effectsWithoutMagnitude.push_back("sEffectSummonAncestralGhost"); - effectsWithoutMagnitude.push_back("sEffectSummonSkeletalMinion"); - effectsWithoutMagnitude.push_back("sEffectSummonBonewalker"); - effectsWithoutMagnitude.push_back("sEffectSummonGreaterBonewalker"); - effectsWithoutMagnitude.push_back("sEffectSummonBonelord"); - effectsWithoutMagnitude.push_back("sEffectSummonWingedTwilight"); - effectsWithoutMagnitude.push_back("sEffectSummonHunger"); - effectsWithoutMagnitude.push_back("sEffectSummonGoldenSaint"); - effectsWithoutMagnitude.push_back("sEffectSummonFlameAtronach"); - effectsWithoutMagnitude.push_back("sEffectSummonFrostAtronach"); - effectsWithoutMagnitude.push_back("sEffectSummonStormAtronach"); - effectsWithoutMagnitude.push_back("sEffectSummonCenturionSphere"); - effectsWithoutMagnitude.push_back("sEffectBoundDagger"); - effectsWithoutMagnitude.push_back("sEffectBoundLongsword"); - effectsWithoutMagnitude.push_back("sEffectBoundMace"); - effectsWithoutMagnitude.push_back("sEffectBoundBattleAxe"); - effectsWithoutMagnitude.push_back("sEffectBoundSpear"); - effectsWithoutMagnitude.push_back("sEffectBoundLongbow"); - effectsWithoutMagnitude.push_back("sEffectBoundCuirass"); - effectsWithoutMagnitude.push_back("sEffectBoundHelm"); - effectsWithoutMagnitude.push_back("sEffectBoundBoots"); - effectsWithoutMagnitude.push_back("sEffectBoundShield"); - effectsWithoutMagnitude.push_back("sEffectBoundGloves"); - effectsWithoutMagnitude.push_back("sEffectStuntedMagicka"); - effectsWithoutMagnitude.push_back("sEffectMark"); - effectsWithoutMagnitude.push_back("sEffectRecall"); - effectsWithoutMagnitude.push_back("sEffectDivineIntervention"); - effectsWithoutMagnitude.push_back("sEffectAlmsiviIntervention"); - effectsWithoutMagnitude.push_back("sEffectCureCommonDisease"); - effectsWithoutMagnitude.push_back("sEffectCureBlightDisease"); - effectsWithoutMagnitude.push_back("sEffectCureCorprusDisease"); - effectsWithoutMagnitude.push_back("sEffectCurePoison"); - effectsWithoutMagnitude.push_back("sEffectCureParalyzation"); - effectsWithoutMagnitude.push_back("sEffectRemoveCurse"); - effectsWithoutMagnitude.push_back("sEffectSummonCreature01"); - effectsWithoutMagnitude.push_back("sEffectSummonCreature02"); - effectsWithoutMagnitude.push_back("sEffectSummonCreature03"); - effectsWithoutMagnitude.push_back("sEffectSummonCreature04"); - effectsWithoutMagnitude.push_back("sEffectSummonCreature05"); - effectsWithoutMagnitude.push_back("sEffectSummonFabricant"); - - return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end()); -} - -bool MWSpellEffect::effectInvolvesAttribute (const std::string& effect) -{ - return (effect == "sEffectRestoreAttribute" - || effect == "sEffectAbsorbAttribute" - || effect == "sEffectDrainAttribute" - || effect == "sEffectFortifyAttribute" - || effect == "sEffectDamageAttribute"); -} - -bool MWSpellEffect::effectInvolvesSkill (const std::string& effect) -{ - return (effect == "sEffectRestoreSkill" - || effect == "sEffectAbsorbSkill" - || effect == "sEffectDrainSkill" - || effect == "sEffectFortifySkill" - || effect == "sEffectDamageSkill"); -} - MWSpellEffect::~MWSpellEffect() { } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index cc733122c..0a15e8e1f 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -249,14 +249,6 @@ namespace MWGui void setWindowManager(MWBase::WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellEffect(const SpellEffectParams& params); - static std::string effectIDToString(const short effectID); - - /// \todo Remove all of these! The information can be obtained via the ESM::MagicEffect's flags! - static bool effectHasMagnitude (const std::string& effect); - static bool effectHasDuration (const std::string& effect); - static bool effectInvolvesAttribute (const std::string& effect); - static bool effectInvolvesSkill (const std::string& effect); - int getRequestedWidth() const { return mRequestedWidth; } protected: diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c937c9894..21299e25c 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -180,6 +180,8 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; + + delete mFactory; } MWRender::SkyManager* RenderingManager::getSkyManager() diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index be588fbb0..954214036 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -79,4 +79,161 @@ void MagicEffect::save(ESMWriter &esm) esm.writeHNOString("DESC", mDescription); } +std::string MagicEffect::effectIdToString(short effectID) +{ + // Map effect ID to GMST name + // http://www.uesp.net/morrow/hints/mweffects.shtml + std::map names; + names[85] ="sEffectAbsorbAttribute"; + names[88] ="sEffectAbsorbFatigue"; + names[86] ="sEffectAbsorbHealth"; + names[87] ="sEffectAbsorbSpellPoints"; + names[89] ="sEffectAbsorbSkill"; + names[63] ="sEffectAlmsiviIntervention"; + names[47] ="sEffectBlind"; + names[123] ="sEffectBoundBattleAxe"; + names[129] ="sEffectBoundBoots"; + names[127] ="sEffectBoundCuirass"; + names[120] ="sEffectBoundDagger"; + names[131] ="sEffectBoundGloves"; + names[128] ="sEffectBoundHelm"; + names[125] ="sEffectBoundLongbow"; + names[121] ="sEffectBoundLongsword"; + names[122] ="sEffectBoundMace"; + names[130] ="sEffectBoundShield"; + names[124] ="sEffectBoundSpear"; + names[7] ="sEffectBurden"; + names[50] ="sEffectCalmCreature"; + names[49] ="sEffectCalmHumanoid"; + names[40] ="sEffectChameleon"; + names[44] ="sEffectCharm"; + names[118] ="sEffectCommandCreatures"; + names[119] ="sEffectCommandHumanoids"; + names[132] ="sEffectCorpus"; // NB this typo. (bethesda made it) + names[70] ="sEffectCureBlightDisease"; + names[69] ="sEffectCureCommonDisease"; + names[71] ="sEffectCureCorprusDisease"; + names[73] ="sEffectCureParalyzation"; + names[72] ="sEffectCurePoison"; + names[22] ="sEffectDamageAttribute"; + names[25] ="sEffectDamageFatigue"; + names[23] ="sEffectDamageHealth"; + names[24] ="sEffectDamageMagicka"; + names[26] ="sEffectDamageSkill"; + names[54] ="sEffectDemoralizeCreature"; + names[53] ="sEffectDemoralizeHumanoid"; + names[64] ="sEffectDetectAnimal"; + names[65] ="sEffectDetectEnchantment"; + names[66] ="sEffectDetectKey"; + names[38] ="sEffectDisintegrateArmor"; + names[37] ="sEffectDisintegrateWeapon"; + names[57] ="sEffectDispel"; + names[62] ="sEffectDivineIntervention"; + names[17] ="sEffectDrainAttribute"; + names[20] ="sEffectDrainFatigue"; + names[18] ="sEffectDrainHealth"; + names[19] ="sEffectDrainSpellpoints"; + names[21] ="sEffectDrainSkill"; + names[8] ="sEffectFeather"; + names[14] ="sEffectFireDamage"; + names[4] ="sEffectFireShield"; + names[117] ="sEffectFortifyAttackBonus"; + names[79] ="sEffectFortifyAttribute"; + names[82] ="sEffectFortifyFatigue"; + names[80] ="sEffectFortifyHealth"; + names[81] ="sEffectFortifySpellpoints"; + names[84] ="sEffectFortifyMagickaMultiplier"; + names[83] ="sEffectFortifySkill"; + names[52] ="sEffectFrenzyCreature"; + names[51] ="sEffectFrenzyHumanoid"; + names[16] ="sEffectFrostDamage"; + names[6] ="sEffectFrostShield"; + names[39] ="sEffectInvisibility"; + names[9] ="sEffectJump"; + names[10] ="sEffectLevitate"; + names[41] ="sEffectLight"; + names[5] ="sEffectLightningShield"; + names[12] ="sEffectLock"; + names[60] ="sEffectMark"; + names[43] ="sEffectNightEye"; + names[13] ="sEffectOpen"; + names[45] ="sEffectParalyze"; + names[27] ="sEffectPoison"; + names[56] ="sEffectRallyCreature"; + names[55] ="sEffectRallyHumanoid"; + names[61] ="sEffectRecall"; + names[68] ="sEffectReflect"; + names[100] ="sEffectRemoveCurse"; + names[95] ="sEffectResistBlightDisease"; + names[94] ="sEffectResistCommonDisease"; + names[96] ="sEffectResistCorprusDisease"; + names[90] ="sEffectResistFire"; + names[91] ="sEffectResistFrost"; + names[93] ="sEffectResistMagicka"; + names[98] ="sEffectResistNormalWeapons"; + names[99] ="sEffectResistParalysis"; + names[97] ="sEffectResistPoison"; + names[92] ="sEffectResistShock"; + names[74] ="sEffectRestoreAttribute"; + names[77] ="sEffectRestoreFatigue"; + names[75] ="sEffectRestoreHealth"; + names[76] ="sEffectRestoreSpellPoints"; + names[78] ="sEffectRestoreSkill"; + names[42] ="sEffectSanctuary"; + names[3] ="sEffectShield"; + names[15] ="sEffectShockDamage"; + names[46] ="sEffectSilence"; + names[11] ="sEffectSlowFall"; + names[58] ="sEffectSoultrap"; + names[48] ="sEffectSound"; + names[67] ="sEffectSpellAbsorption"; + names[136] ="sEffectStuntedMagicka"; + names[106] ="sEffectSummonAncestralGhost"; + names[110] ="sEffectSummonBonelord"; + names[108] ="sEffectSummonLeastBonewalker"; + names[134] ="sEffectSummonCenturionSphere"; + names[103] ="sEffectSummonClannfear"; + names[104] ="sEffectSummonDaedroth"; + names[105] ="sEffectSummonDremora"; + names[114] ="sEffectSummonFlameAtronach"; + names[115] ="sEffectSummonFrostAtronach"; + names[113] ="sEffectSummonGoldenSaint"; + names[109] ="sEffectSummonGreaterBonewalker"; + names[112] ="sEffectSummonHunger"; + names[102] ="sEffectSummonScamp"; + names[107] ="sEffectSummonSkeletalMinion"; + names[116] ="sEffectSummonStormAtronach"; + names[111] ="sEffectSummonWingedTwilight"; + names[135] ="sEffectSunDamage"; + names[1] ="sEffectSwiftSwim"; + names[59] ="sEffectTelekinesis"; + names[101] ="sEffectTurnUndead"; + names[133] ="sEffectVampirism"; + names[0] ="sEffectWaterBreathing"; + names[2] ="sEffectWaterWalking"; + names[33] ="sEffectWeaknesstoBlightDisease"; + names[32] ="sEffectWeaknesstoCommonDisease"; + names[34] ="sEffectWeaknesstoCorprusDisease"; + names[28] ="sEffectWeaknesstoFire"; + names[29] ="sEffectWeaknesstoFrost"; + names[31] ="sEffectWeaknesstoMagicka"; + names[36] ="sEffectWeaknesstoNormalWeapons"; + names[35] ="sEffectWeaknesstoPoison"; + names[30] ="sEffectWeaknesstoShock"; + + // bloodmoon + names[138] ="sEffectSummonCreature01"; + names[139] ="sEffectSummonCreature02"; + names[140] ="sEffectSummonCreature03"; + names[141] ="sEffectSummonCreature04"; + names[142] ="sEffectSummonCreature05"; + + // tribunal + names[137] ="sEffectSummonFabricant"; + + assert(names.find(effectID) != names.end() && "Unimplemented effect type"); + + return names[effectID]; +} + } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 861f66be0..abf4ab545 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -13,11 +13,19 @@ struct MagicEffect { enum Flags { - NoDuration = 0x4, - SpellMaking = 0x0200, - Enchanting = 0x0400, - Negative = 0x0800 // A harmful effect. Will determine whether - // eg. NPCs regard this spell as an attack. + TargetSkill = 0x1, // Affects a specific skill, which is specified elsewhere in the effect structure. + TargetAttribute = 0x2, // Affects a specific attribute, which is specified elsewhere in the effect structure. + NoDuration = 0x4, // Has no duration. Only runs effect once on cast. + NoMagnitude = 0x8, // Has no magnitude. + Negative = 0x10, // Counts as a negative effect. Interpreted as useful for attack, and is treated as a bad effect in alchemy. + ContinuousVfx = 0x20, // The effect's hit particle VFX repeats for the full duration of the spell, rather than occuring once on hit. + CastSelf = 0x40, // Allows range - cast on self. + CastTouch = 0x80, // Allows range - cast on touch. + CastTarget = 0x100, // Allows range - cast on target. + UncappedDamage = 0x1000, // Negates multiple cap behaviours. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second. + NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot re-cast" message for self target. + Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally. + CasterLinked = 0x20000 // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells. }; struct MEDTstruct @@ -30,6 +38,9 @@ struct MagicEffect float mSpeed, mSize, mSizeCap; }; // 36 bytes + static std::string effectIdToString(short effectID); + + MEDTstruct mData; std::string mIcon, mParticle; // Textures From 1cc2c2055f41a0d68757972fb27e077290490360 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:20:26 +0200 Subject: [PATCH 013/255] Issue #61: Implemented basic ingredient handling in Alchemy class --- apps/openmw/mwmechanics/alchemy.cpp | 52 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 22 +++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index c7e5da70a..6d3deed3c 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -11,6 +11,10 @@ void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mNpc = npc; + mIngredients.resize (4); + + std::fill (mIngredients.begin(), mIngredients.end(), MWWorld::Ptr()); + mTools.resize (4); std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); @@ -44,3 +48,51 @@ MWMechanics::Alchemy::TToolsIterator MWMechanics::Alchemy::endTools() const { return mTools.end(); } + +MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::beginIngredients() const +{ + return mIngredients.begin(); +} + +MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::endIngredients() const +{ + return mIngredients.end(); +} + +void MWMechanics::Alchemy::clear() +{ + mNpc = MWWorld::Ptr(); + mTools.clear(); + mIngredients.clear(); +} + +int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) +{ + // find a free slot + int slot = -1; + + for (int i=0; i (mIngredients.size()); ++i) + if (mIngredients[i].isEmpty()) + { + slot = i; + break; + } + + if (slot==-1) + return -1; + + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + if (!iter->isEmpty() && ingredient.get()==iter->get()) + return -1; + + mIngredients[slot] = ingredient; + + return slot; +} + +void MWMechanics::Alchemy::removeIngredient (int index) +{ + if (index>=0 && index (mIngredients.size())) + mIngredients[index] = MWWorld::Ptr(); +} + diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index fcaba9012..7c3cf9e68 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -7,7 +7,7 @@ namespace MWMechanics { - /// \brief Potion creatin via alchemy skill + /// \brief Potion creation via alchemy skill class Alchemy { public: @@ -15,10 +15,14 @@ namespace MWMechanics typedef std::vector TToolsContainer; typedef TToolsContainer::const_iterator TToolsIterator; + typedef std::vector TIngredientsContainer; + typedef TIngredientsContainer::const_iterator TIngredientsIterator; + private: MWWorld::Ptr mNpc; TToolsContainer mTools; + TIngredientsContainer mIngredients; public: @@ -29,6 +33,22 @@ namespace MWMechanics TToolsIterator beginTools() const; TToolsIterator endTools() const; + + TIngredientsIterator beginIngredients() const; + + TIngredientsIterator endIngredients() const; + + void clear(); + ///< Remove alchemist, tools and ingredients. + + int addIngredient (const MWWorld::Ptr& ingredient); + ///< Add ingredient into the next free slot. + /// + /// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being + /// listed already. + + void removeIngredient (int index); + ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). }; } From 14833a4c3abbae15a5d000e00f80649f8117acb1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:20:49 +0200 Subject: [PATCH 014/255] Issue #61: More robust tools handling in alchemy window --- apps/openmw/mwgui/alchemywindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 93eee60ee..2aa46fda0 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -62,6 +62,8 @@ namespace MWGui void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender) { + mAlchemy.clear(); + mWindowManager.removeGuiMode(GM_Alchemy); mWindowManager.removeGuiMode(GM_Inventory); } @@ -265,9 +267,9 @@ namespace MWGui { if (!iter->isEmpty()) { - mApparatus[index]->setUserString ("ToolTipType", "ItemPtr"); - mApparatus[index]->setUserData (*iter); - mApparatus[index]->setImageTexture (getIconPath (*iter)); + mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr"); + mApparatus.at (index)->setUserData (*iter); + mApparatus.at (index)->setImageTexture (getIconPath (*iter)); } } } From 332039da10d303b611d85298a690ddf23392fbf5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 2 Oct 2012 10:29:47 +0200 Subject: [PATCH 015/255] Issue #61: replaced 4 ingredient member variables with vector in alchemy GUI --- apps/openmw/mwgui/alchemywindow.cpp | 148 ++++++++-------------------- apps/openmw/mwgui/alchemywindow.hpp | 6 +- 2 files changed, 44 insertions(+), 110 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 2aa46fda0..cef5d6e2e 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -28,14 +28,14 @@ namespace MWGui { AlchemyWindow::AlchemyWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_alchemy_window.layout", parWindowManager) - , ContainerBase(0), mApparatus (4) + , ContainerBase(0), mApparatus (4), mIngredients (4) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); - getWidget(mIngredient1, "Ingredient1"); - getWidget(mIngredient2, "Ingredient2"); - getWidget(mIngredient3, "Ingredient3"); - getWidget(mIngredient4, "Ingredient4"); + getWidget(mIngredients[0], "Ingredient1"); + getWidget(mIngredients[1], "Ingredient2"); + getWidget(mIngredients[2], "Ingredient3"); + getWidget(mIngredients[3], "Ingredient4"); getWidget(mApparatus[0], "Apparatus1"); getWidget(mApparatus[1], "Apparatus2"); getWidget(mApparatus[2], "Apparatus3"); @@ -43,10 +43,10 @@ namespace MWGui getWidget(mEffectsBox, "CreatedEffects"); getWidget(mNameEdit, "NameEdit"); - mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); - mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); + mIngredients[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); @@ -80,14 +80,10 @@ namespace MWGui // make sure 2 or more ingredients were selected int numIngreds = 0; - if (mIngredient1->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient2->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient3->isUserString("ToolTipType")) - ++numIngreds; - if (mIngredient4->isUserString("ToolTipType")) - ++numIngreds; + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + ++numIngreds; + if (numIngreds < 2) { mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector()); @@ -138,14 +134,9 @@ namespace MWGui // note by scrawl: not rounding down here, I can't imagine a created potion to // have 0 weight when using ingredients with 0.1 weight respectively float weight = 0; - if (mIngredient1->isUserString("ToolTipType")) - weight += mIngredient1->getUserData()->get()->base->mData.mWeight; - if (mIngredient2->isUserString("ToolTipType")) - weight += mIngredient2->getUserData()->get()->base->mData.mWeight; - if (mIngredient3->isUserString("ToolTipType")) - weight += mIngredient3->getUserData()->get()->base->mData.mWeight; - if (mIngredient4->isUserString("ToolTipType")) - weight += mIngredient4->getUserData()->get()->base->mData.mWeight; + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + weight += mIngredients[i]->getUserData()->get()->base->mData.mWeight; newPotion.mData.mWeight = weight / float(numIngreds); newPotion.mData.mValue = 100; /// \todo @@ -222,34 +213,15 @@ namespace MWGui } // reduce count of the ingredients - if (mIngredient1->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient1->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient1); - } - if (mIngredient2->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient2->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient2); - } - if (mIngredient3->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient3->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient3); - } - if (mIngredient4->isUserString("ToolTipType")) - { - MWWorld::Ptr ingred = *mIngredient4->getUserData(); - ingred.getRefData().setCount(ingred.getRefData().getCount()-1); - if (ingred.getRefData().getCount() == 0) - removeIngredient(mIngredient4); + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + { + MWWorld::Ptr ingred = *mIngredients[i]->getUserData(); + ingred.getRefData().setCount(ingred.getRefData().getCount()-1); + if (ingred.getRefData().getCount() == 0) + removeIngredient(mIngredients[i]); } + update(); } @@ -289,45 +261,24 @@ namespace MWGui // (which could happen if two similiar ingredients don't stack because of script / owner) bool alreadyAdded = false; std::string name = MWWorld::Class::get(item).getName(item); - if (mIngredient1->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient1->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient2->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient2->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient3->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient3->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - if (mIngredient4->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredient4->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + { + MWWorld::Ptr item2 = *mIngredients[i]->getUserData(); + std::string name2 = MWWorld::Class::get(item2).getName(item2); + if (name == name2) + alreadyAdded = true; + } + if (alreadyAdded) return; - if (!mIngredient1->isUserString("ToolTipType")) - add = mIngredient1; - if (add == NULL && !mIngredient2->isUserString("ToolTipType")) - add = mIngredient2; - if (add == NULL && !mIngredient3->isUserString("ToolTipType")) - add = mIngredient3; - if (add == NULL && !mIngredient4->isUserString("ToolTipType")) - add = mIngredient4; + for (int i=0; i<4; ++i) + if (!mIngredients[i]->isUserString("ToolTipType")) + { + add = mIngredients[i]; + break; + } if (add != NULL) { @@ -346,14 +297,9 @@ namespace MWGui { std::vector ignore; // don't show ingredients that are currently selected in the "available ingredients" box. - if (mIngredient1->isUserString("ToolTipType")) - ignore.push_back(*mIngredient1->getUserData()); - if (mIngredient2->isUserString("ToolTipType")) - ignore.push_back(*mIngredient2->getUserData()); - if (mIngredient3->isUserString("ToolTipType")) - ignore.push_back(*mIngredient3->getUserData()); - if (mIngredient4->isUserString("ToolTipType")) - ignore.push_back(*mIngredient4->getUserData()); + for (int i=0; i<4; ++i) + if (mIngredients[i]->isUserString("ToolTipType")) + ignore.push_back(*mIngredients[i]->getUserData()); return ignore; } @@ -364,15 +310,7 @@ namespace MWGui for (int i=0; i<4; ++i) { - MyGUI::ImageBox* ingredient; - if (i==0) - ingredient = mIngredient1; - else if (i==1) - ingredient = mIngredient2; - else if (i==2) - ingredient = mIngredient3; - else if (i==3) - ingredient = mIngredient4; + MyGUI::ImageBox* ingredient = mIngredients[i]; if (!ingredient->isUserString("ToolTipType")) continue; diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 5091fb57a..179cdd174 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -22,11 +22,6 @@ namespace MWGui MyGUI::Button* mCreateButton; MyGUI::Button* mCancelButton; - MyGUI::ImageBox* mIngredient1; - MyGUI::ImageBox* mIngredient2; - MyGUI::ImageBox* mIngredient3; - MyGUI::ImageBox* mIngredient4; - MyGUI::Widget* mEffectsBox; MyGUI::EditBox* mNameEdit; @@ -51,6 +46,7 @@ namespace MWGui MWMechanics::Alchemy mAlchemy; std::vector mApparatus; + std::vector mIngredients; }; } From 7ee038fdd7fcb51f901893ae0e6554a2f0cc3dc1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 3 Oct 2012 12:03:07 +0200 Subject: [PATCH 016/255] fog now distance based instead of depth --- files/materials/objects.shader | 2 +- files/materials/openmw.configuration | 1 - files/materials/terrain.shader | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 45f33774d..525e4ab63 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -256,7 +256,7 @@ #endif #if FOG - float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); + float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w); #if UNDERWATER // regular fog only if fragment is above water diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index ee97451d3..2f84680f0 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -1,6 +1,5 @@ configuration water_reflection { - fog false shadows false shadows_pssm false mrt_output false diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 9183595e3..35ce40330 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -332,7 +332,7 @@ #if FOG - float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); + float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w); #if UNDERWATER // regular fog only if fragment is above water From 1c0dd3ccc57ec4f8e5234be8c49d5afab875b362 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 3 Oct 2012 15:06:54 +0200 Subject: [PATCH 017/255] some editing code --- apps/openmw/mwgui/enchantingdialog.cpp | 6 + apps/openmw/mwgui/enchantingdialog.hpp | 4 + apps/openmw/mwgui/spellcreationdialog.cpp | 167 +++++++++++++++++- apps/openmw/mwgui/spellcreationdialog.hpp | 34 +++- apps/openmw/mwgui/widgets.cpp | 135 +++++++------- apps/openmw/mwgui/windowmanagerimp.cpp | 1 + files/mygui/openmw_enchanting_dialog.layout | 25 ++- .../mygui/openmw_spellcreation_dialog.layout | 3 +- 8 files changed, 294 insertions(+), 81 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 990d4d06e..b3e785fd9 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -8,7 +8,9 @@ namespace MWGui EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_enchanting_dialog.layout", parWindowManager) { + getWidget(mCancelButton, "CancelButton"); + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked); } void EnchantingDialog::open() @@ -27,4 +29,8 @@ namespace MWGui mWindowManager.removeGuiMode (GM_Enchanting); } + void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender) + { + mWindowManager.removeGuiMode (GM_Enchanting); + } } diff --git a/apps/openmw/mwgui/enchantingdialog.hpp b/apps/openmw/mwgui/enchantingdialog.hpp index c6f0a72db..663758b02 100644 --- a/apps/openmw/mwgui/enchantingdialog.hpp +++ b/apps/openmw/mwgui/enchantingdialog.hpp @@ -19,6 +19,10 @@ namespace MWGui protected: virtual void onReferenceUnavailable(); + + void onCancelButtonClicked(MyGUI::Widget* sender); + + MyGUI::Button* mCancelButton; }; } diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 133a01fe0..c10295ad1 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -15,6 +15,7 @@ #include "tooltips.hpp" #include "widgets.hpp" +#include "class.hpp" namespace { @@ -31,6 +32,7 @@ namespace MWGui EditEffectDialog::EditEffectDialog(MWBase::WindowManager &parWindowManager) : WindowModal("openmw_edit_effect.layout", parWindowManager) + , mEditing(false) { getWidget(mCancelButton, "CancelButton"); getWidget(mOkButton, "OkButton"); @@ -64,7 +66,27 @@ namespace MWGui onRangeButtonClicked(mRangeButton); } - void EditEffectDialog::setEffect (const ESM::MagicEffect *effect) + void EditEffectDialog::newEffect (const ESM::MagicEffect *effect) + { + setMagicEffect(effect); + mEditing = false; + + mDeleteButton->setVisible (false); + } + + void EditEffectDialog::editEffect (ESM::ENAMstruct effect) + { + const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effect.mEffectID); + + setMagicEffect(magicEffect); + + mEffect = effect; + mEditing = true; + + mDeleteButton->setVisible (true); + } + + void EditEffectDialog::setMagicEffect (const ESM::MagicEffect *effect) { std::string icon = effect->mIcon; icon[icon.size()-3] = 'd'; @@ -75,6 +97,8 @@ namespace MWGui mEffectImage->setImageTexture (icon); mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}"); + + mEffect.mEffectID = effect->mIndex; } void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) @@ -94,12 +118,19 @@ namespace MWGui void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender) { + setVisible(false); + eventEffectRemoved(mEffect); } void EditEffectDialog::onOkButtonClicked (MyGUI::Widget* sender) { setVisible(false); + + if (mEditing) + eventEffectModified(mEffect); + else + eventEffectAdded(mEffect); } void EditEffectDialog::onCancelButtonClicked (MyGUI::Widget* sender) @@ -107,6 +138,16 @@ namespace MWGui setVisible(false); } + void EditEffectDialog::setSkill (int skill) + { + mEffect.mSkill = skill; + } + + void EditEffectDialog::setAttribute (int attribute) + { + mEffect.mAttribute = attribute; + } + // ------------------------------------------------------------------------------------------------ SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) @@ -130,6 +171,10 @@ namespace MWGui mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onBuyButtonClicked); mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onAvailableEffectClicked); + + mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectAdded); + mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectModified); + mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectRemoved); } @@ -205,15 +250,131 @@ namespace MWGui } + void SpellCreationDialog::onSelectAttribute () + { + mAddEffectDialog.setVisible(true); + mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId()); + mWindowManager.removeDialog (mSelectAttributeDialog); + mSelectAttributeDialog = 0; + } + + void SpellCreationDialog::onSelectSkill () + { + mAddEffectDialog.setVisible(true); + mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId ()); + mWindowManager.removeDialog (mSelectSkillDialog); + mSelectSkillDialog = 0; + } + + void SpellCreationDialog::onAttributeOrSkillCancel () + { + if (mSelectSkillDialog) + mWindowManager.removeDialog (mSelectSkillDialog); + if (mSelectAttributeDialog) + mWindowManager.removeDialog (mSelectAttributeDialog); + + mSelectSkillDialog = 0; + mSelectAttributeDialog = 0; + } + void SpellCreationDialog::onAvailableEffectClicked (MyGUI::Widget* sender) { short effectId = *sender->getUserData(); const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId); + mAddEffectDialog.newEffect (effect); - mAddEffectDialog.setVisible(true); - mAddEffectDialog.setEffect (effect); + if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) + { + delete mSelectSkillDialog; + mSelectSkillDialog = new SelectSkillDialog(mWindowManager); + mSelectSkillDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); + mSelectSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectSkill); + mSelectSkillDialog->setVisible (true); + } + else if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + { + delete mSelectAttributeDialog; + mSelectAttributeDialog = new SelectAttributeDialog(mWindowManager); + mSelectAttributeDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); + mSelectAttributeDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute); + mSelectAttributeDialog->setVisible (true); + } + else + { + mAddEffectDialog.setVisible(true); + } } + void SpellCreationDialog::onEffectModified (ESM::ENAMstruct effect) + { + mEffects[mSelectedEffect] = effect; + + updateEffectsView(); + } + + void SpellCreationDialog::onEffectRemoved (ESM::ENAMstruct effect) + { + mEffects.erase(mEffects.begin() + mSelectedEffect); + updateEffectsView(); + } + + void SpellCreationDialog::updateEffectsView () + { + MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator (); + MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets); + + MyGUI::IntSize size(0,0); + + int i = 0; + for (std::vector::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) + { + Widgets::SpellEffectParams params; + params.mEffectID = it->mEffectID; + params.mSkill = it->mSkill; + params.mAttribute = it->mAttribute; + params.mDuration = it->mDuration; + params.mMagnMin = it->mMagnMin; + params.mMagnMax = it->mMagnMax; + params.mRange = it->mRange; + + MyGUI::Button* button = mUsedEffectsView->createWidget("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default); + button->setUserData(i); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onEditEffect); + button->setNeedMouseFocus (true); + + Widgets::MWSpellEffectPtr effect = button->createWidget("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default); + + effect->setNeedMouseFocus (false); + effect->setWindowManager (&mWindowManager); + effect->setSpellEffect (params); + + effect->setSize(effect->getRequestedWidth (), 24); + button->setSize(effect->getRequestedWidth (), 24); + + size.width = std::max(size.width, effect->getRequestedWidth ()); + size.height += 24; + ++i; + } + + mUsedEffectsView->setCanvasSize(size); + } + + void SpellCreationDialog::onEffectAdded (ESM::ENAMstruct effect) + { + mEffects.push_back(effect); + + updateEffectsView(); + } + + void SpellCreationDialog::onEditEffect (MyGUI::Widget *sender) + { + int id = *sender->getUserData(); + + mSelectedEffect = id; + + mAddEffectDialog.editEffect (mEffects[id]); + mAddEffectDialog.setVisible (true); + } } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index a2db719a7..73c940412 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -4,6 +4,7 @@ #include "window_base.hpp" #include "referenceinterface.hpp" #include "list.hpp" +#include "widgets.hpp" namespace MWGui { @@ -18,7 +19,17 @@ namespace MWGui virtual void open(); - void setEffect (const ESM::MagicEffect* effect); + void setSkill(int skill); + void setAttribute(int attribute); + + void newEffect (const ESM::MagicEffect* effect); + void editEffect (ESM::ENAMstruct effect); + + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Effect; + + EventHandle_Effect eventEffectAdded; + EventHandle_Effect eventEffectModified; + EventHandle_Effect eventEffectRemoved; protected: MyGUI::Button* mCancelButton; @@ -42,12 +53,16 @@ namespace MWGui MyGUI::ImageBox* mEffectImage; MyGUI::TextBox* mEffectName; + bool mEditing; + protected: void onRangeButtonClicked (MyGUI::Widget* sender); void onDeleteButtonClicked (MyGUI::Widget* sender); void onOkButtonClicked (MyGUI::Widget* sender); void onCancelButtonClicked (MyGUI::Widget* sender); + void setMagicEffect(const ESM::MagicEffect* effect); + protected: ESM::ENAMstruct mEffect; }; @@ -68,6 +83,17 @@ namespace MWGui void onBuyButtonClicked (MyGUI::Widget* sender); void onAvailableEffectClicked (MyGUI::Widget* sender); + void onAttributeOrSkillCancel(); + void onSelectAttribute(); + void onSelectSkill(); + + void onEffectAdded(ESM::ENAMstruct effect); + void onEffectModified(ESM::ENAMstruct effect); + void onEffectRemoved(ESM::ENAMstruct effect); + + void updateEffectsView(); + + void onEditEffect(MyGUI::Widget* sender); MyGUI::EditBox* mNameEdit; MyGUI::TextBox* mMagickaCost; @@ -78,11 +104,17 @@ namespace MWGui MyGUI::Button* mCancelButton; MyGUI::TextBox* mPriceLabel; + int mSelectedEffect; + EditEffectDialog mAddEffectDialog; SelectAttributeDialog* mSelectAttributeDialog; SelectSkillDialog* mSelectSkillDialog; + Widgets::MWEffectList* mUsedEffectsList; + + std::vector mEffects; + }; } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 62e65be35..d6a839760 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -385,82 +385,77 @@ void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) void MWSpellEffect::updateWidgets() { - if (!mWindowManager) - return; - const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID); - if (!magicEffect) - return; - if (mTextWidget) + + assert(magicEffect); + assert(mWindowManager); + + std::string pt = mWindowManager->getGameSettingString("spoint", ""); + std::string pts = mWindowManager->getGameSettingString("spoints", ""); + std::string to = " " + mWindowManager->getGameSettingString("sTo", "") + " "; + std::string sec = " " + mWindowManager->getGameSettingString("ssecond", ""); + std::string secs = " " + mWindowManager->getGameSettingString("sseconds", ""); + + std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); + std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); + + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) { - std::string pt = mWindowManager->getGameSettingString("spoint", ""); - std::string pts = mWindowManager->getGameSettingString("spoints", ""); - std::string to = " " + mWindowManager->getGameSettingString("sTo", "") + " "; - std::string sec = " " + mWindowManager->getGameSettingString("ssecond", ""); - std::string secs = " " + mWindowManager->getGameSettingString("sseconds", ""); - - std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); - std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); - if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) - { - spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); - } - if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) - { - static const char *attributes[8] = { - "sAttributeStrength", - "sAttributeIntelligence", - "sAttributeWillpower", - "sAttributeAgility", - "sAttributeSpeed", - "sAttributeEndurance", - "sAttributePersonality", - "sAttributeLuck" - }; - spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); - } - - if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) - { - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); - else - { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " " + pts; - } - } - - // constant effects have no duration and no target - if (!mEffectParams.mIsConstant) - { - if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) - { - spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); - } - - // potions have no target - if (!mEffectParams.mNoTarget) - { - std::string on = mWindowManager->getGameSettingString("sonword", ""); - if (mEffectParams.mRange == ESM::RT_Self) - spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); - else if (mEffectParams.mRange == ESM::RT_Touch) - spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); - else if (mEffectParams.mRange == ESM::RT_Target) - spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); - } - } - - static_cast(mTextWidget)->setCaption(spellLine); - mRequestedWidth = mTextWidget->getTextSize().width + 24; + spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); } - if (mImageWidget) + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { - std::string path = std::string("icons\\") + magicEffect->mIcon; - fixTexturePath(path); - mImageWidget->setImageTexture(path); + static const char *attributes[8] = { + "sAttributeStrength", + "sAttributeIntelligence", + "sAttributeWillpower", + "sAttributeAgility", + "sAttributeSpeed", + "sAttributeEndurance", + "sAttributePersonality", + "sAttributeLuck" + }; + spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); } + + if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + { + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); + else + { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " " + pts; + } + } + + // constant effects have no duration and no target + if (!mEffectParams.mIsConstant) + { + if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) + { + spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); + } + + // potions have no target + if (!mEffectParams.mNoTarget) + { + std::string on = mWindowManager->getGameSettingString("sonword", ""); + if (mEffectParams.mRange == ESM::RT_Self) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); + else if (mEffectParams.mRange == ESM::RT_Touch) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); + else if (mEffectParams.mRange == ESM::RT_Target) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); + } + } + + static_cast(mTextWidget)->setCaption(spellLine); + mRequestedWidth = mTextWidget->getTextSize().width + 24; + + std::string path = std::string("icons\\") + magicEffect->mIcon; + fixTexturePath(path); + mImageWidget->setImageTexture(path); } MWSpellEffect::~MWSpellEffect() diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a043fc6b4..906bb2ca7 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -578,6 +578,7 @@ void WindowManager::onFrame (float frameDuration) mTradeWindow->checkReferenceAvailable(); mSpellBuyingWindow->checkReferenceAvailable(); mSpellCreationDialog->checkReferenceAvailable(); + mEnchantingDialog->checkReferenceAvailable(); mContainerWindow->checkReferenceAvailable(); mConsole->checkReferenceAvailable(); } diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index ea8156056..e3c8a8b18 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -19,13 +19,26 @@ - - + + + + + + + + + + + + + + + + - - + @@ -34,7 +47,7 @@ - + @@ -43,7 +56,7 @@ - + diff --git a/files/mygui/openmw_spellcreation_dialog.layout b/files/mygui/openmw_spellcreation_dialog.layout index 2013fece8..499224362 100644 --- a/files/mygui/openmw_spellcreation_dialog.layout +++ b/files/mygui/openmw_spellcreation_dialog.layout @@ -48,7 +48,8 @@ - + + From 025e820703344ea3cd7a57cc278d4fc2e42f1586 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 3 Oct 2012 15:36:10 +0200 Subject: [PATCH 018/255] abstracted code and use it in enchanting window as well --- apps/openmw/mwgui/enchantingdialog.cpp | 7 ++ apps/openmw/mwgui/enchantingdialog.hpp | 3 +- apps/openmw/mwgui/spellcreationdialog.cpp | 92 ++++++++++++--------- apps/openmw/mwgui/spellcreationdialog.hpp | 63 ++++++++------ files/mygui/openmw_enchanting_dialog.layout | 3 +- 5 files changed, 105 insertions(+), 63 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index b3e785fd9..3bd67ade6 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -7,8 +7,13 @@ namespace MWGui EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_enchanting_dialog.layout", parWindowManager) + , EffectEditorBase(parWindowManager) { getWidget(mCancelButton, "CancelButton"); + getWidget(mAvailableEffectsList, "AvailableEffects"); + getWidget(mUsedEffectsView, "UsedEffects"); + + setWidgets(mAvailableEffectsList, mUsedEffectsView); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked); } @@ -21,6 +26,8 @@ namespace MWGui void EnchantingDialog::startEnchanting (MWWorld::Ptr actor) { mPtr = actor; + + startEditing (); } void EnchantingDialog::onReferenceUnavailable () diff --git a/apps/openmw/mwgui/enchantingdialog.hpp b/apps/openmw/mwgui/enchantingdialog.hpp index 663758b02..0415c9d8d 100644 --- a/apps/openmw/mwgui/enchantingdialog.hpp +++ b/apps/openmw/mwgui/enchantingdialog.hpp @@ -3,13 +3,14 @@ #include "window_base.hpp" #include "referenceinterface.hpp" +#include "spellcreationdialog.hpp" #include "../mwbase/windowmanager.hpp" namespace MWGui { - class EnchantingDialog : public WindowBase, public ReferenceInterface + class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase { public: EnchantingDialog(MWBase::WindowManager& parWindowManager); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index c10295ad1..4e1c334db 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -152,9 +152,7 @@ namespace MWGui SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_spellcreation_dialog.layout", parWindowManager) - , mAddEffectDialog(parWindowManager) - , mSelectAttributeDialog(NULL) - , mSelectSkillDialog(NULL) + , EffectEditorBase(parWindowManager) { getWidget(mNameEdit, "NameEdit"); getWidget(mMagickaCost, "MagickaCost"); @@ -165,18 +163,28 @@ namespace MWGui getWidget(mBuyButton, "BuyButton"); getWidget(mCancelButton, "CancelButton"); - mAddEffectDialog.setVisible(false); - mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onCancelButtonClicked); mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onBuyButtonClicked); - mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onAvailableEffectClicked); - - mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectAdded); - mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectModified); - mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectRemoved); + setWidgets(mAvailableEffectsList, mUsedEffectsView); } + void SpellCreationDialog::startSpellMaking (MWWorld::Ptr actor) + { + mPtr = actor; + + startEditing(); + } + + void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender) + { + mWindowManager.removeGuiMode (MWGui::GM_SpellCreation); + } + + void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) + { + + } void SpellCreationDialog::open() { @@ -189,10 +197,23 @@ namespace MWGui mWindowManager.removeGuiMode (GM_SpellCreation); } - void SpellCreationDialog::startSpellMaking (MWWorld::Ptr actor) - { - mPtr = actor; + // ------------------------------------------------------------------------------------------------ + + EffectEditorBase::EffectEditorBase(MWBase::WindowManager& parWindowManager) + : mAddEffectDialog(parWindowManager) + , mSelectAttributeDialog(NULL) + , mSelectSkillDialog(NULL) + { + mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded); + mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified); + mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &EffectEditorBase::onEffectRemoved); + + mAddEffectDialog.setVisible (false); + } + + void EffectEditorBase::startEditing () + { // get the list of magic effects that are known to the player MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -237,47 +258,44 @@ namespace MWGui ToolTips::createMagicEffectToolTip (w, *it); } - } - void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender) + void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView) { - mWindowManager.removeGuiMode (MWGui::GM_SpellCreation); + mAvailableEffectsList = availableEffectsList; + mUsedEffectsView = usedEffectsView; + + mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked); } - void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) - { - - } - - void SpellCreationDialog::onSelectAttribute () + void EffectEditorBase::onSelectAttribute () { mAddEffectDialog.setVisible(true); mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId()); - mWindowManager.removeDialog (mSelectAttributeDialog); + MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog); mSelectAttributeDialog = 0; } - void SpellCreationDialog::onSelectSkill () + void EffectEditorBase::onSelectSkill () { mAddEffectDialog.setVisible(true); mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId ()); - mWindowManager.removeDialog (mSelectSkillDialog); + MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog); mSelectSkillDialog = 0; } - void SpellCreationDialog::onAttributeOrSkillCancel () + void EffectEditorBase::onAttributeOrSkillCancel () { if (mSelectSkillDialog) - mWindowManager.removeDialog (mSelectSkillDialog); + MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog); if (mSelectAttributeDialog) - mWindowManager.removeDialog (mSelectAttributeDialog); + MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog); mSelectSkillDialog = 0; mSelectAttributeDialog = 0; } - void SpellCreationDialog::onAvailableEffectClicked (MyGUI::Widget* sender) + void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender) { short effectId = *sender->getUserData(); @@ -288,7 +306,7 @@ namespace MWGui if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) { delete mSelectSkillDialog; - mSelectSkillDialog = new SelectSkillDialog(mWindowManager); + mSelectSkillDialog = new SelectSkillDialog(*MWBase::Environment::get().getWindowManager ()); mSelectSkillDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); mSelectSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectSkill); mSelectSkillDialog->setVisible (true); @@ -296,7 +314,7 @@ namespace MWGui else if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { delete mSelectAttributeDialog; - mSelectAttributeDialog = new SelectAttributeDialog(mWindowManager); + mSelectAttributeDialog = new SelectAttributeDialog(*MWBase::Environment::get().getWindowManager ()); mSelectAttributeDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); mSelectAttributeDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute); mSelectAttributeDialog->setVisible (true); @@ -307,20 +325,20 @@ namespace MWGui } } - void SpellCreationDialog::onEffectModified (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectModified (ESM::ENAMstruct effect) { mEffects[mSelectedEffect] = effect; updateEffectsView(); } - void SpellCreationDialog::onEffectRemoved (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectRemoved (ESM::ENAMstruct effect) { mEffects.erase(mEffects.begin() + mSelectedEffect); updateEffectsView(); } - void SpellCreationDialog::updateEffectsView () + void EffectEditorBase::updateEffectsView () { MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator (); MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets); @@ -347,7 +365,7 @@ namespace MWGui Widgets::MWSpellEffectPtr effect = button->createWidget("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default); effect->setNeedMouseFocus (false); - effect->setWindowManager (&mWindowManager); + effect->setWindowManager (MWBase::Environment::get().getWindowManager ()); effect->setSpellEffect (params); effect->setSize(effect->getRequestedWidth (), 24); @@ -361,14 +379,14 @@ namespace MWGui mUsedEffectsView->setCanvasSize(size); } - void SpellCreationDialog::onEffectAdded (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect) { mEffects.push_back(effect); updateEffectsView(); } - void SpellCreationDialog::onEditEffect (MyGUI::Widget *sender) + void EffectEditorBase::onEditEffect (MyGUI::Widget *sender) { int id = *sender->getUserData(); diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 73c940412..c5fffeb63 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -67,7 +67,45 @@ namespace MWGui ESM::ENAMstruct mEffect; }; - class SpellCreationDialog : public WindowBase, public ReferenceInterface + + class EffectEditorBase + { + public: + EffectEditorBase(MWBase::WindowManager& parWindowManager); + + + protected: + Widgets::MWList* mAvailableEffectsList; + MyGUI::ScrollView* mUsedEffectsView; + + EditEffectDialog mAddEffectDialog; + SelectAttributeDialog* mSelectAttributeDialog; + SelectSkillDialog* mSelectSkillDialog; + + int mSelectedEffect; + + std::vector mEffects; + + void onEffectAdded(ESM::ENAMstruct effect); + void onEffectModified(ESM::ENAMstruct effect); + void onEffectRemoved(ESM::ENAMstruct effect); + + void onAvailableEffectClicked (MyGUI::Widget* sender); + + void onAttributeOrSkillCancel(); + void onSelectAttribute(); + void onSelectSkill(); + + void onEditEffect(MyGUI::Widget* sender); + + void updateEffectsView(); + + void startEditing(); + void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); + + }; + + class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase { public: SpellCreationDialog(MWBase::WindowManager& parWindowManager); @@ -81,40 +119,17 @@ namespace MWGui void onCancelButtonClicked (MyGUI::Widget* sender); void onBuyButtonClicked (MyGUI::Widget* sender); - void onAvailableEffectClicked (MyGUI::Widget* sender); - void onAttributeOrSkillCancel(); - void onSelectAttribute(); - void onSelectSkill(); - - void onEffectAdded(ESM::ENAMstruct effect); - void onEffectModified(ESM::ENAMstruct effect); - void onEffectRemoved(ESM::ENAMstruct effect); - - void updateEffectsView(); - - void onEditEffect(MyGUI::Widget* sender); MyGUI::EditBox* mNameEdit; MyGUI::TextBox* mMagickaCost; MyGUI::TextBox* mSuccessChance; - Widgets::MWList* mAvailableEffectsList; - MyGUI::ScrollView* mUsedEffectsView; MyGUI::Button* mBuyButton; MyGUI::Button* mCancelButton; MyGUI::TextBox* mPriceLabel; - int mSelectedEffect; - - EditEffectDialog mAddEffectDialog; - - SelectAttributeDialog* mSelectAttributeDialog; - SelectSkillDialog* mSelectSkillDialog; - Widgets::MWEffectList* mUsedEffectsList; - std::vector mEffects; - }; } diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index e3c8a8b18..a19c56925 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -77,7 +77,8 @@ - + + From 85d9357e3ae71a04493e87113c0805a5b7794287 Mon Sep 17 00:00:00 2001 From: gugus Date: Sat, 6 Oct 2012 17:52:46 +0200 Subject: [PATCH 019/255] Travel GUI --- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwgui/tradewindow.hpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 14 +++++++------- apps/openmw/mwgui/travelwindow.hpp | 4 +--- apps/openmw/mwgui/windowmanagerimp.cpp | 1 + files/mygui/CMakeLists.txt | 1 + 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 74cae380b..fc4220fc3 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -16,7 +16,7 @@ namespace MWGui { TradeWindow::TradeWindow(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_trade_window.layout", parWindowManager) - , ReferenceInterface(NULL) // no drag&drop + , ContainerBase(NULL) // no drag&drop , mCurrentBalance(0) { MyGUI::ScrollView* itemView; diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 7ca3a97b4..4ec55045c 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TradeWindow : public ReferenceInterface, public WindowBase + class TradeWindow : public ContainerBase, public WindowBase { public: TradeWindow(MWBase::WindowManager& parWindowManager); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index f561a2c99..674517ace 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -23,8 +23,7 @@ namespace MWGui const int TravelWindow::sLineHeight = 18; TravelWindow::TravelWindow(MWBase::WindowManager& parWindowManager) : - WindowBase("openmw_spell_buying_window.layout", parWindowManager) - , ContainerBase(NULL) // no drag&drop + WindowBase("openmw_travel_window.layout", parWindowManager) , mCurrentY(0) , mLastPos(0) { @@ -33,8 +32,8 @@ namespace MWGui getWidget(mCancelButton, "CancelButton"); getWidget(mPlayerGold, "PlayerGold"); getWidget(mSelect, "Select"); - getWidget(mDestinations, "Spells"); - getWidget(mDestinationsView, "SpellsView"); + getWidget(mDestinations, "Travel"); + getWidget(mDestinationsView, "DestinationsView"); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked); @@ -61,8 +60,8 @@ namespace MWGui toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); - toAdd->setUserString("ToolTipType", "Spell"); - toAdd->setUserString("Spell", travelId); + //toAdd->setUserString("ToolTipType", "Spell"); + toAdd->setUserString("Destination", travelId); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); } @@ -111,12 +110,13 @@ namespace MWGui } updateLabels(); - mPtr.get()->base->mTransport[0]. + //mPtr.get()->base->mTransport[0]. mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); } void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) { + std::cout << "traveling to:" << _sender->getUserString("Destination"); /*int price = *_sender->getUserData(); if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index 07a516ce8..66360b05b 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -20,7 +20,7 @@ namespace MWGui namespace MWGui { - class TravelWindow : public ContainerBase, public WindowBase + class TravelWindow : public ReferenceInterface, public WindowBase { public: TravelWindow(MWBase::WindowManager& parWindowManager); @@ -35,8 +35,6 @@ namespace MWGui MyGUI::ScrollView* mDestinationsView; - MWWorld::Ptr mActor; - std::map mDestinationsWidgetMap; void onCancelButtonClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5f76e76cf..7054b6ba8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -376,6 +376,7 @@ void WindowManager::updateVisible() break; case GM_Travel: mTravelWindow->setVisible(true); + break; case GM_SpellCreation: mSpellCreationDialog->setVisible(true); break; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index a33d59ef6..2135df348 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -78,6 +78,7 @@ set(MYGUI_FILES openmw_spellcreation_dialog.layout openmw_edit_effect.layout openmw_enchanting_dialog.layout + openmw_travel_window.layout smallbars.png VeraMono.ttf markers.png From 1f4de03613841da56b28d265516626a4d01756fb Mon Sep 17 00:00:00 2001 From: gugus Date: Sat, 6 Oct 2012 22:33:10 +0200 Subject: [PATCH 020/255] oooups --- files/mygui/openmw_travel_window.layout | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 files/mygui/openmw_travel_window.layout diff --git a/files/mygui/openmw_travel_window.layout b/files/mygui/openmw_travel_window.layout new file mode 100644 index 000000000..07a6daf48 --- /dev/null +++ b/files/mygui/openmw_travel_window.layout @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5a611b66d76669b1d564601fc568d071d1f3af5c Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 8 Oct 2012 11:14:22 +0200 Subject: [PATCH 021/255] traveling. --- apps/openmw/mwgui/travelwindow.cpp | 38 ++++++++++++++++++++---------- apps/openmw/mwgui/travelwindow.hpp | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 674517ace..7414b148a 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -47,7 +47,7 @@ namespace MWGui mSelect->getHeight()); } - void TravelWindow::addDestination(const std::string& travelId) + void TravelWindow::addDestination(const std::string& travelId,ESM::Position pos,bool interior) { //std::cout << "travel to" << travelId; /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); @@ -56,12 +56,17 @@ namespace MWGui MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; /// \todo price adjustment depending on merchantile skill - toAdd->setUserData(price); + std::ostringstream oss; + oss << price; + toAdd->setUserString("price",oss.str()); + if(interior) toAdd->setUserString("interior","y"); + else toAdd->setUserString("interior","n"); toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); //toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Destination", travelId); + toAdd->setUserData(pos); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId)); } @@ -102,11 +107,12 @@ namespace MWGui for(int i = 0;i()->base->mTransport.size();i++) { std::string cellname = mPtr.get()->base->mTransport[i].mCellName; + bool interior = true; int x,y; MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->base->mTransport[i].mPos.pos[0], mPtr.get()->base->mTransport[i].mPos.pos[1],x,y); - if(cellname == "") cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; - addDestination(cellname); + if(cellname == "") {cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->name; interior= false;} + addDestination(cellname,mPtr.get()->base->mTransport[i].mPos,interior); } updateLabels(); @@ -117,19 +123,25 @@ namespace MWGui void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender) { std::cout << "traveling to:" << _sender->getUserString("Destination"); - /*int price = *_sender->getUserData(); + std::istringstream iss(_sender->getUserString("price")); + int price; + iss >> price; if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { 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 (mSpellsWidgetMap.find(_sender)->second); - mWindowManager.getTradeWindow()->addOrRemoveGold(-price); - startSpellBuying(mPtr); - - MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); - }*/ + ESM::Position pos = *_sender->getUserData(); + std::string cellname = _sender->getUserString("Destination"); + int x,y; + bool interior = _sender->getUserString("interior") == "y"; + MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); + MWWorld::CellStore* cell; + if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); + else cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + } } void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index 66360b05b..cc3d6a31f 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -40,7 +40,7 @@ namespace MWGui void onCancelButtonClicked(MyGUI::Widget* _sender); void onTravelButtonClick(MyGUI::Widget* _sender); void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void addDestination(const std::string& destinationID); + void addDestination(const std::string& destinationID,ESM::Position pos,bool interior); void clearDestinations(); int mLastPos,mCurrentY; From 27a3487d78499876ee0e91449c1f91b7330c8470 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 8 Oct 2012 15:51:36 +0200 Subject: [PATCH 022/255] right prices --- apps/openmw/mwgui/travelwindow.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 7414b148a..c2eb33c6c 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -56,11 +56,23 @@ namespace MWGui MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); mCurrentY += sLineHeight; /// \todo price adjustment depending on merchantile skill + if(interior) + { + toAdd->setUserString("interior","y"); + price = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fMagesGuildTravel")->getFloat(); + } + else + { + toAdd->setUserString("interior","n"); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position PlayerPos = player.getRefData().getPosition(); + float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); + price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat(); + } std::ostringstream oss; oss << price; toAdd->setUserString("price",oss.str()); - if(interior) toAdd->setUserString("interior","y"); - else toAdd->setUserString("interior","n"); + toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); From 57f3b50dc8fe93cf13bfa7ab0b0465bd88450815 Mon Sep 17 00:00:00 2001 From: cfcohen Date: Tue, 9 Oct 2012 01:33:47 -0400 Subject: [PATCH 023/255] Add more detail to ESMTool record dumping. --- apps/esmtool/esmtool.cpp | 32 +- apps/esmtool/record.cpp | 625 ++++++++++++++++++++++++++++++++++++--- apps/esmtool/record.hpp | 6 +- 3 files changed, 618 insertions(+), 45 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 88709f58b..944bc7d8c 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -57,6 +57,8 @@ struct Arguments std::string encoding; std::string filename; std::string outname; + + std::vector types; ESMData data; ESM::ESMReader reader; @@ -71,6 +73,8 @@ bool parseOptions (int argc, char** argv, Arguments &info) ("help,h", "print help message.") ("version,v", "print version information and quit.") ("raw,r", "Show an unformattet list of all records and subrecords.") + ("type,t", bpo::value< std::vector >(), + "Show only records of this type.") ("quiet,q", "Supress all record information. Useful for speed tests.") ("loadcells,C", "Browse through contents of all cells.") @@ -122,6 +126,9 @@ bool parseOptions (int argc, char** argv, Arguments &info) return false; } + if (variables.count("type") > 0) + info.types = variables["type"].as< std::vector >(); + info.mode = variables["mode"].as(); if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp")) { @@ -306,14 +313,23 @@ int load(Arguments& info) uint32_t flags; esm.getRecHeader(flags); + // Is the user interested in this record type? + bool interested = true; + if (info.types.size() > 0) + { + std::vector::iterator match; + match = std::find(info.types.begin(), info.types.end(), + n.toString()); + if (match == info.types.end()) interested = false; + } + std::string id = esm.getHNOString("NAME"); - if(!quiet) + if(!quiet && interested) std::cout << "\nRecord: " << n.toString() << " '" << id << "'\n"; - EsmTool::RecordBase *record = - EsmTool::RecordBase::create(n.val); + EsmTool::RecordBase *record = EsmTool::RecordBase::create(n); if (record == 0) { if (std::find(skipped.begin(), skipped.end(), n.val) == skipped.end()) @@ -326,18 +342,16 @@ int load(Arguments& info) if (quiet) break; std::cout << " Skipping\n"; } else { - if (record->getType() == ESM::REC_GMST) { + if (record->getType().val == ESM::REC_GMST) { // preset id for GameSetting record record->cast()->get().mId = id; } record->setId(id); record->setFlags((int) flags); record->load(esm); - if (!quiet) { - record->print(); - } + if (!quiet && interested) record->print(); - if (record->getType() == ESM::REC_CELL && loadCells) { + if (record->getType().val == ESM::REC_CELL && loadCells) { loadCell(record->cast()->get(), esm, info); } @@ -434,7 +448,7 @@ int clone(Arguments& info) { EsmTool::RecordBase *record = *it; - name.val = record->getType(); + name.val = record->getType().val; esm.startRecord(name.toString(), record->getFlags()); diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 9609e5242..38615b240 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1,15 +1,64 @@ #include "record.hpp" #include +#include + +void printAIPackage(ESM::AIPackage p) +{ + if (p.mType == ESM::AI_Wander) + { + std::cout << " AIType Wander:" << std::endl; + std::cout << " Distance: " << p.mWander.mDistance << std::endl; + std::cout << " Duration: " << p.mWander.mDuration << std::endl; + std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; + if (p.mWander.mUnk != 1) + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + + std::cout << " Idle: "; + for (int i = 0; i != 8; i++) + std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << std::endl; + } + else if (p.mType == ESM::AI_Travel) + { + std::cout << " AIType Travel:" << std::endl; + std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) + { + if (p.mType == ESM::AI_Follow) std::cout << " AIType Follow:" << std::endl; + else std::cout << " AIType Escort:" << std::endl; + + std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + std::cout << " Duration: " << p.mTarget.mDuration << std::endl; + std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; + std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Activate) + { + std::cout << " AIType Activate:" << std::endl; + std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; + std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; + } + else { + std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; + } + + if (p.mCellName != "") + std::cout << " Cell Name: " << p.mCellName << std::endl; +} namespace EsmTool { RecordBase * -RecordBase::create(int type) +RecordBase::create(ESM::NAME type) { RecordBase *record = 0; - switch (type) { + switch (type.val) { case ESM::REC_ACTI: { record = new EsmTool::Record; @@ -233,7 +282,7 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; } @@ -241,38 +290,75 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; + // mEffects missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Armor: " << mData.mData.mArmor << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + // mParts missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Type: " << (int)mData.mData.mType << std::endl; + std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + std::cout << " Part: " << (int)mData.mData.mPart << std::endl; + std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; + std::cout << " SkillID: " << mData.mData.mSkillID << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + // mText missing } template<> @@ -281,13 +367,38 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; + std::vector::iterator pit; + for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++) + std::cout << " Power: " << *pit << std::endl; } template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Region: " << mData.mRegion << std::endl; + // None of the cells have names... + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + if (mData.mRegion != "") + std::cout << " Region: " << mData.mRegion << std::endl; + std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + + std::cout << " Coordinates: " << " (" << mData.getGridX() << "," + << mData.getGridY() << ")" << std::endl; + + if (mData.mData.mFlags & ESM::Cell::Interior && + !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + { + std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; + std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; + std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; + std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + std::cout << " Water Level: " << mData.mWater << std::endl; + } + else + std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; + std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; + std::cout << " NAM0: " << mData.mNAM0 << std::endl; + } template<> @@ -295,37 +406,120 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; + std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; + std::cout << " Attribute1: " << mData.mData.mAttribute[0] << std::endl; + std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; + std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + // mEnchant also in CTDTstruct? } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Weight: " << mData.mWeight << std::endl; + // mInventory missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Original: " << mData.mOriginal << std::endl; + std::cout << " Scale: " << mData.mScale << std::endl; + + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Level: " << mData.mData.mLevel << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << mData.mData.mStrength << std::endl; + std::cout << " Intelligence: " << mData.mData.mIntelligence << std::endl; + std::cout << " Willpower: " << mData.mData.mWillpower << std::endl; + std::cout << " Agility: " << mData.mData.mAgility << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Endurance: " << mData.mData.mEndurance << std::endl; + std::cout << " Personality: " << mData.mData.mPersonality << std::endl; + std::cout << " Luck: " << mData.mData.mLuck << std::endl; + + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Magicka: " << mData.mData.mMana << std::endl; + std::cout << " Fatigue: " << mData.mData.mFatigue << std::endl; + std::cout << " Soul: " << mData.mData.mSoul << std::endl; + std::cout << " Combat: " << mData.mData.mCombat << std::endl; + std::cout << " Magic: " << mData.mData.mMagic << std::endl; + std::cout << " Stealth: " << mData.mData.mStealth << std::endl; + std::cout << " Attack1: " << mData.mData.mAttack[0] + << "-" << mData.mData.mAttack[1] << std::endl; + std::cout << " Attack2: " << mData.mData.mAttack[2] + << "-" << mData.mData.mAttack[3] << std::endl; + std::cout << " Attack3: " << mData.mData.mAttack[4] + << "-" << mData.mData.mAttack[5] << std::endl; + std::cout << " Gold: " << mData.mData.mGold << std::endl; + + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) + std::cout << " Spell: " << *sit << std::endl; + + std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; + std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; + + std::vector::iterator pit; + for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) + printAIPackage(*pit); } template<> void Record::print() { - // nothing to print + std::cout << " Type: " << (int)mData.mType << std::endl; + // mInfo missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Mesh: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; std::cout << " OpenSound: " << mData.mOpenSound << std::endl; std::cout << " CloseSound: " << mData.mCloseSound << std::endl; @@ -334,22 +528,51 @@ void Record::print() template<> void Record::print() { - // nothing to print + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + std::cout << " Charge: " << mData.mData.mCharge << std::endl; + std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; + // mEffects missing } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Attr1: " << mData.mData.mAttribute1 << std::endl; - std::cout << " Attr2: " << mData.mData.mAttribute2 << std::endl; std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; + if (mData.mData.mUnknown != -1) + std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; + std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; + std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; + for (int i = 0; i != 6; i++) + if (mData.mData.mSkillID[i] != -1) + std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + for (int i = 0; i != 10; i++) + if (mData.mRanks[i] != "") + { + std::cout << " Rank: " << mData.mRanks[i] << std::endl; + std::cout << " Attribute1 Requirement: " + << mData.mData.mRankData[i].mAttribute1 << std::endl; + std::cout << " Attribute2 Requirement: " + << mData.mData.mRankData[i].mAttribute2 << std::endl; + std::cout << " One Skill at Level: " + << mData.mData.mRankData[i].mSkill1 << std::endl; + std::cout << " Two Skills at Level: " + << mData.mData.mRankData[i].mSkill2 << std::endl; + std::cout << " Faction Reaction: " + << mData.mData.mRankData[i].mFactReaction << std::endl; + } + std::vector::iterator rit; + for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) + std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; } template<> void Record::print() { - // nothing to print + // nothing to print (well, nothing that's correct anyway) + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Value: " << mData.mValue << std::endl; } template<> @@ -380,67 +603,130 @@ void Record::print() { std::cout << " Id: " << mData.mId << std::endl; std::cout << " Text: " << mData.mResponse << std::endl; + // Lots missing, more coming } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + for (int i = 0; i !=4; i++) + { + // A value of -1 means no effect + if (mData.mData.mEffectID[i] == -1) continue; + std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; + std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; + std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + } } template<> void Record::print() { - std::cout << " Coords: [" << mData.mX << "," << mData.mY << "]" << std::endl; + std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; + // Lots missing, more coming } template<> void Record::print() { + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; + std::vector::iterator iit; + for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) + std::cout << " Creature: Level: " << iit->mLevel + << " Creature: " << iit->mId << std::endl; } template<> void Record::print() { + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; + std::vector::iterator iit; + for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) + std::cout << " Inventory: Count: " << iit->mLevel + << " Item: " << iit->mId << std::endl; } template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + if (mData.mModel != "") + std::cout << " Model: " << mData.mModel << std::endl; + if (mData.mIcon != "") + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Duration: " << mData.mData.mTime << std::endl; + std::cout << " Radius: " << mData.mData.mRadius << std::endl; + std::cout << " Color: " << mData.mData.mColor << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; } template<> void Record::print() { std::cout << " Id: " << mData.mId << std::endl; + std::cout << " Index: " << mData.mIndex << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl; } @@ -448,53 +734,294 @@ template<> void Record::print() { std::cout << " Index: " << mData.mIndex << std::endl; - - const char *text = "Positive"; - if (mData.mData.mFlags & ESM::MagicEffect::Negative) { - text = "Negative"; - } - std::cout << " " << text << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Particle Texture: " << mData.mParticle << std::endl; + if (mData.mCasting != "") + std::cout << " Casting Static: " << mData.mCasting << std::endl; + if (mData.mCastSound != "") + std::cout << " Casting Sound: " << mData.mCastSound << std::endl; + if (mData.mBolt != "") + std::cout << " Bolt Static: " << mData.mBolt << std::endl; + if (mData.mBoltSound != "") + std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; + if (mData.mHit != "") + std::cout << " Hit Static: " << mData.mHit << std::endl; + if (mData.mHitSound != "") + std::cout << " Hit Sound: " << mData.mHitSound << std::endl; + if (mData.mArea != "") + std::cout << " Area Static: " << mData.mArea << std::endl; + if (mData.mAreaSound != "") + std::cout << " Area Sound: " << mData.mAreaSound << std::endl; + std::cout << " School: " << mData.mData.mSchool << std::endl; + std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Size: " << mData.mData.mSize << std::endl; + std::cout << " Size Cap: " << mData.mData.mSizeCap << std::endl; + std::cout << " RGB Color: " << "(" + << mData.mData.mRed << "," + << mData.mData.mGreen << "," + << mData.mData.mGreen << ")" << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Animation: " << mData.mModel << std::endl; + std::cout << " Hair Model: " << mData.mHair << std::endl; + std::cout << " Head Model: " << mData.mHead << std::endl; std::cout << " Race: " << mData.mRace << std::endl; + std::cout << " Class: " << mData.mClass << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mFaction != "") + std::cout << " Faction: " << mData.mFaction << std::endl; + std::cout << " Flags: " << mData.mFlags << std::endl; + + // Seriously? + if (mData.mNpdt52.mGold == -10) + { + std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; + std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; + std::cout << " Unknown1: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; + std::cout << " Unknown2: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; + std::cout << " Unknown3: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; + std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; + } + else { + std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; + std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; + std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; + std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; + std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; + std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; + std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; + std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; + + std::cout << " Skills:" << std::endl; + for (int i = 0; i != 27; i++) + std::cout << " " << i << " = " + << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; + + std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; + std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; + std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; + std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; + std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; + } + + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) + std::cout << " Spell: " << *sit << std::endl; + + std::vector::iterator dit; + for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++) + { + std::cout << " Destination Position: " + << boost::format("%12.3f") % dit->mPos.pos[0] << "," + << boost::format("%12.3f") % dit->mPos.pos[1] << "," + << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + std::cout << " Destination Rotation: " + << boost::format("%9.6f") % dit->mPos.rot[0] << "," + << boost::format("%9.6f") % dit->mPos.rot[1] << "," + << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; + if (dit->mCellName != "") + std::cout << " Destination Cell: " << dit->mCellName << std::endl; + } + + std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; + std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; + + std::vector::iterator pit; + for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) + printAIPackage(*pit); } template<> void Record::print() { std::cout << " Cell: " << mData.mCell << std::endl; - std::cout << " Point count: " << mData.mPoints.size() << std::endl; - std::cout << " Edge count: " << mData.mEdges.size() << std::endl; + std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; + std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; + if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) + std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; + std::cout << " Point Count: " << mData.mPoints.size() << std::endl; + std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; + + int i = 0; + ESM::Pathgrid::PointList::iterator pit; + for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++) + { + std::cout << " Point[" << i << "]:" << std::endl; + std::cout << " Coordinates: (" << pit->mX << "," + << pit->mY << "," << pit->mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; + std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; + std::cout << " Unknown: " << pit->mUnknown << std::endl; + i++; + } + i = 0; + ESM::Pathgrid::EdgeList::iterator eit; + for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); eit++) + { + std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; + if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) + std::cout << " BAD POINT IN EDGE!" << std::endl; + i++; + } } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Length: " << mData.mData.mHeight.mMale << "m " << mData.mData.mHeight.mFemale << "f" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + + std::cout << " Male:" << std::endl; + std::cout << " Strength: " + << mData.mData.mStrength.mMale << std::endl; + std::cout << " Intelligence: " + << mData.mData.mIntelligence.mMale << std::endl; + std::cout << " Willpower: " + << mData.mData.mWillpower.mMale << std::endl; + std::cout << " Agility: " + << mData.mData.mAgility.mMale << std::endl; + std::cout << " Speed: " + << mData.mData.mSpeed.mMale << std::endl; + std::cout << " Endurance: " + << mData.mData.mEndurance.mMale << std::endl; + std::cout << " Personality: " + << mData.mData.mPersonality.mMale << std::endl; + std::cout << " Luck: " + << mData.mData.mLuck.mMale << std::endl; + std::cout << " Height: " + << mData.mData.mHeight.mMale << std::endl; + std::cout << " Weight: " + << mData.mData.mWeight.mMale << std::endl; + + std::cout << " Female:" << std::endl; + std::cout << " Strength: " + << mData.mData.mStrength.mFemale << std::endl; + std::cout << " Intelligence: " + << mData.mData.mIntelligence.mFemale << std::endl; + std::cout << " Willpower: " + << mData.mData.mWillpower.mFemale << std::endl; + std::cout << " Agility: " + << mData.mData.mAgility.mFemale << std::endl; + std::cout << " Speed: " + << mData.mData.mSpeed.mFemale << std::endl; + std::cout << " Endurance: " + << mData.mData.mEndurance.mFemale << std::endl; + std::cout << " Personality: " + << mData.mData.mPersonality.mFemale << std::endl; + std::cout << " Luck: " + << mData.mData.mLuck.mFemale << std::endl; + std::cout << " Height: " + << mData.mData.mHeight.mFemale << std::endl; + std::cout << " Weight: " + << mData.mData.mWeight.mFemale << std::endl; + + for (int i = 0; i != 7; i++) + // Not all races have 7 skills. + if (mData.mData.mBonus[i].mSkill != -1) + std::cout << " Skill: " << mData.mData.mBonus[i].mSkill + << " = " << mData.mData.mBonus[i].mBonus << std::endl; + + std::vector::iterator sit; + for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) + std::cout << " Power: " << *sit << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + + std::cout << " Weather:" << std::endl; + std::cout << " Clear: " << (int)mData.mData.mClear << std::endl; + std::cout << " Cloudy: " << (int)mData.mData.mCloudy << std::endl; + std::cout << " Foggy: " << (int)mData.mData.mFoggy << std::endl; + std::cout << " Overcast: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Rain: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Thunder: " << (int)mData.mData.mThunder << std::endl; + std::cout << " Ash: " << (int)mData.mData.mAsh << std::endl; + std::cout << " Blight: " << (int)mData.mData.mBlight << std::endl; + std::cout << " UnknownA: " << (int)mData.mData.mA << std::endl; + std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; + std::cout << " Map Color: " << mData.mMapColor << std::endl; + if (mData.mSleepList != "") + std::cout << " Sleep List: " << mData.mSleepList << std::endl; + std::vector::iterator sit; + for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++) + std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mData.mName.toString() << std::endl; + + std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl; + std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl; + std::cout << " Num Floats: " << mData.mData.mNumFloats << std::endl; + std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; + std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; + + std::cout << " Script: [skipped]" << std::endl; + // Skip until multi-line field is controllable by a command line option. + //std::cout << "-------------------------------------------" << std::endl; + //std::cout << s->scriptText << std::endl; + //std::cout << "-------------------------------------------" << std::endl; + std::vector::iterator vit; + for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++) + std::cout << " Variable: " << *vit << std::endl; + + std::cout << " ByteCode: "; + std::vector::iterator cit; + for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++) + std::cout << boost::format("%02X") % (int)(*cit); + std::cout << std::endl; } template<> @@ -519,25 +1046,34 @@ void Record::print() { std::cout << " Creature: " << mData.mCreature << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Type: " << mData.mType << std::endl; } template<> void Record::print() { std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Volume: " << mData.mData.mVolume << std::endl; + std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; + if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) + std::cout << " Range: " << (int)mData.mData.mMinRange << " - " + << (int)mData.mData.mMaxRange << std::endl; } template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + // mEffect missing } template<> void Record::print() { - std::cout << "Start script: " << mData.mScript << std::endl; + std::cout << "Start Script: " << mData.mScript << std::endl; + std::cout << "Start Data: " << mData.mData << std::endl; } template<> @@ -549,11 +1085,34 @@ void Record::print() template<> void Record::print() { - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Chop: " << mData.mData.mChop[0] << "-" << mData.mData.mChop[1] << std::endl; - std::cout << " Slash: " << mData.mData.mSlash[0] << "-" << mData.mData.mSlash[1] << std::endl; - std::cout << " Thrust: " << mData.mData.mThrust[0] << "-" << mData.mData.mThrust[1] << std::endl; + // No names on VFX bolts + if (mData.mName != "") + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + // No icons on VFX bolts or magic bolts + if (mData.mIcon != "") + std::cout << " Icon: " << mData.mIcon << std::endl; + if (mData.mScript != "") + std::cout << " Script: " << mData.mScript << std::endl; + if (mData.mEnchant != "") + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Reach: " << mData.mData.mReach << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) + std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" + << (int)mData.mData.mChop[1] << std::endl; + if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) + std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" + << (int)mData.mData.mSlash[1] << std::endl; + if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) + std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" + << (int)mData.mData.mThrust[1] << std::endl; } template<> diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index 3cd7f5b54..e75870ab6 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -20,7 +20,7 @@ namespace EsmTool protected: std::string mId; int mFlags; - int mType; + ESM::NAME mType; public: RecordBase () {} @@ -42,7 +42,7 @@ namespace EsmTool mFlags = flags; } - int getType() const { + ESM::NAME getType() const { return mType; } @@ -50,7 +50,7 @@ namespace EsmTool virtual void save(ESM::ESMWriter &esm) = 0; virtual void print() = 0; - static RecordBase *create(int type); + static RecordBase *create(ESM::NAME type); // just make it a bit shorter template From 35d099a63856bc37ce381388f2135066a4460836 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 9 Oct 2012 17:10:25 +0200 Subject: [PATCH 024/255] disabling gcc extensions --- CMakeLists.txt | 2 +- apps/launcher/pluginsview.hpp | 4 ++-- apps/mwiniimporter/importer.cpp | 8 ++++---- apps/openmw/main.cpp | 2 +- apps/openmw/mwbase/soundmanager.hpp | 2 +- apps/openmw/mwmechanics/drawstate.hpp | 2 +- apps/openmw/mwrender/globalmap.cpp | 4 ++-- apps/openmw/mwrender/water.hpp | 2 +- apps/openmw/mwscript/scriptmanagerimp.hpp | 2 +- apps/openmw/mwsound/mpgsnd_decoder.hpp | 2 +- apps/openmw/mwsound/openal_output.hpp | 2 +- apps/openmw/mwsound/soundmanagerimp.hpp | 2 +- components/esm/aipackage.hpp | 2 +- components/esm_store/reclists.hpp | 4 ++-- libs/openengine/bullet/CMotionState.cpp | 2 +- libs/openengine/bullet/physic.cpp | 2 +- 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 614a840c4..b10562eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,7 +306,7 @@ endif() # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) - add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder) + add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++0x -pedantic) # Silence warnings in OGRE headers. Remove once OGRE got fixed! add_definitions (-Wno-ignored-qualifiers) diff --git a/apps/launcher/pluginsview.hpp b/apps/launcher/pluginsview.hpp index b3dfb79ff..484351e33 100644 --- a/apps/launcher/pluginsview.hpp +++ b/apps/launcher/pluginsview.hpp @@ -24,6 +24,6 @@ public slots: }; -Q_DECLARE_METATYPE(QVector); +Q_DECLARE_METATYPE(QVector) -#endif \ No newline at end of file +#endif diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index d396df648..19b69794f 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -78,7 +78,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { multistrmap::iterator it; if((it = map.find(key)) == map.end()) { - map.insert( std::make_pair > (key, std::vector() ) ); + map.insert( std::make_pair (key, std::vector() ) ); } map[key].push_back(value); } @@ -115,7 +115,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { multistrmap::iterator it; if((it = map.find(key)) == map.end()) { - map.insert( std::make_pair > (key, std::vector() ) ); + map.insert( std::make_pair (key, std::vector() ) ); } map[key].push_back(value); } @@ -152,12 +152,12 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { } } } -}; +} void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { multistrmap::iterator it = cfg.find(key); if(it == cfg.end()) { - cfg.insert(std::make_pair >(key, std::vector() )); + cfg.insert(std::make_pair (key, std::vector() )); } cfg[key].push_back(value); } diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 5c2ba2f80..2da52311f 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -68,7 +68,7 @@ void validate(boost::any &v, std::vector const &tokens, FallbackMap if((mapIt = map->mMap.find(key)) == map->mMap.end()) { - map->mMap.insert(std::make_pair(key,value)); + map->mMap.insert(std::make_pair (key,value)); } } } diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index 745832583..92c177ff3 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -37,7 +37,7 @@ namespace MWBase Play_Normal = 0, /* tracked, non-looping, multi-instance, environment */ Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */ Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */ - Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position + Play_NoTrack = 1<<2 /* (3D only) Play the sound at the given object's position * but do not keep it updated (the sound will not move with * the object and will not stop when the object is deleted. */ }; diff --git a/apps/openmw/mwmechanics/drawstate.hpp b/apps/openmw/mwmechanics/drawstate.hpp index 112b6e4f9..5be00505c 100644 --- a/apps/openmw/mwmechanics/drawstate.hpp +++ b/apps/openmw/mwmechanics/drawstate.hpp @@ -8,7 +8,7 @@ namespace MWMechanics { DrawState_Weapon = 0, DrawState_Spell = 1, - DrawState_Nothing = 2, + DrawState_Nothing = 2 }; } diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index c23fdc1a3..7a799a2e4 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -53,7 +53,7 @@ namespace MWRender { Ogre::Image image; - Ogre::uchar data[mWidth * mHeight * 3]; + std::vector data (mWidth * mHeight * 3); for (int x = mMinX; x <= mMaxX; ++x) { @@ -150,7 +150,7 @@ namespace MWRender } } - image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8); + image.loadDynamicImage (&data[0], mWidth, mHeight, Ogre::PF_B8G8R8); //image.save (mCacheDir + "/GlobalMap.png"); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index dcb76533b..f1e3d7a3b 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -23,7 +23,7 @@ namespace Ogre class Entity; class Vector3; struct RenderTargetEvent; -}; +} namespace MWRender { diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index bacc232b2..a97310ae5 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -74,6 +74,6 @@ namespace MWScript ///< Return index of the variable of the given name and type in the given script. Will /// throw an exception, if there is no such script or variable or the type does not match. }; -}; +} #endif diff --git a/apps/openmw/mwsound/mpgsnd_decoder.hpp b/apps/openmw/mwsound/mpgsnd_decoder.hpp index 870773edc..09082c2f4 100644 --- a/apps/openmw/mwsound/mpgsnd_decoder.hpp +++ b/apps/openmw/mwsound/mpgsnd_decoder.hpp @@ -52,6 +52,6 @@ namespace MWSound #ifndef DEFAULT_DECODER #define DEFAULT_DECODER (::MWSound::MpgSnd_Decoder) #endif -}; +} #endif diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index 90917c53c..fecffa575 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -66,6 +66,6 @@ namespace MWSound #ifndef DEFAULT_OUTPUT #define DEFAULT_OUTPUT (::MWSound::OpenAL_Output) #endif -}; +} #endif diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index f91e291ef..a84aa3b9a 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -26,7 +26,7 @@ namespace MWSound enum Environment { Env_Normal, - Env_Underwater, + Env_Underwater }; class SoundManager : public MWBase::SoundManager diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 3046a6a98..8e55b6889 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -60,7 +60,7 @@ namespace ESM AI_Travel = 0x545f4941, AI_Follow = 0x465f4941, AI_Escort = 0x455f4941, - AI_Activate = 0x415f4941, + AI_Activate = 0x415f4941 }; /// \note Used for storaging packages in a single container diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 24580a79c..0b265a566 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -331,7 +331,7 @@ namespace ESMS // Find land for the given coordinates. Return null if no mData. Land *search(int x, int y) const { - LandMap::const_iterator itr = lands.find(std::make_pair(x, y)); + LandMap::const_iterator itr = lands.find(std::make_pair (x, y)); if ( itr == lands.end() ) { return NULL; @@ -350,7 +350,7 @@ namespace ESMS land->load(esm); // Store the structure - lands[std::make_pair(land->mX, land->mY)] = land; + lands[std::make_pair (land->mX, land->mY)] = land; } }; diff --git a/libs/openengine/bullet/CMotionState.cpp b/libs/openengine/bullet/CMotionState.cpp index dc28d9e5f..6be615dfb 100644 --- a/libs/openengine/bullet/CMotionState.cpp +++ b/libs/openengine/bullet/CMotionState.cpp @@ -16,7 +16,7 @@ namespace Physic pEng = eng; tr.setIdentity(); pName = name; - }; + } void CMotionState::getWorldTransform(btTransform &worldTrans) const { diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index b42ffb84c..4f16a4143 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -626,4 +626,4 @@ namespace Physic shape->Shape->getAabb(trans, min, max); } -}}; +}} From 3fd887c030c4b4e9848356c1d4cb79645f457ee1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 9 Oct 2012 17:11:41 +0200 Subject: [PATCH 025/255] silenced some warnings --- components/esm/esmwriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 24658a40b..c1ae06490 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -138,11 +138,11 @@ void ESMWriter::writeHNString(const std::string& name, const std::string& data) void ESMWriter::writeHNString(const std::string& name, const std::string& data, int size) { - assert(data.size() <= size); + assert(static_cast (data.size()) <= size); startSubRecord(name); writeHString(data); - if (data.size() < size) + if (static_cast (data.size()) < size) { for (int i = data.size(); i < size; ++i) write("\0",1); From d97184cd4d144ca53b3df857f58b9dfcd3d74efc Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 9 Oct 2012 17:48:44 +0200 Subject: [PATCH 026/255] fixing some warnings --- extern/shiny | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/shiny b/extern/shiny index ffd078843..b9ed0f2f3 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit ffd078843c11586107024ccbc2493d0ec2df896c +Subproject commit b9ed0f2f3f10915aafd083248a1d6a37293c0db0 From 94f2937c8f87a04807e648c1085444da43d75cc6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 9 Oct 2012 19:28:10 +0200 Subject: [PATCH 027/255] missed a warning --- extern/shiny | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/shiny b/extern/shiny index b9ed0f2f3..f17c4ebab 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit b9ed0f2f3f10915aafd083248a1d6a37293c0db0 +Subproject commit f17c4ebab0e7a1f3bbb25fd9b3dbef2bd742536a From 50e259c060b3666c4d28e919474a3bbea14c922a Mon Sep 17 00:00:00 2001 From: cfcohen Date: Tue, 9 Oct 2012 19:41:45 -0400 Subject: [PATCH 028/255] Remove tabs as requested. Sorry about that, thought I already had. :-) I updated the help to better document the --type option, although I did not finish reasoning through it's interaction with the new loading framework. I also expanded the print() methods of a few more of the record types to make a more consistent commit. --- apps/esmtool/esmtool.cpp | 29 ++- apps/esmtool/record.cpp | 495 +++++++++++++++++++++++---------------- apps/esmtool/record.hpp | 4 +- 3 files changed, 317 insertions(+), 211 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 944bc7d8c..4f6d9dbfc 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -13,7 +13,7 @@ #include "record.hpp" -#define ESMTOOL_VERSION 1.1 +#define ESMTOOL_VERSION 1.2 // Create a local alias for brevity namespace bpo = boost::program_options; @@ -72,9 +72,12 @@ bool parseOptions (int argc, char** argv, Arguments &info) desc.add_options() ("help,h", "print help message.") ("version,v", "print version information and quit.") - ("raw,r", "Show an unformattet list of all records and subrecords.") - ("type,t", bpo::value< std::vector >(), - "Show only records of this type.") + ("raw,r", "Show an unformatted list of all records and subrecords.") + // The intention is that this option would interact better + // with other modes including clone, dump, and raw. + ("type,t", bpo::value< std::vector >(), + "Show only records of this type (four character record code). May " + "be specified multiple times. Only affects dump mode.") ("quiet,q", "Supress all record information. Useful for speed tests.") ("loadcells,C", "Browse through contents of all cells.") @@ -313,15 +316,15 @@ int load(Arguments& info) uint32_t flags; esm.getRecHeader(flags); - // Is the user interested in this record type? - bool interested = true; - if (info.types.size() > 0) - { - std::vector::iterator match; - match = std::find(info.types.begin(), info.types.end(), - n.toString()); - if (match == info.types.end()) interested = false; - } + // Is the user interested in this record type? + bool interested = true; + if (info.types.size() > 0) + { + std::vector::iterator match; + match = std::find(info.types.begin(), info.types.end(), + n.toString()); + if (match == info.types.end()) interested = false; + } std::string id = esm.getHNOString("NAME"); diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 38615b240..c679a1c4d 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -12,18 +12,18 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; if (p.mWander.mUnk != 1) - std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; std::cout << " Idle: "; for (int i = 0; i != 8; i++) - std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << (int)p.mWander.mIdle[i] << " "; std::cout << std::endl; } else if (p.mType == ESM::AI_Travel) { std::cout << " AIType Travel:" << std::endl; std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," - << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; } else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) @@ -32,7 +32,7 @@ void printAIPackage(ESM::AIPackage p) else std::cout << " AIType Escort:" << std::endl; std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," - << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; std::cout << " Duration: " << p.mTarget.mDuration << std::endl; std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; @@ -51,6 +51,27 @@ void printAIPackage(ESM::AIPackage p) std::cout << " Cell Name: " << p.mCellName << std::endl; } +void printEffectList(ESM::EffectList effects) +{ + int i = 0; + std::vector::iterator eit; + for (eit = effects.mList.begin(); eit != effects.mList.end(); eit++) + { + std::cout << " Effect[" << i << "]: " << eit->mEffectID << std::endl; + if (eit->mSkill != -1) + std::cout << " Skill: " << (int)eit->mSkill << std::endl; + if (eit->mAttribute != -1) + std::cout << " Attribute: " << (int)eit->mAttribute << std::endl; + std::cout << " Range: " << eit->mRange << std::endl; + // Area is always zero if range type is "Self" + if (eit->mRange != ESM::RT_Self) + std::cout << " Area: " << eit->mArea << std::endl; + std::cout << " Duration: " << eit->mDuration << std::endl; + std::cout << " Magnitude: " << eit->mMagnMin << "-" << eit->mMagnMax << std::endl; + i++; + } +} + namespace EsmTool { RecordBase * @@ -293,11 +314,11 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; - // mEffects missing + printEffectList(mData.mEffects); } template<> @@ -307,16 +328,23 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; std::cout << " Armor: " << mData.mData.mArmor << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - // mParts missing + std::vector::iterator pit; + for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) + { + std::cout << " Body Part: " << (int)(pit->mPart) << std::endl; + std::cout << " Male Name: " << pit->mMale << std::endl; + if (pit->mFemale != "") + std::cout << " Female Name: " << pit->mFemale << std::endl; + } } template<> @@ -350,15 +378,20 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; std::cout << " SkillID: " << mData.mData.mSkillID << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - // mText missing + std::cout << " Text: [skipped]" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << mData.mText << std::endl; + // std::cout << "-------------------------------------------" << std::endl; } template<> @@ -369,7 +402,7 @@ void Record::print() std::cout << " Description: " << mData.mDescription << std::endl; std::vector::iterator pit; for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++) - std::cout << " Power: " << *pit << std::endl; + std::cout << " Power: " << *pit << std::endl; } template<> @@ -377,25 +410,25 @@ void Record::print() { // None of the cells have names... if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; if (mData.mRegion != "") - std::cout << " Region: " << mData.mRegion << std::endl; + std::cout << " Region: " << mData.mRegion << std::endl; std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; std::cout << " Coordinates: " << " (" << mData.getGridX() << "," - << mData.getGridY() << ")" << std::endl; + << mData.getGridY() << ")" << std::endl; if (mData.mData.mFlags & ESM::Cell::Interior && - !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + !(mData.mData.mFlags & ESM::Cell::QuasiEx)) { - std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; - std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; - std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; - std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; - std::cout << " Water Level: " << mData.mWater << std::endl; + std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; + std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; + std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; + std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + std::cout << " Water Level: " << mData.mWater << std::endl; } else - std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; + std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl; std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; std::cout << " NAM0: " << mData.mNAM0 << std::endl; @@ -412,9 +445,9 @@ void Record::print() std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; + std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; } template<> @@ -424,9 +457,9 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -439,10 +472,13 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << mData.mFlags << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl; - // mInventory missing + std::vector::iterator cit; + for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; } template<> @@ -476,21 +512,21 @@ void Record::print() std::cout << " Magic: " << mData.mData.mMagic << std::endl; std::cout << " Stealth: " << mData.mData.mStealth << std::endl; std::cout << " Attack1: " << mData.mData.mAttack[0] - << "-" << mData.mData.mAttack[1] << std::endl; + << "-" << mData.mData.mAttack[1] << std::endl; std::cout << " Attack2: " << mData.mData.mAttack[2] - << "-" << mData.mData.mAttack[3] << std::endl; + << "-" << mData.mData.mAttack[3] << std::endl; std::cout << " Attack3: " << mData.mData.mAttack[4] - << "-" << mData.mData.mAttack[5] << std::endl; + << "-" << mData.mData.mAttack[5] << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl; std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; std::vector::iterator sit; for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) - std::cout << " Spell: " << *sit << std::endl; + std::cout << " Spell: " << *sit << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; @@ -505,14 +541,19 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) - printAIPackage(*pit); + printAIPackage(*pit); } template<> void Record::print() { std::cout << " Type: " << (int)mData.mType << std::endl; - // mInfo missing + // Sadly, there are no DialInfos, because the loader dumps as it + // loads, rather than loading and then dumping. :-( Anyone mind if + // I change this? + std::vector::iterator iit; + for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); iit++) + std::cout << "INFO!" << iit->mId << std::endl; } template<> @@ -532,7 +573,7 @@ void Record::print() std::cout << " Cost: " << mData.mData.mCost << std::endl; std::cout << " Charge: " << mData.mData.mCharge << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; - // mEffects missing + printEffectList(mData.mEffects); } template<> @@ -541,30 +582,30 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; if (mData.mData.mUnknown != -1) - std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; + std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; for (int i = 0; i != 6; i++) - if (mData.mData.mSkillID[i] != -1) - std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + if (mData.mData.mSkillID[i] != -1) + std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; for (int i = 0; i != 10; i++) - if (mData.mRanks[i] != "") - { - std::cout << " Rank: " << mData.mRanks[i] << std::endl; - std::cout << " Attribute1 Requirement: " - << mData.mData.mRankData[i].mAttribute1 << std::endl; - std::cout << " Attribute2 Requirement: " - << mData.mData.mRankData[i].mAttribute2 << std::endl; - std::cout << " One Skill at Level: " - << mData.mData.mRankData[i].mSkill1 << std::endl; - std::cout << " Two Skills at Level: " - << mData.mData.mRankData[i].mSkill2 << std::endl; - std::cout << " Faction Reaction: " - << mData.mData.mRankData[i].mFactReaction << std::endl; - } + if (mData.mRanks[i] != "") + { + std::cout << " Rank: " << mData.mRanks[i] << std::endl; + std::cout << " Attribute1 Requirement: " + << mData.mData.mRankData[i].mAttribute1 << std::endl; + std::cout << " Attribute2 Requirement: " + << mData.mData.mRankData[i].mAttribute2 << std::endl; + std::cout << " One Skill at Level: " + << mData.mData.mRankData[i].mSkill1 << std::endl; + std::cout << " Two Skills at Level: " + << mData.mData.mRankData[i].mSkill2 << std::endl; + std::cout << " Faction Reaction: " + << mData.mData.mRankData[i].mFactReaction << std::endl; + } std::vector::iterator rit; for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) - std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; + std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl; } template<> @@ -602,8 +643,53 @@ template<> void Record::print() { std::cout << " Id: " << mData.mId << std::endl; + if (mData.mPrev != "") + std::cout << " Previous ID: " << mData.mPrev << std::endl; + if (mData.mNext != "") + std::cout << " Next ID: " << mData.mNext << std::endl; std::cout << " Text: " << mData.mResponse << std::endl; - // Lots missing, more coming + if (mData.mActor != "") + std::cout << " Actor: " << mData.mActor << std::endl; + if (mData.mRace != "") + std::cout << " Race: " << mData.mRace << std::endl; + if (mData.mClass != "") + std::cout << " Class: " << mData.mClass << std::endl; + std::cout << " Factionless: " << mData.mFactionLess << std::endl; + if (mData.mNpcFaction != "") + std::cout << " NPC Faction: " << mData.mNpcFaction << std::endl; + if (mData.mData.mRank != -1) + std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; + if (mData.mPcFaction != "") + std::cout << " PC Faction: " << mData.mPcFaction << std::endl; + // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) + if (mData.mData.mPCrank != -1) + std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; + if (mData.mCell != "") + std::cout << " Cell: " << mData.mCell << std::endl; + if (mData.mData.mDisposition > 0) + std::cout << " Disposition: " << mData.mData.mDisposition << std::endl; + if (mData.mData.mGender != ESM::DialInfo::NA) + std::cout << " Gender: " << mData.mData.mGender << std::endl; + if (mData.mSound != "") + std::cout << " Sound File: " << mData.mSound << std::endl; + + if (mData.mResultScript != "") + { + std::cout << " Result Script: [skipped]" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << mData.mResultScript << std::endl; + // std::cout << "-------------------------------------------" << std::endl; + } + + std::cout << " Quest Status: " << mData.mQuestStatus << std::endl; + std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; + std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; + + std::vector::iterator sit; + for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++) + std::cout << " Select Rule: " << sit->mType << " " << sit->mSelectRule << std::endl; } template<> @@ -613,16 +699,16 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; for (int i = 0; i !=4; i++) { - // A value of -1 means no effect - if (mData.mData.mEffectID[i] == -1) continue; - std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; - std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; - std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + // A value of -1 means no effect + if (mData.mData.mEffectID[i] == -1) continue; + std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; + std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; + std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; } } @@ -630,7 +716,23 @@ template<> void Record::print() { std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; - // Lots missing, more coming + std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " HasData: " << mData.mHasData << std::endl; + std::cout << " DataTypes: " << mData.mDataTypes << std::endl; + + // Seems like this should done with reference counting in the + // loader to me. But I'm not really knowledgable about this + // record type yet. --Cory + bool wasLoaded = mData.mDataLoaded; + if (mData.mDataTypes) mData.loadData(mData.mDataTypes); + if (mData.mDataLoaded) + { + std::cout << " Height Offset: " << mData.mLandData->mHeightOffset << std::endl; + // Lots of missing members. + std::cout << " Unknown1: " << mData.mLandData->mUnk1 << std::endl; + std::cout << " Unknown2: " << mData.mLandData->mUnk2 << std::endl; + } + if (!wasLoaded) mData.unloadData(); } template<> @@ -641,8 +743,8 @@ void Record::print() std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) - std::cout << " Creature: Level: " << iit->mLevel - << " Creature: " << iit->mId << std::endl; + std::cout << " Creature: Level: " << iit->mLevel + << " Creature: " << iit->mId << std::endl; } template<> @@ -653,21 +755,21 @@ void Record::print() std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) - std::cout << " Inventory: Count: " << iit->mLevel - << " Item: " << iit->mId << std::endl; + std::cout << " Inventory: Count: " << iit->mLevel + << " Item: " << iit->mId << std::endl; } template<> void Record::print() { if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; if (mData.mModel != "") - std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; if (mData.mIcon != "") - std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -684,7 +786,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -699,7 +801,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -714,7 +816,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -739,30 +841,30 @@ void Record::print() std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl; if (mData.mCasting != "") - std::cout << " Casting Static: " << mData.mCasting << std::endl; + std::cout << " Casting Static: " << mData.mCasting << std::endl; if (mData.mCastSound != "") - std::cout << " Casting Sound: " << mData.mCastSound << std::endl; + std::cout << " Casting Sound: " << mData.mCastSound << std::endl; if (mData.mBolt != "") - std::cout << " Bolt Static: " << mData.mBolt << std::endl; + std::cout << " Bolt Static: " << mData.mBolt << std::endl; if (mData.mBoltSound != "") - std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; + std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; if (mData.mHit != "") - std::cout << " Hit Static: " << mData.mHit << std::endl; + std::cout << " Hit Static: " << mData.mHit << std::endl; if (mData.mHitSound != "") - std::cout << " Hit Sound: " << mData.mHitSound << std::endl; + std::cout << " Hit Sound: " << mData.mHitSound << std::endl; if (mData.mArea != "") - std::cout << " Area Static: " << mData.mArea << std::endl; + std::cout << " Area Static: " << mData.mArea << std::endl; if (mData.mAreaSound != "") - std::cout << " Area Sound: " << mData.mAreaSound << std::endl; + std::cout << " Area Sound: " << mData.mAreaSound << std::endl; std::cout << " School: " << mData.mData.mSchool << std::endl; std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; std::cout << " Speed: " << mData.mData.mSpeed << std::endl; std::cout << " Size: " << mData.mData.mSize << std::endl; std::cout << " Size Cap: " << mData.mData.mSizeCap << std::endl; std::cout << " RGB Color: " << "(" - << mData.mData.mRed << "," - << mData.mData.mGreen << "," - << mData.mData.mGreen << ")" << std::endl; + << mData.mData.mRed << "," + << mData.mData.mGreen << "," + << mData.mData.mGreen << ")" << std::endl; } template<> @@ -772,7 +874,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; @@ -788,77 +890,77 @@ void Record::print() std::cout << " Race: " << mData.mRace << std::endl; std::cout << " Class: " << mData.mClass << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mFaction != "") - std::cout << " Faction: " << mData.mFaction << std::endl; + std::cout << " Faction: " << mData.mFaction << std::endl; std::cout << " Flags: " << mData.mFlags << std::endl; // Seriously? if (mData.mNpdt52.mGold == -10) { - std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; - std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; - std::cout << " Unknown1: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; - std::cout << " Unknown2: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; - std::cout << " Unknown3: " - << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; - std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; + std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; + std::cout << " Faction: " << (int)mData.mNpdt52.mFactionID << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; + std::cout << " Unknown1: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; + std::cout << " Unknown2: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; + std::cout << " Unknown3: " + << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; + std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl; } else { - std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; + std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; - std::cout << " Attributes:" << std::endl; - std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; - std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; - std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; - std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; - std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; - std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; - std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; - std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; + std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; + std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; + std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; + std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; + std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; + std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; + std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; - std::cout << " Skills:" << std::endl; - for (int i = 0; i != 27; i++) - std::cout << " " << i << " = " - << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; - - std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; - std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; - std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; - std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; - std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; + std::cout << " Skills:" << std::endl; + for (int i = 0; i != 27; i++) + std::cout << " " << i << " = " + << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; + + std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; + std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; + std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; + std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; + std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; } std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount + << " Item: " << cit->mItem.toString() << std::endl; std::vector::iterator sit; for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) - std::cout << " Spell: " << *sit << std::endl; + std::cout << " Spell: " << *sit << std::endl; std::vector::iterator dit; for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++) { - std::cout << " Destination Position: " - << boost::format("%12.3f") % dit->mPos.pos[0] << "," - << boost::format("%12.3f") % dit->mPos.pos[1] << "," - << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; - std::cout << " Destination Rotation: " - << boost::format("%9.6f") % dit->mPos.rot[0] << "," - << boost::format("%9.6f") % dit->mPos.rot[1] << "," - << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; - if (dit->mCellName != "") - std::cout << " Destination Cell: " << dit->mCellName << std::endl; + std::cout << " Destination Position: " + << boost::format("%12.3f") % dit->mPos.pos[0] << "," + << boost::format("%12.3f") % dit->mPos.pos[1] << "," + << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + std::cout << " Destination Rotation: " + << boost::format("%9.6f") % dit->mPos.rot[0] << "," + << boost::format("%9.6f") % dit->mPos.rot[1] << "," + << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; + if (dit->mCellName != "") + std::cout << " Destination Cell: " << dit->mCellName << std::endl; } std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; @@ -874,7 +976,7 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) - printAIPackage(*pit); + printAIPackage(*pit); } template<> @@ -884,7 +986,7 @@ void Record::print() std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) - std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; + std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; std::cout << " Point Count: " << mData.mPoints.size() << std::endl; std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; @@ -892,22 +994,22 @@ void Record::print() ESM::Pathgrid::PointList::iterator pit; for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); pit++) { - std::cout << " Point[" << i << "]:" << std::endl; - std::cout << " Coordinates: (" << pit->mX << "," - << pit->mY << "," << pit->mZ << ")" << std::endl; - std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; - std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; - std::cout << " Unknown: " << pit->mUnknown << std::endl; - i++; + std::cout << " Point[" << i << "]:" << std::endl; + std::cout << " Coordinates: (" << pit->mX << "," + << pit->mY << "," << pit->mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; + std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; + std::cout << " Unknown: " << pit->mUnknown << std::endl; + i++; } i = 0; ESM::Pathgrid::EdgeList::iterator eit; for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); eit++) { - std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; - if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) - std::cout << " BAD POINT IN EDGE!" << std::endl; - i++; + std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; + if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) + std::cout << " BAD POINT IN EDGE!" << std::endl; + i++; } } @@ -920,57 +1022,57 @@ void Record::print() std::cout << " Male:" << std::endl; std::cout << " Strength: " - << mData.mData.mStrength.mMale << std::endl; + << mData.mData.mStrength.mMale << std::endl; std::cout << " Intelligence: " - << mData.mData.mIntelligence.mMale << std::endl; + << mData.mData.mIntelligence.mMale << std::endl; std::cout << " Willpower: " - << mData.mData.mWillpower.mMale << std::endl; + << mData.mData.mWillpower.mMale << std::endl; std::cout << " Agility: " - << mData.mData.mAgility.mMale << std::endl; + << mData.mData.mAgility.mMale << std::endl; std::cout << " Speed: " - << mData.mData.mSpeed.mMale << std::endl; + << mData.mData.mSpeed.mMale << std::endl; std::cout << " Endurance: " - << mData.mData.mEndurance.mMale << std::endl; + << mData.mData.mEndurance.mMale << std::endl; std::cout << " Personality: " - << mData.mData.mPersonality.mMale << std::endl; + << mData.mData.mPersonality.mMale << std::endl; std::cout << " Luck: " - << mData.mData.mLuck.mMale << std::endl; + << mData.mData.mLuck.mMale << std::endl; std::cout << " Height: " - << mData.mData.mHeight.mMale << std::endl; + << mData.mData.mHeight.mMale << std::endl; std::cout << " Weight: " - << mData.mData.mWeight.mMale << std::endl; + << mData.mData.mWeight.mMale << std::endl; std::cout << " Female:" << std::endl; std::cout << " Strength: " - << mData.mData.mStrength.mFemale << std::endl; + << mData.mData.mStrength.mFemale << std::endl; std::cout << " Intelligence: " - << mData.mData.mIntelligence.mFemale << std::endl; + << mData.mData.mIntelligence.mFemale << std::endl; std::cout << " Willpower: " - << mData.mData.mWillpower.mFemale << std::endl; + << mData.mData.mWillpower.mFemale << std::endl; std::cout << " Agility: " - << mData.mData.mAgility.mFemale << std::endl; + << mData.mData.mAgility.mFemale << std::endl; std::cout << " Speed: " - << mData.mData.mSpeed.mFemale << std::endl; + << mData.mData.mSpeed.mFemale << std::endl; std::cout << " Endurance: " - << mData.mData.mEndurance.mFemale << std::endl; + << mData.mData.mEndurance.mFemale << std::endl; std::cout << " Personality: " - << mData.mData.mPersonality.mFemale << std::endl; + << mData.mData.mPersonality.mFemale << std::endl; std::cout << " Luck: " - << mData.mData.mLuck.mFemale << std::endl; + << mData.mData.mLuck.mFemale << std::endl; std::cout << " Height: " - << mData.mData.mHeight.mFemale << std::endl; + << mData.mData.mHeight.mFemale << std::endl; std::cout << " Weight: " - << mData.mData.mWeight.mFemale << std::endl; + << mData.mData.mWeight.mFemale << std::endl; for (int i = 0; i != 7; i++) - // Not all races have 7 skills. - if (mData.mData.mBonus[i].mSkill != -1) - std::cout << " Skill: " << mData.mData.mBonus[i].mSkill - << " = " << mData.mData.mBonus[i].mBonus << std::endl; + // Not all races have 7 skills. + if (mData.mData.mBonus[i].mSkill != -1) + std::cout << " Skill: " << mData.mData.mBonus[i].mSkill + << " = " << mData.mData.mBonus[i].mBonus << std::endl; std::vector::iterator sit; for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) - std::cout << " Power: " << *sit << std::endl; + std::cout << " Power: " << *sit << std::endl; } template<> @@ -991,10 +1093,10 @@ void Record::print() std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; std::cout << " Map Color: " << mData.mMapColor << std::endl; if (mData.mSleepList != "") - std::cout << " Sleep List: " << mData.mSleepList << std::endl; + std::cout << " Sleep List: " << mData.mSleepList << std::endl; std::vector::iterator sit; for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++) - std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; + std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; } template<> @@ -1009,18 +1111,19 @@ void Record::print() std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; std::cout << " Script: [skipped]" << std::endl; - // Skip until multi-line field is controllable by a command line option. - //std::cout << "-------------------------------------------" << std::endl; - //std::cout << s->scriptText << std::endl; - //std::cout << "-------------------------------------------" << std::endl; + // Skip until multi-line fields is controllable by a command line option. + // Mildly problematic because there are no parameter to print() currently. + // std::cout << "-------------------------------------------" << std::endl; + // std::cout << s->scriptText << std::endl; + // std::cout << "-------------------------------------------" << std::endl; std::vector::iterator vit; for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++) - std::cout << " Variable: " << *vit << std::endl; + std::cout << " Variable: " << *vit << std::endl; std::cout << " ByteCode: "; std::vector::iterator cit; for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++) - std::cout << boost::format("%02X") % (int)(*cit); + std::cout << boost::format("%02X") % (int)(*cit); std::cout << std::endl; } @@ -1055,8 +1158,8 @@ void Record::print() std::cout << " Sound: " << mData.mSound << std::endl; std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) - std::cout << " Range: " << (int)mData.mData.mMinRange << " - " - << (int)mData.mData.mMaxRange << std::endl; + std::cout << " Range: " << (int)mData.mData.mMinRange << " - " + << (int)mData.mData.mMaxRange << std::endl; } template<> @@ -1066,7 +1169,7 @@ void Record::print() std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; - // mEffect missing + printEffectList(mData.mEffects); } template<> @@ -1087,15 +1190,15 @@ void Record::print() { // No names on VFX bolts if (mData.mName != "") - std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; // No icons on VFX bolts or magic bolts if (mData.mIcon != "") - std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") - std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") - std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << mData.mData.mType << std::endl; std::cout << " Flags: " << mData.mData.mFlags << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; @@ -1105,14 +1208,14 @@ void Record::print() std::cout << " Reach: " << mData.mData.mReach << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) - std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" - << (int)mData.mData.mChop[1] << std::endl; + std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" + << (int)mData.mData.mChop[1] << std::endl; if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) - std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" - << (int)mData.mData.mSlash[1] << std::endl; + std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" + << (int)mData.mData.mSlash[1] << std::endl; if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) - std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" - << (int)mData.mData.mThrust[1] << std::endl; + std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" + << (int)mData.mData.mThrust[1] << std::endl; } template<> diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index e75870ab6..c3daa9d0c 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -20,7 +20,7 @@ namespace EsmTool protected: std::string mId; int mFlags; - ESM::NAME mType; + ESM::NAME mType; public: RecordBase () {} @@ -42,7 +42,7 @@ namespace EsmTool mFlags = flags; } - ESM::NAME getType() const { + ESM::NAME getType() const { return mType; } From 4174d3c235dad55d2ec7a908576861cd51ca3b98 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Wed, 10 Oct 2012 21:31:40 +0200 Subject: [PATCH 029/255] Added new plugin model for the Data Files tab in the launcher --- apps/launcher/CMakeLists.txt | 18 +- apps/launcher/model/datafilesmodel.cpp | 443 +++++++++++++++++++++++++ apps/launcher/model/datafilesmodel.hpp | 67 ++++ apps/launcher/model/esm/esmfile.cpp | 50 +++ apps/launcher/model/esm/esmfile.hpp | 54 +++ apps/launcher/model/modelitem.cpp | 57 ++++ apps/launcher/model/modelitem.hpp | 32 ++ 7 files changed, 718 insertions(+), 3 deletions(-) create mode 100644 apps/launcher/model/datafilesmodel.cpp create mode 100644 apps/launcher/model/datafilesmodel.hpp create mode 100644 apps/launcher/model/esm/esmfile.cpp create mode 100644 apps/launcher/model/esm/esmfile.hpp create mode 100644 apps/launcher/model/modelitem.cpp create mode 100644 apps/launcher/model/modelitem.hpp diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 2bc43db80..53631ebdd 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -1,5 +1,6 @@ set(LAUNCHER datafilespage.cpp + filedialog.cpp graphicspage.cpp lineedit.cpp main.cpp @@ -8,14 +9,18 @@ set(LAUNCHER playpage.cpp pluginsmodel.cpp pluginsview.cpp - filedialog.cpp launcher.rc + + model/datafilesmodel.cpp + model/modelitem.cpp + model/esm/esmfile.cpp ) set(LAUNCHER_HEADER combobox.hpp datafilespage.hpp + filedialog.hpp graphicspage.hpp lineedit.hpp maindialog.hpp @@ -23,20 +28,27 @@ set(LAUNCHER_HEADER playpage.hpp pluginsmodel.hpp pluginsview.hpp - filedialog.hpp + + model/datafilesmodel.hpp + model/modelitem.hpp + model/esm/esmfile.hpp ) # Headers that must be pre-processed set(LAUNCHER_HEADER_MOC combobox.hpp datafilespage.hpp + filedialog.hpp graphicspage.hpp lineedit.hpp maindialog.hpp playpage.hpp pluginsmodel.hpp pluginsview.hpp - filedialog.hpp + + model/datafilesmodel.hpp + model/modelitem.hpp + model/esm/esmfile.hpp ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC}) diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp new file mode 100644 index 000000000..be89902c8 --- /dev/null +++ b/apps/launcher/model/datafilesmodel.cpp @@ -0,0 +1,443 @@ +#include +#include +#include + +#include + +#include "esm/esmfile.hpp" + +#include "datafilesmodel.hpp" +#include "../naturalsort.hpp" + +DataFilesModel::DataFilesModel(QObject *parent) : + QAbstractTableModel(parent) +{ +} + +DataFilesModel::~DataFilesModel() +{ +} + +void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) +{ + setData(index, state, Qt::CheckStateRole); +} + +Qt::CheckState DataFilesModel::checkState(const QModelIndex &index) +{ + EsmFile *file = item(index.row()); + return mCheckStates[file->fileName()]; +} + +int DataFilesModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : 9; +} + +int DataFilesModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : mFiles.count(); +} + + +bool DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) +{ + if (oldrow < 0 || row < 0 || oldrow == row) + return false; + + emit layoutAboutToBeChanged(); + //emit beginMoveRows(parent, oldrow, oldrow, parent, row); + mFiles.swap(oldrow, row); + //emit endInsertRows(); + emit layoutChanged(); + + return true; +} + +QVariant DataFilesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + +// if (index.row() < 0 || index.row() >= mPlugins.size()) +// return QVariant(); + + EsmFile *file = mFiles.at(index.row()); + + const int column = index.column(); + + switch (role) { + case Qt::DisplayRole: { + + switch (column) { + case 0: + return file->fileName(); + case 1: + return file->author(); + case 2: + return QString("%1 kB").arg(int((file->size() + 1023) / 1024)); + case 3: + //return file->modified().toString(Qt::TextDate); + return file->modified().toString(Qt::ISODate); + case 4: + return file->accessed().toString(Qt::TextDate); + case 5: + return file->version(); + case 6: + return file->path(); + case 7: + return file->masters().join(", "); + case 8: + return file->description(); + } + } + + case Qt::TextAlignmentRole: { + switch (column) { + case 0: + return Qt::AlignLeft + Qt::AlignVCenter; + case 1: + return Qt::AlignLeft + Qt::AlignVCenter; + case 2: + return Qt::AlignRight + Qt::AlignVCenter; + case 3: + return Qt::AlignRight + Qt::AlignVCenter; + case 4: + return Qt::AlignRight + Qt::AlignVCenter; + case 5: + return Qt::AlignRight + Qt::AlignVCenter; + default: + return Qt::AlignLeft + Qt::AlignVCenter; + } + } + + case Qt::CheckStateRole: { + if (column != 0) + return QVariant(); + return mCheckStates[file->fileName()]; + } + case Qt::ToolTipRole: + { + if (column != 0) + return QVariant(); + + if (file->version() == 0.0f) + return QVariant(); // Data not set + + QString tooltip = + QString("Author: %1
\ + Version: %2
\ +
Description:
%3
\ +
Dependencies: %4
") + .arg(file->author()) + .arg(QString::number(file->version())) + .arg(file->description()) + .arg(file->masters().join(", ")); + + + return tooltip; + + } + default: + return QVariant(); + } + +} + +Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + EsmFile *file = mFiles.at(index.row()); + + if (mAvailableFiles.contains(file->fileName())) { + if (index.column() == 0) { + return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + } else { + if (index.column() == 0) { + return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } else { + return Qt::NoItemFlags | Qt::ItemIsSelectable; + } + } + +} + +QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: return tr("Name"); + case 1: return tr("Author"); + case 2: return tr("Size"); + case 3: return tr("Modified"); + case 4: return tr("Accessed"); + case 5: return tr("Version"); + case 6: return tr("Path"); + case 7: return tr("Masters"); + case 8: return tr("Description"); + } + } else { + // Show row numbers + return ++section; + } + + return QVariant(); +} + +bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + + if (role == Qt::CheckStateRole) { + + emit layoutAboutToBeChanged(); + + QString name = item(index.row())->fileName(); + mCheckStates[name] = static_cast(value.toInt()); + + emit checkedItemsChanged(checkedItems(), uncheckedItems()); + emit layoutChanged(); + return true; + } + + return false; +} + +void DataFilesModel::sort(int column, Qt::SortOrder order) +{ + // TODO: Make this more efficient + emit layoutAboutToBeChanged(); + + // A reference list we can sort + QStringList all = uncheckedItems(); + //all.append(uncheckedItems()); + + // Sort the list of items naturally + qSort(all.begin(), all.end(), naturalSortLessThanCI); + + for (int i = 0; i < all.size(); ++i) { + const QString currentItem = all.at(i); + QModelIndex index = indexFromItem(findItem(currentItem)); + + // Move the actual item from the old position to the new + if (index.isValid()) + mFiles.swap(index.row(), i); + } + + emit layoutChanged(); +} + +void DataFilesModel::addFile(EsmFile *file) +{ + emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); + mFiles.append(file); + emit endInsertRows(); +} + +void DataFilesModel::addMasters(const QString &path) +{ + QDir dir(path); + dir.setNameFilters(QStringList(QLatin1String("*.esp"))); + + // Read the dependencies from the plugins + foreach (const QString &path, dir.entryList()) { + QFileInfo info(dir.absoluteFilePath(path)); + + try { + ESM::ESMReader fileReader; + fileReader.setEncoding(std::string("win1252")); + fileReader.open(dir.absoluteFilePath(path).toStdString()); + + ESM::ESMReader::MasterList mlist = fileReader.getMasters(); + + for (unsigned int i = 0; i < mlist.size(); ++i) { + QString master = QString::fromStdString(mlist[i].name); + + // Add the plugin to the internal dependency map + mDependencies[master].append(path); + + // Don't add esps + if (master.endsWith(".esp", Qt::CaseInsensitive)) + continue; + + EsmFile *file = new EsmFile(master); + + // Add the master to the table + if (findItem(master) == 0) + addFile(file); + + + } + + } catch(std::runtime_error &e) { + // An error occurred while reading the .esp + continue; + } + } + + // See if the masters actually exist in the filesystem + dir.setNameFilters(QStringList(QLatin1String("*.esm"))); + + foreach (const QString &path, dir.entryList()) { + + if (findItem(path) == 0) { + EsmFile *file = new EsmFile(path); + addFile(file); + } + + // Make the master selectable + mAvailableFiles.append(path); + } +} + +void DataFilesModel::addPlugins(const QString &path) +{ + QDir dir(path); + dir.setNameFilters(QStringList(QLatin1String("*.esp"))); + + foreach (const QString &path, dir.entryList()) { + QFileInfo info(dir.absoluteFilePath(path)); + EsmFile *file = new EsmFile(path); + + try { + ESM::ESMReader fileReader; + fileReader.setEncoding(std::string("win1252")); + fileReader.open(dir.absoluteFilePath(path).toStdString()); + + ESM::ESMReader::MasterList mlist = fileReader.getMasters(); + QStringList masters; + + for (unsigned int i = 0; i < mlist.size(); ++i) { + QString master = QString::fromStdString(mlist[i].name); + masters.append(master); + + // Add the plugin to the internal dependency map + mDependencies[master].append(path); + } + + file->setAuthor(QString::fromStdString(fileReader.getAuthor())); + file->setSize(info.size()); + file->setDates(info.lastModified(), info.lastRead()); + file->setVersion(fileReader.getFVer()); + file->setPath(info.absoluteFilePath()); + file->setMasters(masters); + file->setDescription(QString::fromStdString(fileReader.getDesc())); + + + // Put the file in the table + addFile(file); + } catch(std::runtime_error &e) { + // An error occurred while reading the .esp + continue; + } + + } +} + +QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const +{ + if (item) + return createIndex(mFiles.indexOf(item), 0); + + return QModelIndex(); +} + +EsmFile* DataFilesModel::findItem(const QString &name) +{ + QList::ConstIterator it; + QList::ConstIterator itEnd = mFiles.constEnd(); + + int i = 0; + for (it = mFiles.constBegin(); it != itEnd; ++it) { + EsmFile *file = item(i); + ++i; + + if (name == file->fileName()) + return file; + } + + // Not found + return 0; +} + +EsmFile* DataFilesModel::item(int row) +{ + if (row >= 0 && row < mFiles.count()) + return mFiles.at(row); + else + return 0; +} + +QStringList DataFilesModel::checkedItems() +{ + QStringList list; + QHash::ConstIterator it; + QHash::ConstIterator itEnd = mCheckStates.constEnd(); + + for (it = mCheckStates.constBegin(); it != itEnd; ++it) { + if (it.value() == Qt::Checked) { + list << it.key(); + } + } + + return list; +} + +void DataFilesModel::uncheckAll() +{ + emit layoutAboutToBeChanged(); + mCheckStates.clear(); + emit layoutChanged(); +} + +QStringList DataFilesModel::uncheckedItems() +{ + QStringList list; + QStringList checked = checkedItems(); + + QList::ConstIterator it; + QList::ConstIterator itEnd = mFiles.constEnd(); + + int i = 0; + for (it = mFiles.constBegin(); it != itEnd; ++it) { + EsmFile *file = item(i); + ++i; + + // Add the items that are not in the checked list + if (!checked.contains(file->fileName())) + list << file->fileName(); + } + + return list; +} + +void DataFilesModel::slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems) +{ + emit layoutAboutToBeChanged(); + + QStringList list; + + foreach (const QString &file, checkedItems) { + list << mDependencies[file]; + } + + foreach (const QString &file, unCheckedItems) { + foreach (const QString &remove, mDependencies[file]) { + list.removeAll(remove); + } + } + + mAvailableFiles.clear(); + mAvailableFiles.append(list); + + emit layoutChanged(); +} diff --git a/apps/launcher/model/datafilesmodel.hpp b/apps/launcher/model/datafilesmodel.hpp new file mode 100644 index 000000000..8710ba88d --- /dev/null +++ b/apps/launcher/model/datafilesmodel.hpp @@ -0,0 +1,67 @@ +#ifndef DATAFILESMODEL_HPP +#define DATAFILESMODEL_HPP + +#include +#include +#include +#include + + +class EsmFile; + +class DataFilesModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit DataFilesModel(QObject *parent = 0); + virtual ~DataFilesModel(); + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + + bool moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex()); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + + inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const + { return QAbstractTableModel::index(row, column, parent); } + + void addFile(EsmFile *file); + + void addMasters(const QString &path); + void addPlugins(const QString &path); + + void uncheckAll(); + + QStringList checkedItems(); + QStringList uncheckedItems(); + + Qt::CheckState checkState(const QModelIndex &index); + void setCheckState(const QModelIndex &index, Qt::CheckState state); + + QModelIndex indexFromItem(EsmFile *item) const; + EsmFile* findItem(const QString &name); + EsmFile* item(int row); + +signals: + void checkedItemsChanged(const QStringList checkedItems, const QStringList unCheckedItems); + +public slots: + void slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems); + +private: + QList mFiles; + QStringList mAvailableFiles; + + QHash mDependencies; + QHash mCheckStates; + +}; + +#endif // DATAFILESMODEL_HPP diff --git a/apps/launcher/model/esm/esmfile.cpp b/apps/launcher/model/esm/esmfile.cpp new file mode 100644 index 000000000..93d83091e --- /dev/null +++ b/apps/launcher/model/esm/esmfile.cpp @@ -0,0 +1,50 @@ +#include "esmfile.hpp" + +EsmFile::EsmFile(QString fileName, ModelItem *parent) + : ModelItem(parent) +{ + mFileName = fileName; + mSize = 0; + mVersion = 0.0f; +} + +void EsmFile::setFileName(const QString &fileName) +{ + mFileName = fileName; +} + +void EsmFile::setAuthor(const QString &author) +{ + mAuthor = author; +} + +void EsmFile::setSize(const int size) +{ + mSize = size; +} + +void EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed) +{ + mModified = modified; + mAccessed = accessed; +} + +void EsmFile::setVersion(float version) +{ + mVersion = version; +} + +void EsmFile::setPath(const QString &path) +{ + mPath = path; +} + +void EsmFile::setMasters(const QStringList &masters) +{ + mMasters = masters; +} + +void EsmFile::setDescription(const QString &description) +{ + mDescription = description; +} diff --git a/apps/launcher/model/esm/esmfile.hpp b/apps/launcher/model/esm/esmfile.hpp new file mode 100644 index 000000000..ad267aa75 --- /dev/null +++ b/apps/launcher/model/esm/esmfile.hpp @@ -0,0 +1,54 @@ +#ifndef ESMFILE_HPP +#define ESMFILE_HPP + +#include +#include + +#include "../modelitem.hpp" + +class EsmFile : public ModelItem +{ + Q_OBJECT + Q_PROPERTY(QString filename READ fileName) + +public: + EsmFile(QString fileName = QString(), ModelItem *parent = 0); + + ~EsmFile() + {} + + void setFileName(const QString &fileName); + void setAuthor(const QString &author); + void setSize(const int size); + void setDates(const QDateTime &modified, const QDateTime &accessed); + void setVersion(const float version); + void setPath(const QString &path); + void setMasters(const QStringList &masters); + void setDescription(const QString &description); + + inline QString fileName() { return mFileName; } + inline QString author() { return mAuthor; } + inline int size() { return mSize; } + inline QDateTime modified() { return mModified; } + inline QDateTime accessed() { return mAccessed; } + inline float version() { return mVersion; } + inline QString path() { return mPath; } + inline QStringList masters() { return mMasters; } + inline QString description() { return mDescription; } + + +private: + QString mFileName; + QString mAuthor; + int mSize; + QDateTime mModified; + QDateTime mAccessed; + float mVersion; + QString mPath; + QStringList mMasters; + QString mDescription; + +}; + + +#endif diff --git a/apps/launcher/model/modelitem.cpp b/apps/launcher/model/modelitem.cpp new file mode 100644 index 000000000..0ff7e45cb --- /dev/null +++ b/apps/launcher/model/modelitem.cpp @@ -0,0 +1,57 @@ +#include "modelitem.hpp" + +ModelItem::ModelItem(ModelItem *parent) + : mParentItem(parent) + , QObject(parent) +{ +} + +ModelItem::~ModelItem() +{ + qDeleteAll(mChildItems); +} + + +ModelItem *ModelItem::parent() +{ + return mParentItem; +} + +int ModelItem::row() const +{ + if (mParentItem) + return 1; + //return mParentItem->childRow(const_cast(this)); + //return mParentItem->mChildItems.indexOf(const_cast(this)); + + return -1; +} + + +int ModelItem::childCount() const +{ + return mChildItems.count(); +} + +int ModelItem::childRow(ModelItem *child) const +{ + Q_ASSERT(child); + + return mChildItems.indexOf(child); +} + +ModelItem *ModelItem::child(int row) +{ + return mChildItems.value(row); +} + + +void ModelItem::appendChild(ModelItem *item) +{ + mChildItems.append(item); +} + +void ModelItem::removeChild(int row) +{ + mChildItems.removeAt(row); +} diff --git a/apps/launcher/model/modelitem.hpp b/apps/launcher/model/modelitem.hpp new file mode 100644 index 000000000..f4cb4322f --- /dev/null +++ b/apps/launcher/model/modelitem.hpp @@ -0,0 +1,32 @@ +#ifndef MODELITEM_HPP +#define MODELITEM_HPP + +#include +#include + +class ModelItem : public QObject +{ + Q_OBJECT + +public: + ModelItem(ModelItem *parent = 0); + ~ModelItem(); + + ModelItem *parent(); + int row() const; + + int childCount() const; + int childRow(ModelItem *child) const; + ModelItem *child(int row); + + void appendChild(ModelItem *child); + void removeChild(int row); + + //virtual bool acceptChild(ModelItem *child); + +protected: + ModelItem *mParentItem; + QList mChildItems; +}; + +#endif From 57736769860c97eede190dfd6d3cfd92d5b2e37a Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Wed, 10 Oct 2012 22:58:04 +0200 Subject: [PATCH 030/255] Got the Data Files tab to use the new model --- apps/launcher/datafilespage.cpp | 1210 ++++++++---------------- apps/launcher/datafilespage.hpp | 49 +- apps/launcher/model/datafilesmodel.cpp | 2 +- 3 files changed, 395 insertions(+), 866 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 8ca3c9aed..c0a447e26 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -3,12 +3,14 @@ #include #include +#include "model/datafilesmodel.hpp" +#include "model/esm/esmfile.hpp" + +#include "combobox.hpp" #include "datafilespage.hpp" -#include "lineedit.hpp" #include "filedialog.hpp" +#include "lineedit.hpp" #include "naturalsort.hpp" -#include "pluginsmodel.hpp" -#include "pluginsview.hpp" #include /** @@ -46,13 +48,15 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) : QWidget(parent) , mCfgMgr(cfg) { - mDataFilesModel = new QStandardItemModel(); // Contains all plugins with masters - mPluginsModel = new PluginsModel(); // Contains selectable plugins + // Models + mMastersModel = new DataFilesModel(this); + mPluginsModel = new DataFilesModel(this); mPluginsProxyModel = new QSortFilterProxyModel(); mPluginsProxyModel->setDynamicSortFilter(true); mPluginsProxyModel->setSourceModel(mPluginsModel); + // Filter toolbar QLabel *filterLabel = new QLabel(tr("&Filter:"), this); LineEdit *filterLineEdit = new LineEdit(this); filterLabel->setBuddy(filterLineEdit); @@ -71,40 +75,62 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) filterToolBar->addWidget(filterWidget); - mMastersWidget = new QTableWidget(this); // Contains the available masters - mMastersWidget->setObjectName("MastersWidget"); - mMastersWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - mMastersWidget->setSelectionMode(QAbstractItemView::MultiSelection); - mMastersWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - mMastersWidget->setAlternatingRowColors(true); - mMastersWidget->horizontalHeader()->setStretchLastSection(true); - mMastersWidget->horizontalHeader()->hide(); - mMastersWidget->verticalHeader()->hide(); - mMastersWidget->insertColumn(0); - - mPluginsTable = new PluginsView(this); - mPluginsTable->setModel(mPluginsProxyModel); - mPluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); - - mPluginsTable->horizontalHeader()->setStretchLastSection(true); - mPluginsTable->horizontalHeader()->hide(); - - // Set the row height to the size of the checkboxes QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; + mMastersTable = new QTableView(this); + mMastersTable->setModel(mMastersModel); + mMastersTable->setObjectName("MastersTable"); + mMastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); + mMastersTable->setSelectionMode(QAbstractItemView::SingleSelection); + mMastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + mMastersTable->setAlternatingRowColors(true); + mMastersTable->horizontalHeader()->setStretchLastSection(true); + mMastersTable->horizontalHeader()->hide(); + + // Set the row height to the size of the checkboxes + mMastersTable->verticalHeader()->setDefaultSectionSize(height); + mMastersTable->verticalHeader()->hide(); + mMastersTable->setColumnHidden(1, true); + mMastersTable->setColumnHidden(2, true); + mMastersTable->setColumnHidden(3, true); + mMastersTable->setColumnHidden(4, true); + mMastersTable->setColumnHidden(5, true); + mMastersTable->setColumnHidden(6, true); + mMastersTable->setColumnHidden(7, true); + mMastersTable->setColumnHidden(8, true); + + mPluginsTable = new QTableView(this); + mPluginsTable->setModel(mPluginsProxyModel); + mPluginsTable->setObjectName("PluginsTable"); + mPluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); + mPluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); + mPluginsTable->setSelectionMode(QAbstractItemView::SingleSelection); + mPluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + mPluginsTable->setAlternatingRowColors(true); + mPluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); + mPluginsTable->horizontalHeader()->setStretchLastSection(true); + mPluginsTable->verticalHeader()->setDefaultSectionSize(height); + mPluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + mPluginsTable->setColumnHidden(1, true); + mPluginsTable->setColumnHidden(2, true); + mPluginsTable->setColumnHidden(3, true); + mPluginsTable->setColumnHidden(4, true); + mPluginsTable->setColumnHidden(5, true); + mPluginsTable->setColumnHidden(6, true); + mPluginsTable->setColumnHidden(7, true); + mPluginsTable->setColumnHidden(8, true); // Add both tables to a splitter QSplitter *splitter = new QSplitter(this); splitter->setOrientation(Qt::Horizontal); - - splitter->addWidget(mMastersWidget); + splitter->addWidget(mMastersTable); splitter->addWidget(mPluginsTable); // Adjust the default widget widths inside the splitter QList sizeList; - sizeList << 100 << 300; + sizeList << 175 << 200; splitter->setSizes(sizeList); // Bottom part with profile options @@ -127,20 +153,56 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) pageLayout->addWidget(splitter); pageLayout->addWidget(mProfileToolBar); - connect(mMastersWidget->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(masterSelectionChanged(const QItemSelection&, const QItemSelection&))); + connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + + connect(mMastersModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mPluginsModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList))); connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(const QString))); - connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mPluginsTable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&))); createActions(); setupConfig(); - //setupDataFiles(); +} + +void DataFilesPage::createActions() +{ + // Refresh the plugins + QAction *refreshAction = new QAction(tr("Refresh"), this); + refreshAction->setShortcut(QKeySequence(tr("F5"))); + connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh())); + + // Profile actions + mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this); + mNewProfileAction->setToolTip(tr("New Profile")); + mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N"))); + connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile())); + + mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this); + mDeleteProfileAction->setToolTip(tr("Delete Profile")); + mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete"))); + connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile())); + + // Add the newly created actions to the toolbar + mProfileToolBar->addSeparator(); + mProfileToolBar->addAction(mNewProfileAction); + mProfileToolBar->addAction(mDeleteProfileAction); + + // Context menu actions + mCheckAction = new QAction(tr("Check selected"), this); + connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check())); + + mUncheckAction = new QAction(tr("Uncheck selected"), this); + connect(mUncheckAction, SIGNAL(triggered()), this, SLOT(uncheck())); + + // Context menu for the plugins table + mContextMenu = new QMenu(this); + + mContextMenu->addAction(mCheckAction); + mContextMenu->addAction(mUncheckAction); } @@ -189,111 +251,81 @@ void DataFilesPage::setupConfig() } -void DataFilesPage::addDataFiles(Files::Collections &fileCollections, const QString &encoding) +void DataFilesPage::readConfig() { - // First we add all the master files - const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm"); - unsigned int i = 0; // Row number + // Don't read the config if no masters are found + if (mMastersModel->rowCount() < 1) + return; - for (Files::MultiDirCollection::TIter iter(esm.begin()); iter!=esm.end(); ++iter) { - QString currentMaster = QString::fromStdString( - boost::filesystem::path (iter->second.filename()).string()); + QString profile = mProfilesComboBox->currentText(); - const QList itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly); + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } - if (itemList.isEmpty()) { // Master is not yet in the widget - mMastersWidget->insertRow(i); - QTableWidgetItem *item = new QTableWidgetItem(currentMaster); - mMastersWidget->setItem(i, 0, item); - ++i; + mLauncherConfig->beginGroup("Profiles"); + mLauncherConfig->beginGroup(profile); + + QStringList childKeys = mLauncherConfig->childKeys(); + QStringList plugins; + + // Sort the child keys numerical instead of alphabetically + // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 + qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); + + foreach (const QString &key, childKeys) { + const QString keyValue = mLauncherConfig->value(key).toString(); + + if (key.startsWith("Plugin")) { + //QStringList checked = mPluginsModel->checkedItems(); + EsmFile *file = mPluginsModel->findItem(keyValue); + QModelIndex index = mPluginsModel->indexFromItem(file); + + mPluginsModel->setCheckState(index, Qt::Checked); + // Move the row to the top of te view + //mPluginsModel->moveRow(index.row(), checked.count()); + plugins << keyValue; + } + + if (key.startsWith("Master")) { + EsmFile *file = mMastersModel->findItem(keyValue); + mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked); } } - // Now on to the plugins - const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp"); + qDebug() << plugins; - for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter) { - try { - ESMReader fileReader; - QStringList availableMasters; // Will contain all found masters +// // Set the checked item positions +// const QStringList checked = mPluginsModel->checkedItems(); +// for (int i = 0; i < plugins.size(); ++i) { +// EsmFile *file = mPluginsModel->findItem(plugins.at(i)); +// QModelIndex index = mPluginsModel->indexFromItem(file); +// mPluginsModel->moveRow(index.row(), i); +// qDebug() << "Moving: " << plugins.at(i) << " from: " << index.row() << " to: " << i << " count: " << checked.count(); - fileReader.setEncoding(encoding.toStdString()); - fileReader.open(iter->second.string()); +// } - // First we fill the availableMasters and the mMastersWidget - ESMReader::MasterList mlist = fileReader.getMasters(); + // Iterate over the plugins to set their checkstate and position +// for (int i = 0; i < plugins.size(); ++i) { +// const QString plugin = plugins.at(i); - for (unsigned int i = 0; i < mlist.size(); ++i) { - const QString currentMaster = QString::fromStdString(mlist[i].name); - availableMasters.append(currentMaster); +// const QList pluginList = mPluginsModel->findItems(plugin); - const QList itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly); - - if (itemList.isEmpty()) { // Master is not yet in the widget - mMastersWidget->insertRow(i); - - QTableWidgetItem *item = new QTableWidgetItem(currentMaster); - item->setForeground(Qt::red); - item->setFlags(item->flags() & ~(Qt::ItemIsSelectable)); - - mMastersWidget->setItem(i, 0, item); - } - } - - availableMasters.sort(); // Sort the masters alphabetically - - // Now we put the current plugin in the mDataFilesModel under its masters - QStandardItem *parent = new QStandardItem(availableMasters.join(",")); - - QString fileName = QString::fromStdString(boost::filesystem::path (iter->second.filename()).string()); - QStandardItem *child = new QStandardItem(fileName); - - // Tooltip information - QString author = QString::fromStdString(fileReader.getAuthor()); - float version = fileReader.getFVer(); - QString description = QString::fromStdString(fileReader.getDesc()); - - // For the date created/modified - QFileInfo fi(QString::fromStdString(iter->second.string())); - - QString toolTip= QString("Author: %1
\ - Version: %2

\ - Description:
\ - %3

\ - Created on: %4
\ - Last modified: %5") - .arg(author) - .arg(version) - .arg(description) - .arg(fi.created().toString(Qt::TextDate)) - .arg(fi.lastModified().toString(Qt::TextDate)); - - child->setToolTip(toolTip); - - const QList masterList = mDataFilesModel->findItems(availableMasters.join(",")); - - if (masterList.isEmpty()) { // Masters node not yet in the mDataFilesModel - parent->appendRow(child); - mDataFilesModel->appendRow(parent); - } else { - // Masters node exists, append current plugin - foreach (QStandardItem *currentItem, masterList) { - currentItem->appendRow(child); - } - } - - } catch(std::runtime_error &e) { - // An error occurred while reading the .esp - std::cerr << "Error reading .esp: " << e.what() << std::endl; - continue; - } - } +// if (!pluginList.isEmpty()) +// { +// foreach (const QStandardItem *currentPlugin, pluginList) { +// mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); +// // Move the plugin to the position specified in the config file +// mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row())); +// } +// } +// } } - bool DataFilesPage::setupDataFiles() { // We use the Configuration Manager to retrieve the configuration values @@ -356,717 +388,35 @@ bool DataFilesPage::setupDataFiles() } } - // Add the plugins in the data directories - Files::Collections dataCollections(mDataDirs, !variables["fs-strict"].as()); - Files::Collections dataLocalCollections(mDataLocal, !variables["fs-strict"].as()); + // Add the paths to the respective models + for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { + QString path = QString::fromStdString(it->string()); + path.remove(QChar('\"')); + mMastersModel->addMasters(path); + mPluginsModel->addPlugins(path); + } - addDataFiles(dataCollections, QString::fromStdString(variables["encoding"].as())); - addDataFiles(dataLocalCollections, QString::fromStdString(variables["encoding"].as())); + // Same for the data-local paths + for (Files::PathContainer::iterator it = mDataLocal.begin(); it != mDataLocal.end(); ++it) { + QString path = QString::fromStdString(it->string()); + path.remove(QChar('\"')); + mMastersModel->addMasters(path); + mPluginsModel->addPlugins(path); + } + +// mMastersModel->sort(0); +// mPluginsModel->sort(0); - mDataFilesModel->sort(0); readConfig(); return true; } -void DataFilesPage::createActions() -{ - // Refresh the plugins - QAction *refreshAction = new QAction(tr("Refresh"), this); - refreshAction->setShortcut(QKeySequence(tr("F5"))); - connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh())); - - // Profile actions - mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this); - mNewProfileAction->setToolTip(tr("New Profile")); - mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N"))); - connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile())); - - - mCopyProfileAction = new QAction(QIcon::fromTheme("edit-copy"), tr("&Copy Profile"), this); - mCopyProfileAction->setToolTip(tr("Copy Profile")); - mCopyProfileAction->setShortcut(QKeySequence(tr("Ctrl+C"))); - connect(mCopyProfileAction, SIGNAL(triggered()), this, SLOT(copyProfile())); - - mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this); - mDeleteProfileAction->setToolTip(tr("Delete Profile")); - mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete"))); - connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile())); - - // Add the newly created actions to the toolbar - mProfileToolBar->addSeparator(); - mProfileToolBar->addAction(mNewProfileAction); - mProfileToolBar->addAction(mCopyProfileAction); - mProfileToolBar->addAction(mDeleteProfileAction); - - // Context menu actions - mMoveUpAction = new QAction(QIcon::fromTheme("go-up"), tr("Move &Up"), this); - mMoveUpAction->setShortcut(QKeySequence(tr("Ctrl+U"))); - connect(mMoveUpAction, SIGNAL(triggered()), this, SLOT(moveUp())); - - mMoveDownAction = new QAction(QIcon::fromTheme("go-down"), tr("&Move Down"), this); - mMoveDownAction->setShortcut(QKeySequence(tr("Ctrl+M"))); - connect(mMoveDownAction, SIGNAL(triggered()), this, SLOT(moveDown())); - - mMoveTopAction = new QAction(QIcon::fromTheme("go-top"), tr("Move to Top"), this); - mMoveTopAction->setShortcut(QKeySequence(tr("Ctrl+Shift+U"))); - connect(mMoveTopAction, SIGNAL(triggered()), this, SLOT(moveTop())); - - mMoveBottomAction = new QAction(QIcon::fromTheme("go-bottom"), tr("Move to Bottom"), this); - mMoveBottomAction->setShortcut(QKeySequence(tr("Ctrl+Shift+M"))); - connect(mMoveBottomAction, SIGNAL(triggered()), this, SLOT(moveBottom())); - - mCheckAction = new QAction(tr("Check selected"), this); - connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check())); - - mUncheckAction = new QAction(tr("Uncheck selected"), this); - connect(mUncheckAction, SIGNAL(triggered()), this, SLOT(uncheck())); - - // Makes shortcuts work even if the context menu is hidden - this->addAction(refreshAction); - this->addAction(mMoveUpAction); - this->addAction(mMoveDownAction); - this->addAction(mMoveTopAction); - this->addAction(mMoveBottomAction); - - // Context menu for the plugins table - mContextMenu = new QMenu(this); - - mContextMenu->addAction(mMoveUpAction); - mContextMenu->addAction(mMoveDownAction); - mContextMenu->addSeparator(); - mContextMenu->addAction(mMoveTopAction); - mContextMenu->addAction(mMoveBottomAction); - mContextMenu->addSeparator(); - mContextMenu->addAction(mCheckAction); - mContextMenu->addAction(mUncheckAction); - -} - -void DataFilesPage::newProfile() -{ - bool ok; - QString text = QInputDialog::getText(this, tr("New Profile"), - tr("Profile Name:"), QLineEdit::Normal, - tr("New Profile"), &ok); - if (ok && !text.isEmpty()) { - if (mProfilesComboBox->findText(text) != -1) { - QMessageBox::warning(this, tr("Profile already exists"), - tr("the profile %0 already exists.").arg(text), - QMessageBox::Ok); - } else { - // Add the new profile to the combobox - mProfilesComboBox->addItem(text); - mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); - - } - - } - -} - -void DataFilesPage::copyProfile() -{ - QString profile = mProfilesComboBox->currentText(); - bool ok; - - QString text = QInputDialog::getText(this, tr("Copy Profile"), - tr("Profile Name:"), QLineEdit::Normal, - tr("%0 Copy").arg(profile), &ok); - if (ok && !text.isEmpty()) { - if (mProfilesComboBox->findText(text) != -1) { - QMessageBox::warning(this, tr("Profile already exists"), - tr("the profile %0 already exists.").arg(text), - QMessageBox::Ok); - } else { - // Add the new profile to the combobox - mProfilesComboBox->addItem(text); - - // First write the current profile as the new profile - writeConfig(text); - mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); - - } - - } - -} - -void DataFilesPage::deleteProfile() -{ - QString profile = mProfilesComboBox->currentText(); - - - if (profile.isEmpty()) { - return; - } - - QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Delete Profile")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); - - QAbstractButton *deleteButton = - msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() == deleteButton) { - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - - // Open the profile-name subgroup - mLauncherConfig->beginGroup(profile); - mLauncherConfig->remove(""); // Clear the subgroup - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); - - // Remove the profile from the combobox - mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile)); - } -} - -void DataFilesPage::moveUp() -{ - // Shift the selected plugins up one row - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - QModelIndex firstIndex = mPluginsProxyModel->mapToSource(selectedIndexes.first()); - - // Check if the first selected plugin is the top one - if (firstIndex.row() == 0) { - return; - } - - foreach (const QModelIndex ¤tIndex, selectedIndexes) { - const QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(currentIndex); - int currentRow = sourceModelIndex.row(); - - if (sourceModelIndex.isValid() && currentRow > 0) { - mPluginsModel->insertRow((currentRow - 1), mPluginsModel->takeRow(currentRow)); - - const QModelIndex targetIndex = mPluginsModel->index((currentRow - 1), 0, QModelIndex()); - - mPluginsTable->selectionModel()->select(targetIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows); - scrollToSelection(); - } - } -} - -void DataFilesPage::moveDown() -{ - // Shift the selected plugins down one row - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection descending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowGreaterThan); - - const QModelIndex lastIndex = mPluginsProxyModel->mapToSource(selectedIndexes.first()); - - // Check if last selected plugin is bottom one - if ((lastIndex.row() + 1) == mPluginsModel->rowCount()) { - return; - } - - foreach (const QModelIndex ¤tIndex, selectedIndexes) { - const QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(currentIndex); - int currentRow = sourceModelIndex.row(); - - if (sourceModelIndex.isValid() && (currentRow + 1) < mPluginsModel->rowCount()) { - mPluginsModel->insertRow((currentRow + 1), mPluginsModel->takeRow(currentRow)); - - const QModelIndex targetIndex = mPluginsModel->index((currentRow + 1), 0, QModelIndex()); - - mPluginsTable->selectionModel()->select(targetIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows); - scrollToSelection(); - } - } -} - -void DataFilesPage::moveTop() -{ - // Move the selection to the top of the table - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - QModelIndex firstIndex = mPluginsProxyModel->mapToSource(selectedIndexes.first()); - - // Check if the first selected plugin is the top one - if (firstIndex.row() == 0) { - return; - } - - for (int i=0; i < selectedIndexes.count(); ++i) { - - const QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(selectedIndexes.at(i)); - - int currentRow = sourceModelIndex.row(); - - if (sourceModelIndex.isValid() && currentRow > 0) { - - mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentRow)); - mPluginsTable->selectionModel()->select(mPluginsModel->index(i, 0, QModelIndex()), QItemSelectionModel::Select | QItemSelectionModel::Rows); - mPluginsTable->scrollToTop(); - } - } -} - -void DataFilesPage::moveBottom() -{ - // Move the selection to the bottom of the table - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection descending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - const QModelIndex lastIndex = mPluginsProxyModel->mapToSource(selectedIndexes.last()); - - // Check if last selected plugin is bottom one - if ((lastIndex.row() + 1) == mPluginsModel->rowCount()) { - return; - } - - for (int i=0; i < selectedIndexes.count(); ++i) { - - const QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(selectedIndexes.at(i)); - - // Subtract iterations because takeRow shifts the rows below the taken row up - int currentRow = sourceModelIndex.row() - i; - - if (sourceModelIndex.isValid() && (currentRow + 1) < mPluginsModel->rowCount()) { - mPluginsModel->appendRow(mPluginsModel->takeRow(currentRow)); - - // Rowcount starts with 1, row numbers start with 0 - const QModelIndex lastRow = mPluginsModel->index((mPluginsModel->rowCount() -1), 0, QModelIndex()); - - mPluginsTable->selectionModel()->select(lastRow, QItemSelectionModel::Select | QItemSelectionModel::Rows); - mPluginsTable->scrollToBottom(); - } - } -} - -void DataFilesPage::check() -{ - // Check the current selection - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - foreach (const QModelIndex ¤tIndex, selectedIndexes) { - QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(currentIndex); - - if (sourceModelIndex.isValid()) { - mPluginsModel->setData(sourceModelIndex, Qt::Checked, Qt::CheckStateRole); - } - } -} - -void DataFilesPage::uncheck() -{ - // Uncheck the current selection - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - foreach (const QModelIndex ¤tIndex, selectedIndexes) { - QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(currentIndex); - - if (sourceModelIndex.isValid()) { - mPluginsModel->setData(sourceModelIndex, Qt::Unchecked, Qt::CheckStateRole); - } - } -} - -void DataFilesPage::refresh() -{ - // Refresh the plugins table - - writeConfig(); - readConfig(); -} - -void DataFilesPage::scrollToSelection() -{ - // Scroll to the selected plugins - - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - // Get the selected indexes visible by determining the middle index - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - qSort(selectedIndexes.begin(), selectedIndexes.end(), rowSmallerThan); - - // The selected rows including non-selected inside selection - unsigned int selectedRows = selectedIndexes.last().row() - selectedIndexes.first().row(); - - // Determine the row which is roughly in the middle of the selection - unsigned int middleRow = selectedIndexes.first().row() + (int)(selectedRows / 2) + 1; - - - const QModelIndex middleIndex = mPluginsProxyModel->mapFromSource(mPluginsModel->index(middleRow, 0, QModelIndex())); - - // Make sure the whole selection is visible - mPluginsTable->scrollTo(selectedIndexes.first()); - mPluginsTable->scrollTo(selectedIndexes.last()); - mPluginsTable->scrollTo(middleIndex); -} - -void DataFilesPage::showContextMenu(const QPoint &point) -{ - // Make sure there are plugins in the view - if (!mPluginsTable->selectionModel()->hasSelection()) { - return; - } - - QPoint globalPos = mPluginsTable->mapToGlobal(point); - - QModelIndexList selectedIndexes = mPluginsTable->selectionModel()->selectedIndexes(); - - // Show the check/uncheck actions depending on the state of the selected items - mUncheckAction->setEnabled(false); - mCheckAction->setEnabled(false); - - foreach (const QModelIndex ¤tIndex, selectedIndexes) { - if (currentIndex.isValid()) { - - const QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(currentIndex); - - if (!sourceIndex.isValid()) { - return; - } - - const QStandardItem *currentItem = mPluginsModel->itemFromIndex(sourceIndex); - - if (currentItem->checkState() == Qt::Checked) { - mUncheckAction->setEnabled(true); - } else { - mCheckAction->setEnabled(true); - } - } - - } - - // Make sure these are enabled because they might still be disabled - mMoveUpAction->setEnabled(true); - mMoveTopAction->setEnabled(true); - mMoveDownAction->setEnabled(true); - mMoveBottomAction->setEnabled(true); - - QModelIndex firstIndex = mPluginsProxyModel->mapToSource(selectedIndexes.first()); - QModelIndex lastIndex = mPluginsProxyModel->mapToSource(selectedIndexes.last()); - - // Check if selected first item is top row in model - if (firstIndex.row() == 0) { - mMoveUpAction->setEnabled(false); - mMoveTopAction->setEnabled(false); - } - - // Check if last row is bottom row in model - if ((lastIndex.row() + 1) == mPluginsModel->rowCount()) { - mMoveDownAction->setEnabled(false); - mMoveBottomAction->setEnabled(false); - } - - // Show menu - mContextMenu->exec(globalPos); -} - -void DataFilesPage::masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) -{ - if (mMastersWidget->selectionModel()->hasSelection()) { - - QStringList masters; - QString masterstr; - - // Create a QStringList containing all the masters - const QStringList masterList = selectedMasters(); - - foreach (const QString ¤tMaster, masterList) { - masters.append(currentMaster); - } - - masters.sort(); - masterstr = masters.join(","); // Make a comma-separated QString - - // Iterate over all masters in the datafilesmodel to see if they are selected - for (int r=0; rrowCount(); ++r) { - QModelIndex currentIndex = mDataFilesModel->index(r, 0); - QString master = currentIndex.data().toString(); - - if (currentIndex.isValid()) { - // See if the current master is in the string with selected masters - if (masterstr.contains(master)) - { - // Append the plugins from the current master to pluginsmodel - addPlugins(currentIndex); - } - } - } - } - - // See what plugins to remove - QModelIndexList deselectedIndexes = deselected.indexes(); - - if (!deselectedIndexes.isEmpty()) { - foreach (const QModelIndex ¤tIndex, deselectedIndexes) { - - QString master = currentIndex.data().toString(); - master.prepend("*"); - master.append("*"); - const QList itemList = mDataFilesModel->findItems(master, Qt::MatchWildcard); - - foreach (const QStandardItem *currentItem, itemList) { - QModelIndex index = currentItem->index(); - removePlugins(index); - } - } - } - -} - -void DataFilesPage::addPlugins(const QModelIndex &index) -{ - // Find the plugins in the datafilesmodel and append them to the pluginsmodel - if (!index.isValid()) - return; - - for (int r=0; rrowCount(index); ++r ) { - QModelIndex childIndex = index.child(r, 0); - - if (childIndex.isValid()) { - // Now we see if the pluginsmodel already contains this plugin - const QString childIndexData = QVariant(mDataFilesModel->data(childIndex)).toString(); - const QString childIndexToolTip = QVariant(mDataFilesModel->data(childIndex, Qt::ToolTipRole)).toString(); - - const QList itemList = mPluginsModel->findItems(childIndexData); - - if (itemList.isEmpty()) - { - // Plugin not yet in the pluginsmodel, add it - QStandardItem *item = new QStandardItem(childIndexData); - item->setFlags(item->flags() & ~(Qt::ItemIsDropEnabled)); - item->setCheckable(true); - item->setToolTip(childIndexToolTip); - - mPluginsModel->appendRow(item); - } - } - - } - -} - -void DataFilesPage::removePlugins(const QModelIndex &index) -{ - - if (!index.isValid()) - return; - - for (int r=0; rrowCount(index); ++r) { - QModelIndex childIndex = index.child(r, 0); - - const QList itemList = mPluginsModel->findItems(QVariant(childIndex.data()).toString()); - - if (!itemList.isEmpty()) { - foreach (const QStandardItem *currentItem, itemList) { - mPluginsModel->removeRow(currentItem->row()); - } - } - } - -} - -void DataFilesPage::setCheckState(QModelIndex index) -{ - if (!index.isValid()) - return; - - QModelIndex sourceModelIndex = mPluginsProxyModel->mapToSource(index); - - if (mPluginsModel->data(sourceModelIndex, Qt::CheckStateRole) == Qt::Checked) { - // Selected row is checked, uncheck it - mPluginsModel->setData(sourceModelIndex, Qt::Unchecked, Qt::CheckStateRole); - } else { - mPluginsModel->setData(sourceModelIndex, Qt::Checked, Qt::CheckStateRole); - } -} - -const QStringList DataFilesPage::selectedMasters() -{ - QStringList masters; - const QList selectedMasters = mMastersWidget->selectedItems(); - - foreach (const QTableWidgetItem *item, selectedMasters) { - masters.append(item->data(Qt::DisplayRole).toString()); - } - - return masters; -} - -const QStringList DataFilesPage::checkedPlugins() -{ - QStringList checkedItems; - - for (int r=0; rrowCount(); ++r ) { - QModelIndex index = mPluginsModel->index(r, 0); - - if (index.isValid()) { - // See if the current item is checked - if (mPluginsModel->data(index, Qt::CheckStateRole) == Qt::Checked) { - checkedItems.append(index.data().toString()); - } - } - } - return checkedItems; -} - -void DataFilesPage::uncheckPlugins() -{ - for (int r=0; rrowCount(); ++r ) { - QModelIndex index = mPluginsModel->index(r, 0); - - if (index.isValid()) { - // See if the current item is checked - if (mPluginsModel->data(index, Qt::CheckStateRole) == Qt::Checked) { - mPluginsModel->setData(index, Qt::Unchecked, Qt::CheckStateRole); - } - } - } -} - -void DataFilesPage::filterChanged(const QString filter) -{ - QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); - mPluginsProxyModel->setFilterRegExp(regExp); -} - -void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) -{ - // Prevent the deletion of the default profile - if (current == "Default") { - mDeleteProfileAction->setEnabled(false); - } else { - mDeleteProfileAction->setEnabled(true); - } - - if (!previous.isEmpty()) { - writeConfig(previous); - mLauncherConfig->sync(); - } else { - return; - } - - uncheckPlugins(); - // Deselect the masters - mMastersWidget->selectionModel()->clearSelection(); - readConfig(); -} - -void DataFilesPage::readConfig() -{ - QString profile = mProfilesComboBox->currentText(); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - mLauncherConfig->beginGroup(profile); - - QStringList childKeys = mLauncherConfig->childKeys(); - QStringList plugins; - - // Sort the child keys numerical instead of alphabetically - // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 - qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); - - foreach (const QString &key, childKeys) { - const QString keyValue = mLauncherConfig->value(key).toString(); - - if (key.startsWith("Plugin")) { - plugins.append(keyValue); - continue; - } - - if (key.startsWith("Master")) { - const QList masterList = mMastersWidget->findItems(keyValue, Qt::MatchFixedString); - - if (!masterList.isEmpty()) { - foreach (QTableWidgetItem *currentMaster, masterList) { - mMastersWidget->selectionModel()->select(mMastersWidget->model()->index(currentMaster->row(), 0), QItemSelectionModel::Select); - } - } - } - } - - // Iterate over the plugins to set their checkstate and position - for (int i = 0; i < plugins.size(); ++i) { - const QString plugin = plugins.at(i); - - const QList pluginList = mPluginsModel->findItems(plugin); - - if (!pluginList.isEmpty()) - { - foreach (const QStandardItem *currentPlugin, pluginList) { - mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); - - // Move the plugin to the position specified in the config file - mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row())); - } - } - } - -} - void DataFilesPage::writeConfig(QString profile) { // Don't overwrite the config if no masters are found - if (mMastersWidget->rowCount() < 1) { + if (mMastersModel->rowCount() < 1) return; - } QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string()); QDir userPath(pathStr); @@ -1150,13 +500,11 @@ void DataFilesPage::writeConfig(QString profile) path = QString::fromStdString(it->string()); path.remove(QChar('\"')); - QDir dir(path); - // Make sure the string is quoted when it contains spaces if (path.contains(" ")) { - gameConfig << "data=\"" << dir.absolutePath() << "\"" << endl; + gameConfig << "data=\"" << path << "\"" << endl; } else { - gameConfig << "data=" << dir.absolutePath() << endl; + gameConfig << "data=" << path << endl; } } @@ -1165,23 +513,19 @@ void DataFilesPage::writeConfig(QString profile) path = QString::fromStdString(mDataLocal.front().string()); path.remove(QChar('\"')); - QDir dir(path); - if (path.contains(" ")) { - gameConfig << "data-local=\"" << dir.absolutePath() << "\"" << endl; + gameConfig << "data-local=\"" << path << "\"" << endl; } else { - gameConfig << "data-local=" << dir.absolutePath() << endl; + gameConfig << "data-local=" << path << endl; } } - if (profile.isEmpty()) { + if (profile.isEmpty()) profile = mProfilesComboBox->currentText(); - } - if (profile.isEmpty()) { + if (profile.isEmpty()) return; - } // Make sure we have no groups open while (!mLauncherConfig->group().isEmpty()) { @@ -1196,7 +540,7 @@ void DataFilesPage::writeConfig(QString profile) mLauncherConfig->remove(""); // Clear the subgroup // Now write the masters to the configs - const QStringList masters = selectedMasters(); + const QStringList masters = mMastersModel->checkedItems(); // We don't use foreach because we need i for (int i = 0; i < masters.size(); ++i) { @@ -1208,7 +552,7 @@ void DataFilesPage::writeConfig(QString profile) } // And finally write all checked plugins - const QStringList plugins = checkedPlugins(); + const QStringList plugins = mPluginsModel->checkedItems(); for (int i = 0; i < plugins.size(); ++i) { const QString currentPlugin = plugins.at(i); @@ -1221,3 +565,201 @@ void DataFilesPage::writeConfig(QString profile) mLauncherConfig->endGroup(); mLauncherConfig->sync(); } + + +void DataFilesPage::newProfile() +{ + bool ok; + QString text = QInputDialog::getText(this, tr("New Profile"), + tr("Profile Name:"), QLineEdit::Normal, + tr("New Profile"), &ok); + if (ok && !text.isEmpty()) { + if (mProfilesComboBox->findText(text) != -1) { + QMessageBox::warning(this, tr("Profile already exists"), + tr("the profile %0 already exists.").arg(text), + QMessageBox::Ok); + } else { + // Add the new profile to the combobox + mProfilesComboBox->addItem(text); + mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); + + } + + } +} + +void DataFilesPage::deleteProfile() +{ + QString profile = mProfilesComboBox->currentText(); + + + if (profile.isEmpty()) { + return; + } + + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Delete Profile")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); + + QAbstractButton *deleteButton = + msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); + + msgBox.exec(); + + if (msgBox.clickedButton() == deleteButton) { + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + + // Open the profile-name subgroup + mLauncherConfig->beginGroup(profile); + mLauncherConfig->remove(""); // Clear the subgroup + mLauncherConfig->endGroup(); + mLauncherConfig->endGroup(); + + // Remove the profile from the combobox + mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile)); + } +} + +void DataFilesPage::check() +{ + // Check the current selection + if (!mPluginsTable->selectionModel()->hasSelection()) { + return; + } + + QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes(); + + //sort selection ascending because selectedIndexes returns an unsorted list + //qSort(indexes.begin(), indexes.end(), rowSmallerThan); + + foreach (const QModelIndex &index, indexes) { + if (!index.isValid()) + return; + + mPluginsModel->setCheckState(index, Qt::Checked); + } +} + +void DataFilesPage::uncheck() +{ + // uncheck the current selection + if (!mPluginsTable->selectionModel()->hasSelection()) { + return; + } + + QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes(); + + //sort selection ascending because selectedIndexes returns an unsorted list + //qSort(indexes.begin(), indexes.end(), rowSmallerThan); + + foreach (const QModelIndex &index, indexes) { + if (!index.isValid()) + return; + + mPluginsModel->setCheckState(index, Qt::Unchecked); + } +} + +void DataFilesPage::refresh() +{ + mPluginsModel->sort(0); + + + // Refresh the plugins table + mPluginsTable->scrollToTop(); + writeConfig(); + readConfig(); +} + + +void DataFilesPage::setCheckState(QModelIndex index) +{ + if (!index.isValid()) + return; + + QObject *object = QObject::sender(); + + // Not a signal-slot call + if (!object) + return; + + if (object->objectName() == QLatin1String("PluginsTable")) { + if (mPluginsModel->checkState(index) == Qt::Checked) { + mPluginsModel->setCheckState(index, Qt::Unchecked); + } else { + mPluginsModel->setCheckState(index, Qt::Checked); + } + } + + if (object->objectName() == QLatin1String("MastersTable")) { + if (mMastersModel->checkState(index) == Qt::Checked) { + mMastersModel->setCheckState(index, Qt::Unchecked); + } else { + mMastersModel->setCheckState(index, Qt::Checked); + } + } + + return; + +} + +void DataFilesPage::filterChanged(const QString filter) +{ + QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); + mPluginsProxyModel->setFilterRegExp(regExp); +} + +void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) +{ + // Prevent the deletion of the default profile + (current == QLatin1String("Default")) ? mDeleteProfileAction->setEnabled(false) + : mDeleteProfileAction->setEnabled(true); + + if (!previous.isEmpty()) { + writeConfig(previous); + mLauncherConfig->sync(); + } else { + return; + } + + mMastersModel->uncheckAll(); + mPluginsModel->uncheckAll(); + readConfig(); +} + +void DataFilesPage::showContextMenu(const QPoint &point) +{ + // Make sure there are plugins in the view + if (!mPluginsTable->selectionModel()->hasSelection()) { + return; + } + + QPoint globalPos = mPluginsTable->mapToGlobal(point); + + QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes(); + + // Show the check/uncheck actions depending on the state of the selected items + mUncheckAction->setEnabled(false); + mCheckAction->setEnabled(false); + + foreach (const QModelIndex &index, indexes) { + if (!index.isValid()) + return; + + if (mPluginsModel->checkState(index) == Qt::Checked) { + mUncheckAction->setEnabled(true); + } else { + mCheckAction->setEnabled(true); + } + } + + // Show menu + mContextMenu->exec(globalPos); +} diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 83b318677..648991254 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -8,19 +8,15 @@ #include "combobox.hpp" -class QTableWidget; -class QStandardItemModel; -class QItemSelection; -class QItemSelectionModel; +class QTableView; class QSortFilterProxyModel; -class QStringListModel; class QSettings; class QAction; class QToolBar; class QMenu; -class PluginsModel; -class PluginsView; class ComboBox; +class DataFilesModel; + namespace Files { struct ConfigurationManager; } @@ -37,7 +33,6 @@ public: bool setupDataFiles(); public slots: - void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void setCheckState(QModelIndex index); void filterChanged(const QString filter); @@ -46,37 +41,34 @@ public slots: // Action slots void newProfile(); - void copyProfile(); void deleteProfile(); - void moveUp(); - void moveDown(); - void moveTop(); - void moveBottom(); +// void moveUp(); +// void moveDown(); +// void moveTop(); +// void moveBottom(); void check(); void uncheck(); void refresh(); private: - QTableWidget *mMastersWidget; - PluginsView *mPluginsTable; - - QStandardItemModel *mDataFilesModel; - PluginsModel *mPluginsModel; + DataFilesModel *mMastersModel; + DataFilesModel *mPluginsModel; QSortFilterProxyModel *mPluginsProxyModel; - QItemSelectionModel *mPluginsSelectModel; + + QTableView *mMastersTable; + QTableView *mPluginsTable; QToolBar *mProfileToolBar; QMenu *mContextMenu; QAction *mNewProfileAction; - QAction *mCopyProfileAction; QAction *mDeleteProfileAction; - QAction *mMoveUpAction; - QAction *mMoveDownAction; - QAction *mMoveTopAction; - QAction *mMoveBottomAction; +// QAction *mMoveUpAction; +// QAction *mMoveDownAction; +// QAction *mMoveTopAction; +// QAction *mMoveBottomAction; QAction *mCheckAction; QAction *mUncheckAction; @@ -86,17 +78,12 @@ private: QSettings *mLauncherConfig; - const QStringList checkedPlugins(); - const QStringList selectedMasters(); +// const QStringList checkedPlugins(); +// const QStringList selectedMasters(); - void addDataFiles(Files::Collections &fileCollections, const QString &encoding); - void addPlugins(const QModelIndex &index); - void removePlugins(const QModelIndex &index); - void uncheckPlugins(); void createActions(); void setupConfig(); void readConfig(); - void scrollToSelection(); }; diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index be89902c8..f009c3df0 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include "esm/esmfile.hpp" From 68a856ff6fe8f86a7de123e69eaf4061e1764828 Mon Sep 17 00:00:00 2001 From: cfcohen Date: Wed, 10 Oct 2012 22:00:44 -0400 Subject: [PATCH 031/255] Human readable labels for many records types. Human readable flags for many record types. Improved DialInfo rule parsing. Discovered several issues involving the assignment of various flag bits. --- apps/esmtool/CMakeLists.txt | 2 + apps/esmtool/labels.cpp | 884 ++++++++++++++++++++++++++++++++++++ apps/esmtool/labels.hpp | 64 +++ apps/esmtool/record.cpp | 313 +++++++++---- 4 files changed, 1162 insertions(+), 101 deletions(-) create mode 100644 apps/esmtool/labels.cpp create mode 100644 apps/esmtool/labels.hpp diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index f48aa41bf..5c588fb29 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -1,5 +1,7 @@ set(ESMTOOL esmtool.cpp + labels.hpp + labels.cpp record.hpp record.cpp ) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp new file mode 100644 index 000000000..1ebed1d55 --- /dev/null +++ b/apps/esmtool/labels.cpp @@ -0,0 +1,884 @@ +#include "labels.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +std::string bodyPartLabel(char idx) +{ + const char *bodyPartLabels[] = { + "Head", + "Hair", + "Neck", + "Cuirass", + "Groin", + "Skirt", + "Right Hand", + "Left Hand", + "Right Wrist", + "Left Wrist", + "Shield", + "Right Forearm", + "Left Forearm", + "Right Upperarm", + "Left Upperarm", + "Right Foot", + "Left Foot", + "Right Ankle", + "Left Ankle", + "Right Knee", + "Left Knee", + "Right Leg", + "Left Leg", + "Right Shoulder", + "Left Shoulder", + "Weapon", + "Tail" + }; + + // BUG? idx should probably be unsigned char instead + if ((int)idx >= 0 && (int)(idx) <= 26) + return bodyPartLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string meshPartLabel(char idx) +{ + const char *meshPartLabels[] = { + "Head", + "Hair", + "Neck", + "Chest", + "Groin", + "Hand", + "Wrist", + "Forearm", + "Upperarm", + "Foot", + "Ankle", + "Knee", + "Upper Leg", + "Clavicle", + "Tail" + }; + + if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MP_Tail) + return meshPartLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string meshTypeLabel(char idx) +{ + const char *meshTypeLabels[] = { + "Skin", + "Clothing", + "Armor" + }; + + if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MT_Armor) + return meshTypeLabels[(int)(idx)]; + else + return "Invalid"; +} + +std::string clothingTypeLabel(int idx) +{ + const char *clothingTypeLabels[] = { + "Pants", + "Shoes", + "Shirt", + "Belt", + "Robe", + "Right Glove", + "Left Glove", + "Skirt", + "Ring", + "Amulet" + }; + + if (idx >= 0 && idx <= 9) + return clothingTypeLabels[idx]; + else + return "Invalid"; +} + +std::string armorTypeLabel(int idx) +{ + const char *armorTypeLabels[] = { + "Helmet", + "Cuirass", + "Left Pauldron", + "Right Pauldron", + "Greaves", + "Boots", + "Left Gauntlet", + "Right Gauntlet", + "Shield", + "Left Bracer", + "Right Bracer" + }; + + if (idx >= 0 && idx <= 10) + return armorTypeLabels[idx]; + else + return "Invalid"; +} + +std::string dialogTypeLabel(int idx) +{ + const char *dialogTypeLabels[] = { + "Topic", + "Voice", + "Greeting", + "Persuasion", + "Journal" + }; + + if (idx >= 0 && idx <= 4) + return dialogTypeLabels[idx]; + else if (idx == -1) + return "Deleted"; + else + return "Invalid"; +} + +std::string questStatusLabel(int idx) +{ + const char *questStatusLabels[] = { + "None", + "Name", + "Finished", + "Restart", + "Deleted" + }; + + if (idx >= 0 && idx <= 4) + return questStatusLabels[idx]; + else + return "Invalid"; +} + +std::string creatureTypeLabel(int idx) +{ + const char *creatureTypeLabels[] = { + "Creature", + "Daedra", + "Undead", + "Humanoid", + }; + + if (idx >= 0 && idx <= 3) + return creatureTypeLabels[idx]; + else + return "Invalid"; +} + +std::string soundTypeLabel(int idx) +{ + const char *soundTypeLabels[] = { + "Left Foot", + "Right Foot", + "Swim Left", + "Swim Right", + "Moan", + "Roar", + "Scream", + "Land" + }; + + if (idx >= 0 && idx <= 7) + return soundTypeLabels[idx]; + else + return "Invalid"; +} + +std::string weaponTypeLabel(int idx) +{ + const char *weaponTypeLabels[] = { + "Short Blade One Hand", + "Long Blade One Hand", + "Long Blade Two Hand", + "Blunt One Hand", + "Blunt Two Close", + "Blunt Two Wide", + "Spear Two Wide", + "Axe One Hand", + "Axe Two Hand", + "Marksman Bow", + "Marksman Crossbow", + "Marksman Thrown", + "Arrow", + "Bolt" + }; + + if (idx >= 0 && idx <= 13) + return weaponTypeLabels[idx]; + else + return "Invalid"; +} + +std::string aiTypeLabel(int type) +{ + if (type == ESM::AI_Wander) return "Wander"; + else if (type == ESM::AI_Travel) return "Travel"; + else if (type == ESM::AI_Follow) return "Follow"; + else if (type == ESM::AI_Escort) return "Escort"; + else if (type == ESM::AI_Activate) return "Activate"; + else return "Invalid"; +} + +std::string magicEffectLabel(int idx) +{ + const char* magicEffectLabels [] = { + "Water Breathing", + "Swift Swim", + "Water Walking", + "Shield", + "Fire Shield", + "Lightning Shield", + "Frost Shield", + "Burden", + "Feather", + "Jump", + "Levitate", + "SlowFall", + "Lock", + "Open", + "Fire Damage", + "Shock Damage", + "Frost Damage", + "Drain Attribute", + "Drain Health", + "Drain Magicka", + "Drain Fatigue", + "Drain Skill", + "Damage Attribute", + "Damage Health", + "Damage Magicka", + "Damage Fatigue", + "Damage Skill", + "Poison", + "Weakness to Fire", + "Weakness to Frost", + "Weakness to Shock", + "Weakness to Magicka", + "Weakness to Common Disease", + "Weakness to Blight Disease", + "Weakness to Corprus Disease", + "Weakness to Poison", + "Weakness to Normal Weapons", + "Disintegrate Weapon", + "Disintegrate Armor", + "Invisibility", + "Chameleon", + "Light", + "Sanctuary", + "Night Eye", + "Charm", + "Paralyze", + "Silence", + "Blind", + "Sound", + "Calm Humanoid", + "Calm Creature", + "Frenzy Humanoid", + "Frenzy Creature", + "Demoralize Humanoid", + "Demoralize Creature", + "Rally Humanoid", + "Rally Creature", + "Dispel", + "Soultrap", + "Telekinesis", + "Mark", + "Recall", + "Divine Intervention", + "Almsivi Intervention", + "Detect Animal", + "Detect Enchantment", + "Detect Key", + "Spell Absorption", + "Reflect", + "Cure Common Disease", + "Cure Blight Disease", + "Cure Corprus Disease", + "Cure Poison", + "Cure Paralyzation", + "Restore Attribute", + "Restore Health", + "Restore Magicka", + "Restore Fatigue", + "Restore Skill", + "Fortify Attribute", + "Fortify Health", + "Fortify Magicka", + "Fortify Fatigue", + "Fortify Skill", + "Fortify Maximum Magicka", + "Absorb Attribute", + "Absorb Health", + "Absorb Magicka", + "Absorb Fatigue", + "Absorb Skill", + "Resist Fire", + "Resist Frost", + "Resist Shock", + "Resist Magicka", + "Resist Common Disease", + "Resist Blight Disease", + "Resist Corprus Disease", + "Resist Poison", + "Resist Normal Weapons", + "Resist Paralysis", + "Remove Curse", + "Turn Undead", + "Summon Scamp", + "Summon Clannfear", + "Summon Daedroth", + "Summon Dremora", + "Summon Ancestral Ghost", + "Summon Skeletal Minion", + "Summon Bonewalker", + "Summon Greater Bonewalker", + "Summon Bonelord", + "Summon Winged Twilight", + "Summon Hunger", + "Summon Golden Saint", + "Summon Flame Atronach", + "Summon Frost Atronach", + "Summon Storm Atronach", + "Fortify Attack", + "Command Creature", + "Command Humanoid", + "Bound Dagger", + "Bound Longsword", + "Bound Mace", + "Bound Battle Axe", + "Bound Spear", + "Bound Longbow", + "EXTRA SPELL", + "Bound Cuirass", + "Bound Helm", + "Bound Boots", + "Bound Shield", + "Bound Gloves", + "Corprus", + "Vampirism", + "Summon Centurion Sphere", + "Sun Damage", + "Stunted Magicka", + "Summon Fabricant", + "sEffectSummonCreature01", + "sEffectSummonCreature02", + "sEffectSummonCreature03", + "sEffectSummonCreature04", + "sEffectSummonCreature05" + }; + if (idx >= 0 && idx <= 143) + return magicEffectLabels[idx]; + else + return "Invalid"; +} + +std::string attributeLabel(int idx) +{ + const char* attributeLabels [] = { + "Strength", + "Intelligence", + "Willpower", + "Agility", + "Speed", + "Endurance", + "Personality", + "Luck" + }; + if (idx >= 0 && idx <= 7) + return attributeLabels[idx]; + else + return "Invalid"; +} + +std::string spellTypeLabel(int idx) +{ + const char* spellTypeLabels [] = { + "Spells", + "Abilities", + "Blight Disease", + "Disease", + "Curse", + "Powers" + }; + if (idx >= 0 && idx <= 5) + return spellTypeLabels[idx]; + else + return "Invalid"; +} + +std::string specializationLabel(int idx) +{ + const char* specializationLabels [] = { + "Combat", + "Magic", + "Stealth" + }; + if (idx >= 0 && idx <= 2) + return specializationLabels[idx]; + else + return "Invalid"; +} + +std::string skillLabel(int idx) +{ + const char* skillLabels [] = { + "Block", + "Armorer", + "Medium Armor", + "Heavy Armor", + "Blunt Weapon", + "Long Blade", + "Axe", + "Spear", + "Athletics", + "Enchant", + "Destruction", + "Alteration", + "Illusion", + "Conjuration", + "Mysticism", + "Restoration", + "Alchemy", + "Unarmored", + "Security", + "Sneak", + "Acrobatics", + "Light Armor", + "Short Blade", + "Marksman", + "Mercantile", + "Speechcraft", + "Hand-to-hand" + }; + if (idx >= 0 && idx <= 27) + return skillLabels[idx]; + else + return "Invalid"; +} + +std::string apparatusTypeLabel(int idx) +{ + const char* apparatusTypeLabels [] = { + "Mortar", + "Alembic", + "Calcinator", + "Retort", + }; + if (idx >= 0 && idx <= 3) + return apparatusTypeLabels[idx]; + else + return "Invalid"; +} + +std::string rangeTypeLabel(int idx) +{ + const char* rangeTypeLabels [] = { + "Self", + "Touch", + "Target" + }; + if (idx >= 0 && idx <= 3) + return rangeTypeLabels[idx]; + else + return "Invalid"; +} + +std::string schoolLabel(int idx) +{ + const char* schoolLabels [] = { + "Alteration", + "Conjuration", + "Destruction", + "Illusion", + "Mysticism", + "Restoration" + }; + if (idx >= 0 && idx <= 5) + return schoolLabels[idx]; + else + return "Invalid"; +} + +std::string enchantTypeLabel(int idx) +{ + const char* enchantTypeLabels [] = { + "Cast Once", + "Cast When Strikes", + "Cast When Used", + "Constant Effect" + }; + if (idx >= 0 && idx <= 3) + return enchantTypeLabels[idx]; + else + return "Invalid"; +} + +std::string ruleFunction(int idx) +{ + std::string ruleFunctions[] = { + "Reaction Low", + "Reaction High", + "Rank Requirement", + "NPC? Reputation", + "Health Percent", + "Player Reputation", + "NPC Level", + "Player Health Percent", + "Player Magicka", + "Player Fatigue", + "Player Attribute Strength", + "Player Skill Block", + "Player Skill Armorer", + "Player Skill Medium Armor", + "Player Skill Heavy Armor", + "Player Skill Blunt Weapon", + "Player Skill Long Blade", + "Player Skill Axe", + "Player Skill Spear", + "Player Skill Athletics", + "Player Skill Enchant", + "Player Skill Destruction", + "Player Skill Alteration", + "Player Skill Illusion", + "Player Skill Conjuration", + "Player Skill Mysticism", + "Player SKill Restoration", + "Player Skill Alchemy", + "Player Skill Unarmored", + "Player Skill Security", + "Player Skill Sneak", + "Player Skill Acrobatics", + "Player Skill Light Armor", + "Player Skill Short Blade", + "Player Skill Marksman", + "Player Skill Mercantile", + "Player Skill Speechcraft", + "Player Skill Hand to Hand", +// Unknown1=0->Male, Unknown1=1->Female + "Player Gender", + "Player Expelled from Faction", + "Player Diseased (Common)", + "Player Diseased (Blight)", + "Player Clothing Modifier", + "Player Crime Level", + "Player Same Sex", + "Player Same Race", + "Player Same Faction", + "Faction Rank Difference", + "Player Detected", + "Alarmed", + "Choice Selected", + "Player Attribute Intelligence", + "Player Attribute Willpower", + "Player Attribute Agility", + "Player Attribute Speed", + "Player Attribute Endurance", + "Player Attribute Personality", + "Player Attribute Luck", + "Player Diseased (Corprus)", + "Weather", + "Player is a Vampire", + "Player Level", + "Attacked", + "NPC Talked to Player", + "Player Health", + "Creature Target", + "Friend Hit", + "Fight", + "Hello", + "Alarm", + "Flee", + "Should Attack", + //Unkown but causes NPCs to growl and roar. + "UNKNOWN 72" + }; + if (idx >= 0 && idx <= 72) + return ruleFunctions[idx]; + else + return "Invalid"; +} + +// The "unused flag bits" should probably be defined alongside the +// defined bits in the ESM component. The names of the flag bits are +// very inconsistent. + +std::string bodyPartFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; + if (flags & ESM::BodyPart::BPF_Playable) properties += "Playable "; + int unused = (0xFFFFFFFF ^ + (ESM::BodyPart::BPF_Female| + ESM::BodyPart::BPF_Playable)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string cellFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Cell::HasWater) properties += "HasWater "; + if (flags & ESM::Cell::Interior) properties += "Interior "; + if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; + if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx "; + // CHANGE? This used value is not in the ESM component. + if (flags & 0x00000040) properties += "Unknown "; + int unused = (0xFFFFFFFF ^ + (ESM::Cell::HasWater| + ESM::Cell::Interior| + ESM::Cell::NoSleep| + ESM::Cell::QuasiEx| + 0x00000040)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string containerFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Container::Unknown) properties += "Unknown "; + if (flags & ESM::Container::Organic) properties += "Organic "; + if (flags & ESM::Container::Respawn) properties += "Respawn "; + int unused = (0xFFFFFFFF ^ + (ESM::Container::Unknown| + ESM::Container::Organic| + ESM::Container::Respawn)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string creatureFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Creature::None) properties += "All "; + if (flags & ESM::Creature::Walks) properties += "Walks "; + if (flags & ESM::Creature::Swims) properties += "Swims "; + if (flags & ESM::Creature::Flies) properties += "Flies "; + if (flags & ESM::Creature::Biped) properties += "Biped "; + if (flags & ESM::Creature::Respawn) properties += "Respawn "; + if (flags & ESM::Creature::Weapon) properties += "Weapon "; + if (flags & ESM::Creature::Skeleton) properties += "Skeleton "; + if (flags & ESM::Creature::Metal) properties += "Metal "; + if (flags & ESM::Creature::Essential) properties += "Essential "; + int unused = (0xFFFFFFFF ^ + (ESM::Creature::None| + ESM::Creature::Walks| + ESM::Creature::Swims| + ESM::Creature::Flies| + ESM::Creature::Biped| + ESM::Creature::Respawn| + ESM::Creature::Weapon| + ESM::Creature::Skeleton| + ESM::Creature::Metal| + ESM::Creature::Essential)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string landFlags(int flags) +{ + std::string properties = ""; + // The ESM component says that this first four bits are used, but + // only the first three bits are used as far as I can tell. + // There's also no enumeration of the bit in the ESM component. + if (flags == 0) properties += "[None] "; + if (flags & 0x00000001) properties += "Unknown1 "; + if (flags & 0x00000004) properties += "Unknown3 "; + if (flags & 0x00000002) properties += "Unknown2 "; + if (flags & 0xFFFFFFF8) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string leveledListFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels "; + // BUG? This flag apparently not present on creature lists... + if (flags & ESM::LeveledListBase::Each) properties += "Each "; + // BUG! The unsused bits should be defined in LeveledListBase. + int unused = (0xFFFFFFFF ^ + (ESM::LeveledListBase::AllLevels| + ESM::LeveledListBase::Each)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string lightFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Light::Dynamic) properties += "Dynamic "; + if (flags & ESM::Light::Fire) properties += "Fire "; + if (flags & ESM::Light::Carry) properties += "Carry "; + if (flags & ESM::Light::Flicker) properties += "Flicker "; + if (flags & ESM::Light::FlickerSlow) properties += "FlickerSlow "; + if (flags & ESM::Light::Pulse) properties += "Pulse "; + if (flags & ESM::Light::PulseSlow) properties += "PulseSlow "; + if (flags & ESM::Light::Negative) properties += "Negative "; + if (flags & ESM::Light::OffDefault) properties += "OffDefault "; + int unused = (0xFFFFFFFF ^ + (ESM::Light::Dynamic| + ESM::Light::Fire| + ESM::Light::Carry| + ESM::Light::Flicker| + ESM::Light::FlickerSlow| + ESM::Light::Pulse| + ESM::Light::PulseSlow| + ESM::Light::Negative| + ESM::Light::OffDefault)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string magicEffectFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // Enchanting & SpellMaking occur on the same list of effects. + // "EXTRA SPELL" appears in the construction set under both the + // spell making and enchanting tabs as an allowed effect. Since + // most of the effects without this flags are defective in various + // ways, it's still very unclear what these flag bits are. + if (flags & ESM::MagicEffect::SpellMaking) properties += "SpellMaking "; + if (flags & ESM::MagicEffect::Enchanting) properties += "Enchanting "; + if (flags & 0x00000040) properties += "RangeNoSelf "; + if (flags & 0x00000080) properties += "RangeTouch "; + if (flags & 0x00000100) properties += "RangeTarget "; + if (flags & 0x00001000) properties += "Unknown2 "; + if (flags & 0x00000001) properties += "AffectSkill "; + if (flags & 0x00000002) properties += "AffectAttribute "; + if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration "; + if (flags & 0x00000008) properties += "NoMagnitude "; + if (flags & 0x00000010) properties += "Negative "; + if (flags & 0x00000020) properties += "Unknown1 "; + // ESM componet says 0x800 is negative, but none of the magic + // effects have this flags set. + if (flags & ESM::MagicEffect::Negative) properties += "Unused "; + // Since only Chameleon has this flag it could be anything + // that uniquely distinguishes Chameleon. + if (flags & 0x00002000) properties += "Chameleon "; + if (flags & 0x00004000) properties += "Bound "; + if (flags & 0x00008000) properties += "Summon "; + // Calm, Demoralize, Frenzy, Lock, Open, Rally, Soultrap, Turn Unded + if (flags & 0x00010000) properties += "Unknown3 "; + if (flags & 0x00020000) properties += "Absorb "; + if (flags & 0xFFFC0000) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string npcFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // Mythicmods and the ESM component differ. Mythicmods says + // 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as + // AutoCalc. The former seems to be correct. All Bethesda + // records have bit 0x8 set. A suspiciously large portion of + // females have autocalc turned off. + if (flags & ESM::NPC::Autocalc) properties += "Unknown "; + if (flags & 0x00000010) properties += "Autocalc "; + if (flags & ESM::NPC::Female) properties += "Female "; + if (flags & ESM::NPC::Respawn) properties += "Respawn "; + if (flags & ESM::NPC::Essential) properties += "Essential "; + // These two flags do not appear on any NPCs and may have been + // confused with the flags for creatures. + if (flags & ESM::NPC::Skeleton) properties += "Skeleton "; + if (flags & ESM::NPC::Metal) properties += "Metal "; + // Whether corpses persist is a bit that is unaccounted for, + // however the only unknown bit occurs on ALL records, and + // relatively few NPCs have this bit set. + int unused = (0xFFFFFFFF ^ + (ESM::NPC::Autocalc| + 0x00000010| + ESM::NPC::Female| + ESM::NPC::Respawn| + ESM::NPC::Essential| + ESM::NPC::Skeleton| + ESM::NPC::Metal)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string raceFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // All races have the playable flag set in Bethesda files. + if (flags & ESM::Race::Playable) properties += "Playable "; + if (flags & ESM::Race::Beast) properties += "Beast "; + int unused = (0xFFFFFFFF ^ + (ESM::Race::Playable| + ESM::Race::Beast)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string spellFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc "; + if (flags & ESM::Spell::F_PCStart) properties += "PCStart "; + if (flags & ESM::Spell::F_Always) properties += "Always "; + int unused = (0xFFFFFFFF ^ + (ESM::Spell::F_Autocalc| + ESM::Spell::F_PCStart| + ESM::Spell::F_Always)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} + +std::string weaponFlags(int flags) +{ + std::string properties = ""; + if (flags == 0) properties += "[None] "; + // The interpretation of the flags are still unclear to me. + // Apparently you can't be Silver without being Magical? Many of + // the "Magical" weapons don't have enchantments of any sort. + if (flags & ESM::Weapon::Magical) properties += "Magical "; + if (flags & ESM::Weapon::Silver) properties += "Silver "; + int unused = (0xFFFFFFFF ^ + (ESM::Weapon::Magical| + ESM::Weapon::Silver)); + if (flags & unused) properties += "Invalid "; + properties += str(boost::format("(0x%08X)") % flags); + return properties; +} diff --git a/apps/esmtool/labels.hpp b/apps/esmtool/labels.hpp new file mode 100644 index 000000000..7f1ff7986 --- /dev/null +++ b/apps/esmtool/labels.hpp @@ -0,0 +1,64 @@ +#ifndef OPENMW_ESMTOOL_LABELS_H +#define OPENMW_ESMTOOL_LABELS_H + +#include + +std::string bodyPartLabel(char idx); +std::string meshPartLabel(char idx); +std::string meshTypeLabel(char idx); +std::string clothingTypeLabel(int idx); +std::string armorTypeLabel(int idx); +std::string dialogTypeLabel(int idx); +std::string questStatusLabel(int idx); +std::string creatureTypeLabel(int idx); +std::string soundTypeLabel(int idx); +std::string weaponTypeLabel(int idx); + +// This function's a bit different because the types are record types, +// not consecutive values. +std::string aiTypeLabel(int type); + +// This one's also a bit different, because it enumerates dialog +// select rule functions, not types. Structurally, it still converts +// indexes to strings for display. +std::string ruleFunction(int idx); + +// The labels below here can all be loaded from GMSTs, but are not +// currently because among other things, that requires loading the +// GMSTs before dumping any of the records. + +// If the data format supported ordered lists of GMSTs (post 1.0), the +// lists could define the valid values, their localization strings, +// and the indexes for referencing the types in other records in the +// database. Then a single label function could work for all types. + +std::string magicEffectLabel(int idx); +std::string attributeLabel(int idx); +std::string spellTypeLabel(int idx); +std::string specializationLabel(int idx); +std::string skillLabel(int idx); +std::string apparatusTypeLabel(int idx); +std::string rangeTypeLabel(int idx); +std::string schoolLabel(int idx); +std::string enchantTypeLabel(int idx); + +// The are the flag functions that convert a bitmask into a list of +// human readble strings representing the set bits. + +std::string bodyPartFlags(int flags); +std::string cellFlags(int flags); +std::string containerFlags(int flags); +std::string creatureFlags(int flags); +std::string landFlags(int flags); +std::string leveledListFlags(int flags); +std::string lightFlags(int flags); +std::string magicEffectFlags(int flags); +std::string npcFlags(int flags); +std::string raceFlags(int flags); +std::string spellFlags(int flags); +std::string weaponFlags(int flags); + +// Missing flags functions: +// aiServicesFlags, possibly more + +#endif diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index c679a1c4d..856700f5e 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1,54 +1,126 @@ #include "record.hpp" +#include "labels.hpp" #include #include void printAIPackage(ESM::AIPackage p) { - if (p.mType == ESM::AI_Wander) - { - std::cout << " AIType Wander:" << std::endl; - std::cout << " Distance: " << p.mWander.mDistance << std::endl; - std::cout << " Duration: " << p.mWander.mDuration << std::endl; - std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; - if (p.mWander.mUnk != 1) - std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + std::cout << " AI Type: " << aiTypeLabel(p.mType) + << " (" << boost::format("0x%08X") % p.mType << ")" << std::endl; + if (p.mType == ESM::AI_Wander) + { + std::cout << " Distance: " << p.mWander.mDistance << std::endl; + std::cout << " Duration: " << p.mWander.mDuration << std::endl; + std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; + if (p.mWander.mUnk != 1) + std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; + + std::cout << " Idle: "; + for (int i = 0; i != 8; i++) + std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << std::endl; + } + else if (p.mType == ESM::AI_Travel) + { + std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," + << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; + std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) + { + std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," + << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; + std::cout << " Duration: " << p.mTarget.mDuration << std::endl; + std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; + std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; + } + else if (p.mType == ESM::AI_Activate) + { + std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; + std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; + } + else { + std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; + } + + if (p.mCellName != "") + std::cout << " Cell Name: " << p.mCellName << std::endl; +} - std::cout << " Idle: "; - for (int i = 0; i != 8; i++) - std::cout << (int)p.mWander.mIdle[i] << " "; - std::cout << std::endl; - } - else if (p.mType == ESM::AI_Travel) - { - std::cout << " AIType Travel:" << std::endl; - std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," - << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; - std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl; - } - else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) - { - if (p.mType == ESM::AI_Follow) std::cout << " AIType Follow:" << std::endl; - else std::cout << " AIType Escort:" << std::endl; +std::string ruleString(ESM::DialInfo::SelectStruct ss) +{ + std::string rule = ss.mSelectRule; + + if (rule.length() < 5) + return "INVALID"; + + char type = rule[1]; + char indicator = rule[2]; + + std::string type_str = "INVALID"; + std::string func_str = str(boost::format("INVALID=%s") % rule.substr(1,3)); + int func; + std::istringstream iss(rule.substr(2,2)); + iss >> func; - std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," - << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; - std::cout << " Duration: " << p.mTarget.mDuration << std::endl; - std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; - std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl; - } - else if (p.mType == ESM::AI_Activate) - { - std::cout << " AIType Activate:" << std::endl; - std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; - std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl; - } - else { - std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; - } + switch(type) + { + case '1': + type_str = "Function"; + func_str = ruleFunction(func); + break; + case '2': + if (indicator == 's') type_str = "Global short"; + else if (indicator == 'l') type_str = "Global long"; + else if (indicator == 'f') type_str = "Global float"; + break; + case '3': + if (indicator == 's') type_str = "Local short"; + else if (indicator == 'l') type_str = "Local long"; + else if (indicator == 'f') type_str = "Local float"; + break; + case '4': if (indicator == 'J') type_str = "Journal"; break; + case '5': if (indicator == 'I') type_str = "Item type"; break; + case '6': if (indicator == 'D') type_str = "NPC Dead"; break; + case '7': if (indicator == 'X') type_str = "Not ID"; break; + case '8': if (indicator == 'F') type_str = "Not Faction"; break; + case '9': if (indicator == 'C') type_str = "Not Class"; break; + case 'A': if (indicator == 'R') type_str = "Not Race"; break; + case 'B': if (indicator == 'L') type_str = "Not Cell"; break; + case 'C': if (indicator == 's') type_str = "Not Local"; break; + } + + // Append the variable name to the function string if any. + if (type != '1') func_str = rule.substr(5); + + // In the previous switch, we assumed that the second char was X + // for all types not qual to one. If this wasn't true, go back to + // the error message. + if (type != '1' && rule[3] != 'X') + func_str = str(boost::format("INVALID=%s") % rule.substr(1,3)); - if (p.mCellName != "") - std::cout << " Cell Name: " << p.mCellName << std::endl; + char oper = rule[4]; + std::string oper_str = "??"; + switch (oper) + { + case '0': oper_str = "=="; break; + case '1': oper_str = "!="; break; + case '2': oper_str = "< "; break; + case '3': oper_str = "<="; break; + case '4': oper_str = "> "; break; + case '5': oper_str = ">="; break; + } + + std::string value_str = "??"; + if (ss.mType == ESM::VT_Int) + value_str = str(boost::format("%d") % ss.mI); + else if (ss.mType == ESM::VT_Float) + value_str = str(boost::format("%f") % ss.mF); + + std::string result = str(boost::format("%-12s %-32s %2s %s") + % type_str % func_str % oper_str % value_str); + return result; } void printEffectList(ESM::EffectList effects) @@ -57,12 +129,16 @@ void printEffectList(ESM::EffectList effects) std::vector::iterator eit; for (eit = effects.mList.begin(); eit != effects.mList.end(); eit++) { - std::cout << " Effect[" << i << "]: " << eit->mEffectID << std::endl; + std::cout << " Effect[" << i << "]: " << magicEffectLabel(eit->mEffectID) + << " (" << eit->mEffectID << ")" << std::endl; if (eit->mSkill != -1) - std::cout << " Skill: " << (int)eit->mSkill << std::endl; + std::cout << " Skill: " << skillLabel(eit->mSkill) + << " (" << (int)eit->mSkill << ")" << std::endl; if (eit->mAttribute != -1) - std::cout << " Attribute: " << (int)eit->mAttribute << std::endl; - std::cout << " Range: " << eit->mRange << std::endl; + std::cout << " Attribute: " << attributeLabel(eit->mAttribute) + << " (" << (int)eit->mAttribute << ")" << std::endl; + std::cout << " Range: " << rangeTypeLabel(eit->mRange) + << " (" << eit->mRange << ")" << std::endl; // Area is always zero if range type is "Self" if (eit->mRange != ESM::RT_Self) std::cout << " Area: " << eit->mArea << std::endl; @@ -331,7 +407,8 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << armorTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; @@ -340,7 +417,8 @@ void Record::print() std::vector::iterator pit; for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) { - std::cout << " Body Part: " << (int)(pit->mPart) << std::endl; + std::cout << " Body Part: " << bodyPartLabel(pit->mPart) + << " (" << (int)(pit->mPart) << ")" << std::endl; std::cout << " Male Name: " << pit->mMale << std::endl; if (pit->mFemale != "") std::cout << " Female Name: " << pit->mFemale << std::endl; @@ -354,7 +432,8 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType) + << " (" << (int)mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Quality: " << mData.mData.mQuality << std::endl; @@ -365,9 +444,11 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Type: " << (int)mData.mData.mType << std::endl; - std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; - std::cout << " Part: " << (int)mData.mData.mPart << std::endl; + std::cout << " Type: " << meshTypeLabel(mData.mData.mType) + << " (" << (int)mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << bodyPartFlags(mData.mData.mFlags) << std::endl; + std::cout << " Part: " << meshPartLabel(mData.mData.mPart) + << " (" << (int)mData.mData.mPart << ")" << std::endl; std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; } @@ -413,7 +494,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; if (mData.mRegion != "") std::cout << " Region: " << mData.mRegion << std::endl; - std::cout << " Flags: " << (int)mData.mData.mFlags << std::endl; + std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; std::cout << " Coordinates: " << " (" << mData.getGridX() << "," << mData.getGridY() << ")" << std::endl; @@ -441,13 +522,18 @@ void Record::print() std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; - std::cout << " Attribute1: " << mData.mData.mAttribute[0] << std::endl; - std::cout << " Attribute2: " << mData.mData.mAttribute[1] << std::endl; - std::cout << " Specialization: " << mData.mData.mSpecialization << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) + << " (" << mData.mData.mAttribute[0] << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) + << " (" << mData.mData.mAttribute[1] << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) + << " (" << mData.mData.mSpecialization << ")" << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Major Skill: " << mData.mData.mSkills[i][0] << std::endl; + std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][0]) + << " (" << mData.mData.mSkills[i][0] << ")" << std::endl; for (int i = 0; i != 5; i++) - std::cout << " Minor Skill: " << mData.mData.mSkills[i][1] << std::endl; + std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][1]) + << " (" << mData.mData.mSkills[i][1] << ")" << std::endl; } template<> @@ -460,10 +546,20 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; - // mEnchant also in CTDTstruct? + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + std::vector::iterator pit; + for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) + { + std::cout << " Body Part: " << bodyPartLabel(pit->mPart) + << " (" << (int)(pit->mPart) << ")" << std::endl; + std::cout << " Male Name: " << pit->mMale << std::endl; + if (pit->mFemale != "") + std::cout << " Female Name: " << pit->mFemale << std::endl; + } } template<> @@ -473,7 +569,7 @@ void Record::print() std::cout << " Model: " << mData.mModel << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl; std::vector::iterator cit; for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) @@ -487,11 +583,12 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << creatureFlags(mData.mFlags) << std::endl; std::cout << " Original: " << mData.mOriginal << std::endl; std::cout << " Scale: " << mData.mScale << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << creatureTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Level: " << mData.mData.mLevel << std::endl; std::cout << " Attributes:" << std::endl; @@ -547,7 +644,8 @@ void Record::print() template<> void Record::print() { - std::cout << " Type: " << (int)mData.mType << std::endl; + std::cout << " Type: " << dialogTypeLabel(mData.mType) + << " (" << (int)mData.mType << ")" << std::endl; // Sadly, there are no DialInfos, because the loader dumps as it // loads, rather than loading and then dumping. :-( Anyone mind if // I change this? @@ -569,7 +667,8 @@ void Record::print() template<> void Record::print() { - std::cout << " Type: " << mData.mData.mType << std::endl; + std::cout << " Type: " << enchantTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; std::cout << " Charge: " << mData.mData.mCharge << std::endl; std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl; @@ -583,11 +682,14 @@ void Record::print() std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; if (mData.mData.mUnknown != -1) std::cout << " Unknown: " << mData.mData.mUnknown << std::endl; - std::cout << " Attribute1: " << mData.mData.mAttribute1 << std::endl; - std::cout << " Attribute2: " << mData.mData.mAttribute2 << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute1) + << " (" << mData.mData.mAttribute1 << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute2) + << " (" << mData.mData.mAttribute2 << ")" << std::endl; for (int i = 0; i != 6; i++) if (mData.mData.mSkillID[i] != -1) - std::cout << " Skill: " << mData.mData.mSkillID[i] << std::endl; + std::cout << " Skill: " << skillLabel(mData.mData.mSkillID[i]) + << " (" << mData.mData.mSkillID[i] << ")" << std::endl; for (int i = 0; i != 10; i++) if (mData.mRanks[i] != "") { @@ -683,13 +785,14 @@ void Record::print() // std::cout << "-------------------------------------------" << std::endl; } - std::cout << " Quest Status: " << mData.mQuestStatus << std::endl; + std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) + << " (" << mData.mQuestStatus << ")" << std::endl; std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; std::vector::iterator sit; for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++) - std::cout << " Select Rule: " << sit->mType << " " << sit->mSelectRule << std::endl; + std::cout << " Select Rule: " << ruleString(*sit) << std::endl; } template<> @@ -706,9 +809,12 @@ void Record::print() { // A value of -1 means no effect if (mData.mData.mEffectID[i] == -1) continue; - std::cout << " Effect: " << mData.mData.mEffectID[i] << std::endl; - std::cout << " Skill: " << mData.mData.mSkills[i] << std::endl; - std::cout << " Attribute: " << mData.mData.mAttributes[i] << std::endl; + std::cout << " Effect: " << magicEffectLabel(mData.mData.mEffectID[i]) + << " (" << mData.mData.mEffectID[i] << ")" << std::endl; + std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) + << " (" << mData.mData.mSkills[i] << ")" << std::endl; + std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i]) + << " (" << mData.mData.mAttributes[i] << ")" << std::endl; } } @@ -716,7 +822,7 @@ template<> void Record::print() { std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl; std::cout << " HasData: " << mData.mHasData << std::endl; std::cout << " DataTypes: " << mData.mDataTypes << std::endl; @@ -739,7 +845,7 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -751,7 +857,7 @@ template<> void Record::print() { std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << leveledListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; std::vector::iterator iit; for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) @@ -770,7 +876,7 @@ void Record::print() std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; @@ -802,6 +908,7 @@ void Record::print() std::cout << " Icon: " << mData.mIcon << std::endl; if (mData.mScript != "") std::cout << " Script: " << mData.mScript << std::endl; + // BUG? No Type Label? std::cout << " Type: " << mData.mType << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -835,10 +942,11 @@ void Record::print() template<> void Record::print() { - std::cout << " Index: " << mData.mIndex << std::endl; + std::cout << " Index: " << magicEffectLabel(mData.mIndex) + << " (" << mData.mIndex << ")" << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl; if (mData.mCasting != "") std::cout << " Casting Static: " << mData.mCasting << std::endl; @@ -856,7 +964,8 @@ void Record::print() std::cout << " Area Static: " << mData.mArea << std::endl; if (mData.mAreaSound != "") std::cout << " Area Sound: " << mData.mAreaSound << std::endl; - std::cout << " School: " << mData.mData.mSchool << std::endl; + std::cout << " School: " << schoolLabel(mData.mData.mSchool) + << " (" << mData.mData.mSchool << ")" << std::endl; std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; std::cout << " Speed: " << mData.mData.mSpeed << std::endl; std::cout << " Size: " << mData.mData.mSize << std::endl; @@ -893,7 +1002,7 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mFaction != "") std::cout << " Faction: " << mData.mFaction << std::endl; - std::cout << " Flags: " << mData.mFlags << std::endl; + std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl; // Seriously? if (mData.mNpdt52.mGold == -10) @@ -929,7 +1038,7 @@ void Record::print() std::cout << " Skills:" << std::endl; for (int i = 0; i != 27; i++) - std::cout << " " << i << " = " + std::cout << " " << skillLabel(i) << ": " << (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl; std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl; @@ -1018,7 +1127,7 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl; std::cout << " Male:" << std::endl; std::cout << " Strength: " @@ -1067,8 +1176,10 @@ void Record::print() for (int i = 0; i != 7; i++) // Not all races have 7 skills. if (mData.mData.mBonus[i].mSkill != -1) - std::cout << " Skill: " << mData.mData.mBonus[i].mSkill - << " = " << mData.mData.mBonus[i].mBonus << std::endl; + std::cout << " Skill: " + << skillLabel(mData.mData.mBonus[i].mSkill) + << " (" << mData.mData.mBonus[i].mSkill << ") = " + << mData.mData.mBonus[i].mBonus << std::endl; std::vector::iterator sit; for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) @@ -1130,18 +1241,15 @@ void Record::print() template<> void Record::print() { - std::cout << " ID: " << mData.mIndex << std::endl; - - const char *spec = 0; - int specId = mData.mData.mSpecialization; - if (specId == 0) { - spec = "Combat"; - } else if (specId == 1) { - spec = "Magic"; - } else { - spec = "Stealth"; - } - std::cout << " Type: " << spec << std::endl; + std::cout << " ID: " << skillLabel(mData.mIndex) + << " (" << mData.mIndex << ")" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) + << " (" << mData.mData.mAttribute << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) + << " (" << mData.mData.mSpecialization << ")" << std::endl; + for (int i = 0; i != 4; i++) + std::cout << " UseValue[" << i << "]:" << mData.mData.mUseValue[i] << std::endl; } template<> @@ -1149,7 +1257,8 @@ void Record::print() { std::cout << " Creature: " << mData.mCreature << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Type: " << mData.mType << std::endl; + std::cout << " Type: " << soundTypeLabel(mData.mType) + << " (" << mData.mType << ")" << std::endl; } template<> @@ -1166,8 +1275,9 @@ template<> void Record::print() { std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Type: " << spellTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl; std::cout << " Cost: " << mData.mData.mCost << std::endl; printEffectList(mData.mEffects); } @@ -1199,8 +1309,9 @@ void Record::print() std::cout << " Script: " << mData.mScript << std::endl; if (mData.mEnchant != "") std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << mData.mData.mType << std::endl; - std::cout << " Flags: " << mData.mData.mFlags << std::endl; + std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) + << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << weaponFlags(mData.mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl; From e4a61486c8420606aac580973f088ec141d956fc Mon Sep 17 00:00:00 2001 From: cfcohen Date: Wed, 10 Oct 2012 22:15:19 -0400 Subject: [PATCH 032/255] Removed minor comments left in by accident. --- apps/esmtool/labels.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 1ebed1d55..9fb233237 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -48,7 +48,6 @@ std::string bodyPartLabel(char idx) "Tail" }; - // BUG? idx should probably be unsigned char instead if ((int)idx >= 0 && (int)(idx) <= 26) return bodyPartLabels[(int)(idx)]; else @@ -576,7 +575,6 @@ std::string ruleFunction(int idx) "Player Skill Mercantile", "Player Skill Speechcraft", "Player Skill Hand to Hand", -// Unknown1=0->Male, Unknown1=1->Female "Player Gender", "Player Expelled from Faction", "Player Diseased (Common)", @@ -646,7 +644,7 @@ std::string cellFlags(int flags) if (flags & ESM::Cell::Interior) properties += "Interior "; if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx "; - // CHANGE? This used value is not in the ESM component. + // This used value is not in the ESM component. if (flags & 0x00000040) properties += "Unknown "; int unused = (0xFFFFFFFF ^ (ESM::Cell::HasWater| @@ -725,9 +723,8 @@ std::string leveledListFlags(int flags) std::string properties = ""; if (flags == 0) properties += "[None] "; if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels "; - // BUG? This flag apparently not present on creature lists... + // This flag apparently not present on creature lists... if (flags & ESM::LeveledListBase::Each) properties += "Each "; - // BUG! The unsused bits should be defined in LeveledListBase. int unused = (0xFFFFFFFF ^ (ESM::LeveledListBase::AllLevels| ESM::LeveledListBase::Each)); From 17dc67be0a0f5a651b9693f053aba49305c044d5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 11 Oct 2012 09:08:51 +0200 Subject: [PATCH 033/255] updated credits.txt --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 2968e3487..45611a2d6 100644 --- a/credits.txt +++ b/credits.txt @@ -16,6 +16,7 @@ Alexander Olofsson (Ace) Artem Kotsynyak (greye) athile BrotherBrick +Cory F. Cohen (cfcohen) Cris Mihalache (Mirceam) Douglas Diniz (Dgdiniz) Eli2 From f154031e54d21271d8ee0f01818613d13eb94355 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Oct 2012 18:26:29 +0200 Subject: [PATCH 034/255] last bits of the gui --- apps/openmw/mwgui/spellcreationdialog.cpp | 123 +++++++++++++++++++++- apps/openmw/mwgui/spellcreationdialog.hpp | 13 +++ apps/openmw/mwgui/widgets.cpp | 8 +- apps/openmw/mwgui/widgets.hpp | 6 +- files/materials/water.shader | 2 +- files/mygui/openmw_edit_effect.layout | 79 ++++++++------ 6 files changed, 190 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 4e1c334db..02ce763ea 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -1,5 +1,7 @@ #include "spellcreationdialog.hpp" +#include + #include #include "../mwbase/windowmanager.hpp" @@ -49,21 +51,25 @@ namespace MWGui getWidget(mEffectImage, "EffectImage"); getWidget(mEffectName, "EffectName"); getWidget(mAreaText, "AreaText"); + getWidget(mDurationBox, "DurationBox"); + getWidget(mAreaBox, "AreaBox"); + getWidget(mMagnitudeBox, "MagnitudeBox"); mRangeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onRangeButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onOkButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onCancelButtonClicked); mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onDeleteButtonClicked); + + mMagnitudeMinSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMinChanged); + mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged); + mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged); + mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged); } void EditEffectDialog::open() { WindowModal::open(); center(); - - mEffect.mRange = ESM::RT_Self; - - onRangeButtonClicked(mRangeButton); } void EditEffectDialog::newEffect (const ESM::MagicEffect *effect) @@ -72,6 +78,25 @@ namespace MWGui mEditing = false; mDeleteButton->setVisible (false); + + mEffect.mRange = ESM::RT_Self; + + onRangeButtonClicked(mRangeButton); + + mMagnitudeMinSlider->setScrollPosition (0); + mMagnitudeMaxSlider->setScrollPosition (0); + mAreaSlider->setScrollPosition (0); + mDurationSlider->setScrollPosition (0); + + mDurationValue->setCaption("1"); + mMagnitudeMinValue->setCaption("1"); + mMagnitudeMaxValue->setCaption("- 1"); + mAreaValue->setCaption("0"); + + mEffect.mMagnMin = 1; + mEffect.mMagnMax = 1; + mEffect.mDuration = 1; + mEffect.mArea = 0; } void EditEffectDialog::editEffect (ESM::ENAMstruct effect) @@ -84,6 +109,16 @@ namespace MWGui mEditing = true; mDeleteButton->setVisible (true); + + mMagnitudeMinSlider->setScrollPosition (effect.mMagnMin-1); + mMagnitudeMaxSlider->setScrollPosition (effect.mMagnMax-1); + mAreaSlider->setScrollPosition (effect.mArea); + mDurationSlider->setScrollPosition (effect.mDuration-1); + + onMagnitudeMinChanged (mMagnitudeMinSlider, effect.mMagnMin-1); + onMagnitudeMaxChanged (mMagnitudeMinSlider, effect.mMagnMax-1); + onAreaChanged (mAreaSlider, effect.mArea); + onDurationChanged (mDurationSlider, effect.mDuration-1); } void EditEffectDialog::setMagicEffect (const ESM::MagicEffect *effect) @@ -99,6 +134,39 @@ namespace MWGui mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}"); mEffect.mEffectID = effect->mIndex; + + mMagicEffect = effect; + + updateBoxes(); + } + + void EditEffectDialog::updateBoxes() + { + static int startY = mMagnitudeBox->getPosition().top; + int curY = startY; + + mMagnitudeBox->setVisible (false); + mDurationBox->setVisible (false); + mAreaBox->setVisible (false); + + if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + { + mMagnitudeBox->setPosition(mMagnitudeBox->getPosition().left, curY); + mMagnitudeBox->setVisible (true); + curY += mMagnitudeBox->getSize().height; + } + if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) + { + mDurationBox->setPosition(mDurationBox->getPosition().left, curY); + mDurationBox->setVisible (true); + curY += mDurationBox->getSize().height; + } + if (mEffect.mRange == ESM::RT_Target) + { + mAreaBox->setPosition(mAreaBox->getPosition().left, curY); + mAreaBox->setVisible (true); + curY += mAreaBox->getSize().height; + } } void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) @@ -114,6 +182,16 @@ namespace MWGui mAreaSlider->setVisible (mEffect.mRange != ESM::RT_Self); mAreaText->setVisible (mEffect.mRange != ESM::RT_Self); + + // cycle through range types until we find something that's allowed + if (mEffect.mRange == ESM::RT_Target && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTarget)) + onRangeButtonClicked(sender); + if (mEffect.mRange == ESM::RT_Self && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastSelf)) + onRangeButtonClicked(sender); + if (mEffect.mRange == ESM::RT_Touch && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTouch)) + onRangeButtonClicked(sender); + + updateBoxes(); } void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender) @@ -148,6 +226,42 @@ namespace MWGui mEffect.mAttribute = attribute; } + void EditEffectDialog::onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos) + { + mMagnitudeMinValue->setCaption(boost::lexical_cast(pos+1)); + mEffect.mMagnMin = pos+1; + + // trigger the check again (see below) + onMagnitudeMaxChanged(mMagnitudeMaxSlider, mMagnitudeMaxSlider->getScrollPosition ()); + } + + void EditEffectDialog::onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos) + { + // make sure the max value is actually larger or equal than the min value + size_t magnMin = std::abs(mEffect.mMagnMin); // should never be < 0, this is just here to avoid the compiler warning + if (pos+1 < magnMin) + { + pos = mEffect.mMagnMin-1; + sender->setScrollPosition (pos); + } + + mEffect.mMagnMax = pos+1; + + mMagnitudeMaxValue->setCaption("- " + boost::lexical_cast(pos+1)); + } + + void EditEffectDialog::onDurationChanged (MyGUI::ScrollBar* sender, size_t pos) + { + mDurationValue->setCaption(boost::lexical_cast(pos+1)); + mEffect.mDuration = pos+1; + } + + void EditEffectDialog::onAreaChanged (MyGUI::ScrollBar* sender, size_t pos) + { + mAreaValue->setCaption(boost::lexical_cast(pos)); + mEffect.mArea = pos; + } + // ------------------------------------------------------------------------------------------------ SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager) @@ -356,6 +470,7 @@ namespace MWGui params.mMagnMin = it->mMagnMin; params.mMagnMax = it->mMagnMax; params.mRange = it->mRange; + params.mArea = it->mArea; MyGUI::Button* button = mUsedEffectsView->createWidget("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default); button->setUserData(i); diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index c5fffeb63..255b04cf6 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -38,6 +38,10 @@ namespace MWGui MyGUI::Button* mRangeButton; + MyGUI::Widget* mDurationBox; + MyGUI::Widget* mMagnitudeBox; + MyGUI::Widget* mAreaBox; + MyGUI::TextBox* mMagnitudeMinValue; MyGUI::TextBox* mMagnitudeMaxValue; MyGUI::TextBox* mDurationValue; @@ -61,10 +65,19 @@ namespace MWGui void onOkButtonClicked (MyGUI::Widget* sender); void onCancelButtonClicked (MyGUI::Widget* sender); + void onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos); + void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos); + void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos); + void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos); + void setMagicEffect(const ESM::MagicEffect* effect); + void updateBoxes(); + protected: ESM::ENAMstruct mEffect; + + const ESM::MagicEffect* mMagicEffect; }; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index d6a839760..ed09b9805 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -362,6 +362,7 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects) params.mMagnMin = it->mMagnMin; params.mMagnMax = it->mMagnMax; params.mRange = it->mRange; + params.mArea = it->mArea; result.push_back(params); } return result; @@ -437,6 +438,11 @@ void MWSpellEffect::updateWidgets() spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); } + if (mEffectParams.mArea > 0) + { + spellLine += " #{sin} " + boost::lexical_cast(mEffectParams.mArea) + " #{sfootarea}"; + } + // potions have no target if (!mEffectParams.mNoTarget) { @@ -450,7 +456,7 @@ void MWSpellEffect::updateWidgets() } } - static_cast(mTextWidget)->setCaption(spellLine); + static_cast(mTextWidget)->setCaptionWithReplacing(spellLine); mRequestedWidth = mTextWidget->getTextSize().width + 24; std::string path = std::string("icons\\") + magicEffect->mIcon; diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 0a15e8e1f..a41e1f123 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -32,6 +32,7 @@ namespace MWGui , mRange(-1) , mDuration(-1) , mSkill(-1) + , mArea(0) , mAttribute(-1) , mEffectID(-1) , mNoTarget(false) @@ -51,6 +52,9 @@ namespace MWGui // value of -1 here means the value is unavailable int mMagnMin, mMagnMax, mRange, mDuration; + // value of 0 -> no area effect + int mArea; + bool operator==(const SpellEffectParams& other) const { if (mEffectID != other.mEffectID) @@ -66,7 +70,7 @@ namespace MWGui || mEffectID == 21 // drain skill || mEffectID == 83 // fortify skill || mEffectID == 26); // damage skill - return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute); + return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute) && (other.mArea == mArea); } }; diff --git a/files/materials/water.shader b/files/materials/water.shader index 947dc72f5..6bd277eab 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -298,7 +298,7 @@ } else { - float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); + float fogValue = shSaturate((length(cameraPos.xyz-position.xyz) - fogParams.y) * fogParams.w); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColor), fogValue); } diff --git a/files/mygui/openmw_edit_effect.layout b/files/mygui/openmw_edit_effect.layout index 884723feb..45ecb63ed 100644 --- a/files/mygui/openmw_edit_effect.layout +++ b/files/mygui/openmw_edit_effect.layout @@ -21,49 +21,60 @@
- - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - + + + + + - - - - - + + + + + + + From 85aaacb41a89e37f874ecdbd8f22ad55128dcb0f Mon Sep 17 00:00:00 2001 From: pvdk Date: Fri, 12 Oct 2012 02:25:14 +0200 Subject: [PATCH 035/255] Some cleaning of the launcher source dir --- apps/launcher/CMakeLists.txt | 35 +++-- apps/launcher/datafilespage.cpp | 10 +- apps/launcher/datafilespage.hpp | 1 - apps/launcher/graphicspage.cpp | 3 +- apps/launcher/maindialog.cpp | 2 + apps/launcher/model/datafilesmodel.cpp | 3 +- apps/launcher/pluginsmodel.cpp | 149 ---------------------- apps/launcher/pluginsmodel.hpp | 21 --- apps/launcher/pluginsview.cpp | 41 ------ apps/launcher/pluginsview.hpp | 29 ----- apps/launcher/{ => utils}/combobox.hpp | 0 apps/launcher/{ => utils}/filedialog.cpp | 0 apps/launcher/{ => utils}/filedialog.hpp | 0 apps/launcher/{ => utils}/lineedit.cpp | 0 apps/launcher/{ => utils}/lineedit.hpp | 0 apps/launcher/{ => utils}/naturalsort.cpp | 0 apps/launcher/{ => utils}/naturalsort.hpp | 0 17 files changed, 28 insertions(+), 266 deletions(-) delete mode 100644 apps/launcher/pluginsmodel.cpp delete mode 100644 apps/launcher/pluginsmodel.hpp delete mode 100644 apps/launcher/pluginsview.cpp delete mode 100644 apps/launcher/pluginsview.hpp rename apps/launcher/{ => utils}/combobox.hpp (100%) rename apps/launcher/{ => utils}/filedialog.cpp (100%) rename apps/launcher/{ => utils}/filedialog.hpp (100%) rename apps/launcher/{ => utils}/lineedit.cpp (100%) rename apps/launcher/{ => utils}/lineedit.hpp (100%) rename apps/launcher/{ => utils}/naturalsort.cpp (100%) rename apps/launcher/{ => utils}/naturalsort.hpp (100%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 53631ebdd..92903b48d 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -1,54 +1,51 @@ set(LAUNCHER datafilespage.cpp - filedialog.cpp graphicspage.cpp - lineedit.cpp main.cpp maindialog.cpp - naturalsort.cpp playpage.cpp - pluginsmodel.cpp - pluginsview.cpp - - launcher.rc model/datafilesmodel.cpp model/modelitem.cpp model/esm/esmfile.cpp + + utils/filedialog.cpp + utils/naturalsort.cpp + utils/lineedit.cpp + + launcher.rc ) set(LAUNCHER_HEADER - combobox.hpp datafilespage.hpp - filedialog.hpp graphicspage.hpp - lineedit.hpp maindialog.hpp - naturalsort.hpp playpage.hpp - pluginsmodel.hpp - pluginsview.hpp model/datafilesmodel.hpp model/modelitem.hpp model/esm/esmfile.hpp + + utils/combobox.hpp + utils/lineedit.hpp + utils/filedialog.hpp + utils/naturalsort.hpp ) # Headers that must be pre-processed set(LAUNCHER_HEADER_MOC - combobox.hpp datafilespage.hpp - filedialog.hpp graphicspage.hpp - lineedit.hpp maindialog.hpp playpage.hpp - pluginsmodel.hpp - pluginsview.hpp model/datafilesmodel.hpp model/modelitem.hpp model/esm/esmfile.hpp + + utils/combobox.hpp + utils/lineedit.hpp + utils/filedialog.hpp ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC}) @@ -87,7 +84,7 @@ add_executable(omwlauncher target_link_libraries(omwlauncher ${Boost_LIBRARIES} ${OGRE_LIBRARIES} - ${OGRE_STATIC_PLUGINS} + ${OGRE_STATIC_PLUGINS} ${QT_LIBRARIES} components ) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index c0a447e26..7b6c949c4 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -6,11 +6,12 @@ #include "model/datafilesmodel.hpp" #include "model/esm/esmfile.hpp" -#include "combobox.hpp" +#include "utils/combobox.hpp" +#include "utils/filedialog.hpp" +#include "utils/lineedit.hpp" +#include "utils/naturalsort.hpp" + #include "datafilespage.hpp" -#include "filedialog.hpp" -#include "lineedit.hpp" -#include "naturalsort.hpp" #include /** @@ -110,6 +111,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) mPluginsTable->setAlternatingRowColors(true); mPluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); mPluginsTable->horizontalHeader()->setStretchLastSection(true); + mPluginsTable->horizontalHeader()->hide(); mPluginsTable->verticalHeader()->setDefaultSectionSize(height); mPluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 648991254..64f255b57 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -6,7 +6,6 @@ #include -#include "combobox.hpp" class QTableView; class QSortFilterProxyModel; diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index c3c39cffc..7685cb3c2 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -9,8 +9,9 @@ #include #include +#include "utils/naturalsort.hpp" + #include "graphicspage.hpp" -#include "naturalsort.hpp" QString getAspect(int x, int y) { diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index f7dafd3af..f215b9118 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,5 +1,7 @@ #include +#include "utils/combobox.hpp" + #include "maindialog.hpp" #include "playpage.hpp" #include "graphicspage.hpp" diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index f009c3df0..0aa29a337 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -6,8 +6,9 @@ #include "esm/esmfile.hpp" +#include "../utils/naturalsort.hpp" + #include "datafilesmodel.hpp" -#include "../naturalsort.hpp" DataFilesModel::DataFilesModel(QObject *parent) : QAbstractTableModel(parent) diff --git a/apps/launcher/pluginsmodel.cpp b/apps/launcher/pluginsmodel.cpp deleted file mode 100644 index 86bd53027..000000000 --- a/apps/launcher/pluginsmodel.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include - -#include - -#include "pluginsmodel.hpp" - -PluginsModel::PluginsModel(QObject *parent) : QStandardItemModel(parent) -{ - -} - -void decodeDataRecursive(QDataStream &stream, QStandardItem *item) -{ - int colCount, childCount; - stream >> *item; - stream >> colCount >> childCount; - item->setColumnCount(colCount); - - int childPos = childCount; - - while(childPos > 0) { - childPos--; - QStandardItem *child = new QStandardItem(); - decodeDataRecursive(stream, child); - item->setChild( childPos / colCount, childPos % colCount, child); - } -} - -bool PluginsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, - int row, int column, const QModelIndex &parent) -{ - // Code largely based on QStandardItemModel::dropMimeData - - // check if the action is supported - if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction)) - return false; - - // check if the format is supported - QString format = QLatin1String("application/x-qstandarditemmodeldatalist"); - if (!data->hasFormat(format)) - return QAbstractItemModel::dropMimeData(data, action, row, column, parent); - - if (row > rowCount(parent)) - row = rowCount(parent); - if (row == -1) - row = rowCount(parent); - if (column == -1) - column = 0; - - // decode and insert - QByteArray encoded = data->data(format); - QDataStream stream(&encoded, QIODevice::ReadOnly); - - - //code based on QAbstractItemModel::decodeData - // adapted to work with QStandardItem - int top = std::numeric_limits::max(); - int left = std::numeric_limits::max(); - int bottom = 0; - int right = 0; - QVector rows, columns; - QVector items; - - while (!stream.atEnd()) { - int r, c; - QStandardItem *item = new QStandardItem(); - stream >> r >> c; - decodeDataRecursive(stream, item); - - rows.append(r); - columns.append(c); - items.append(item); - top = qMin(r, top); - left = qMin(c, left); - bottom = qMax(r, bottom); - right = qMax(c, right); - } - - // insert the dragged items into the table, use a bit array to avoid overwriting items, - // since items from different tables can have the same row and column - int dragRowCount = 0; - int dragColumnCount = right - left + 1; - - // Compute the number of continuous rows upon insertion and modify the rows to match - QVector rowsToInsert(bottom + 1); - for (int i = 0; i < rows.count(); ++i) - rowsToInsert[rows.at(i)] = 1; - for (int i = 0; i < rowsToInsert.count(); ++i) { - if (rowsToInsert[i] == 1){ - rowsToInsert[i] = dragRowCount; - ++dragRowCount; - } - } - for (int i = 0; i < rows.count(); ++i) - rows[i] = top + rowsToInsert[rows[i]]; - - QBitArray isWrittenTo(dragRowCount * dragColumnCount); - - // make space in the table for the dropped data - int colCount = columnCount(parent); - if (colCount < dragColumnCount + column) { - insertColumns(colCount, dragColumnCount + column - colCount, parent); - colCount = columnCount(parent); - } - insertRows(row, dragRowCount, parent); - - row = qMax(0, row); - column = qMax(0, column); - - QStandardItem *parentItem = itemFromIndex (parent); - if (!parentItem) - parentItem = invisibleRootItem(); - - QVector newIndexes(items.size()); - // set the data in the table - for (int j = 0; j < items.size(); ++j) { - int relativeRow = rows.at(j) - top; - int relativeColumn = columns.at(j) - left; - int destinationRow = relativeRow + row; - int destinationColumn = relativeColumn + column; - int flat = (relativeRow * dragColumnCount) + relativeColumn; - // if the item was already written to, or we just can't fit it in the table, create a new row - if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) { - destinationColumn = qBound(column, destinationColumn, colCount - 1); - destinationRow = row + dragRowCount; - insertRows(row + dragRowCount, 1, parent); - flat = (dragRowCount * dragColumnCount) + relativeColumn; - isWrittenTo.resize(++dragRowCount * dragColumnCount); - } - if (!isWrittenTo.testBit(flat)) { - newIndexes[j] = index(destinationRow, destinationColumn, parentItem->index()); - isWrittenTo.setBit(flat); - } - } - - for(int k = 0; k < newIndexes.size(); k++) { - if (newIndexes.at(k).isValid()) { - parentItem->setChild(newIndexes.at(k).row(), newIndexes.at(k).column(), items.at(k)); - } else { - delete items.at(k); - } - } - - // The important part, tell the view what is dropped - emit indexesDropped(newIndexes); - - return true; -} diff --git a/apps/launcher/pluginsmodel.hpp b/apps/launcher/pluginsmodel.hpp deleted file mode 100644 index 41df499b5..000000000 --- a/apps/launcher/pluginsmodel.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PLUGINSMODEL_H -#define PLUGINSMODEL_H - -#include - -class PluginsModel : public QStandardItemModel -{ - Q_OBJECT - -public: - PluginsModel(QObject *parent = 0); - ~PluginsModel() {}; - - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - -signals: - void indexesDropped(QVector indexes); - -}; - -#endif \ No newline at end of file diff --git a/apps/launcher/pluginsview.cpp b/apps/launcher/pluginsview.cpp deleted file mode 100644 index 26cf337fb..000000000 --- a/apps/launcher/pluginsview.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#include "pluginsview.hpp" - -PluginsView::PluginsView(QWidget *parent) : QTableView(parent) -{ - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setEditTriggers(QAbstractItemView::NoEditTriggers); - setAlternatingRowColors(true); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::InternalMove); - setDropIndicatorShown(true); - setDragDropOverwriteMode(false); - setContextMenuPolicy(Qt::CustomContextMenu); - -} - -void PluginsView::startDrag(Qt::DropActions supportedActions) -{ - selectionModel()->select( selectionModel()->selection(), - QItemSelectionModel::Select | QItemSelectionModel::Rows ); - QAbstractItemView::startDrag( supportedActions ); -} - -void PluginsView::setModel(QSortFilterProxyModel *model) -{ - QTableView::setModel(model); - - qRegisterMetaType< QVector >(); - - connect(model->sourceModel(), SIGNAL(indexesDropped(QVector)), - this, SLOT(selectIndexes(QVector)), Qt::QueuedConnection); -} - -void PluginsView::selectIndexes( QVector aIndexes ) -{ - selectionModel()->clearSelection(); - foreach( QPersistentModelIndex pIndex, aIndexes ) - selectionModel()->select( pIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows ); -} diff --git a/apps/launcher/pluginsview.hpp b/apps/launcher/pluginsview.hpp deleted file mode 100644 index 484351e33..000000000 --- a/apps/launcher/pluginsview.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef PLUGINSVIEW_H -#define PLUGINSVIEW_H - -#include - -#include "pluginsmodel.hpp" - -class QSortFilterProxyModel; - -class PluginsView : public QTableView -{ - Q_OBJECT -public: - PluginsView(QWidget *parent = 0); - - PluginsModel* model() const - { return qobject_cast(QAbstractItemView::model()); } - - void startDrag(Qt::DropActions supportedActions); - void setModel(QSortFilterProxyModel *model); - -public slots: - void selectIndexes(QVector aIndexes); - -}; - -Q_DECLARE_METATYPE(QVector) - -#endif diff --git a/apps/launcher/combobox.hpp b/apps/launcher/utils/combobox.hpp similarity index 100% rename from apps/launcher/combobox.hpp rename to apps/launcher/utils/combobox.hpp diff --git a/apps/launcher/filedialog.cpp b/apps/launcher/utils/filedialog.cpp similarity index 100% rename from apps/launcher/filedialog.cpp rename to apps/launcher/utils/filedialog.cpp diff --git a/apps/launcher/filedialog.hpp b/apps/launcher/utils/filedialog.hpp similarity index 100% rename from apps/launcher/filedialog.hpp rename to apps/launcher/utils/filedialog.hpp diff --git a/apps/launcher/lineedit.cpp b/apps/launcher/utils/lineedit.cpp similarity index 100% rename from apps/launcher/lineedit.cpp rename to apps/launcher/utils/lineedit.cpp diff --git a/apps/launcher/lineedit.hpp b/apps/launcher/utils/lineedit.hpp similarity index 100% rename from apps/launcher/lineedit.hpp rename to apps/launcher/utils/lineedit.hpp diff --git a/apps/launcher/naturalsort.cpp b/apps/launcher/utils/naturalsort.cpp similarity index 100% rename from apps/launcher/naturalsort.cpp rename to apps/launcher/utils/naturalsort.cpp diff --git a/apps/launcher/naturalsort.hpp b/apps/launcher/utils/naturalsort.hpp similarity index 100% rename from apps/launcher/naturalsort.hpp rename to apps/launcher/utils/naturalsort.hpp From 8ccb0907e647dc02f770aaf5357927605dac811f Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Oct 2012 14:26:10 +0200 Subject: [PATCH 036/255] assertion -> exception; added the old effect flags again --- components/esm/loadmgef.cpp | 5 ++++- components/esm/loadmgef.hpp | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 954214036..d0230e3b6 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -1,5 +1,7 @@ #include "loadmgef.hpp" +#include + #include "esmreader.hpp" #include "esmwriter.hpp" @@ -231,7 +233,8 @@ std::string MagicEffect::effectIdToString(short effectID) // tribunal names[137] ="sEffectSummonFabricant"; - assert(names.find(effectID) != names.end() && "Unimplemented effect type"); + if (names.find(effectID) == names.end()) + throw std::runtime_error( std::string("Unimplemented effect ID ") + boost::lexical_cast(effectID)); return names[effectID]; } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index abf4ab545..00349a355 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -17,7 +17,7 @@ struct MagicEffect TargetAttribute = 0x2, // Affects a specific attribute, which is specified elsewhere in the effect structure. NoDuration = 0x4, // Has no duration. Only runs effect once on cast. NoMagnitude = 0x8, // Has no magnitude. - Negative = 0x10, // Counts as a negative effect. Interpreted as useful for attack, and is treated as a bad effect in alchemy. + Harmful = 0x10, // Counts as a negative effect. Interpreted as useful for attack, and is treated as a bad effect in alchemy. ContinuousVfx = 0x20, // The effect's hit particle VFX repeats for the full duration of the spell, rather than occuring once on hit. CastSelf = 0x40, // Allows range - cast on self. CastTouch = 0x80, // Allows range - cast on touch. @@ -25,7 +25,12 @@ struct MagicEffect UncappedDamage = 0x1000, // Negates multiple cap behaviours. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second. NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot re-cast" message for self target. Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally. - CasterLinked = 0x20000 // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells. + CasterLinked = 0x20000, // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells. + + SpellMaking = 0x0200, + Enchanting = 0x0400, + Negative = 0x0800 // A harmful effect. Will determine whether + // eg. NPCs regard this spell as an attack. (same as 0x10?) }; struct MEDTstruct From c991f68a2dbf929a7a158593042e4dd08163fc18 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 15 Oct 2012 21:54:19 +0200 Subject: [PATCH 037/255] buying created spell --- apps/openmw/mwbase/world.hpp | 6 ++++ apps/openmw/mwgui/spellcreationdialog.cpp | 42 +++++++++++++++++++++++ apps/openmw/mwworld/worldimp.cpp | 14 ++++++++ apps/openmw/mwworld/worldimp.hpp | 4 +++ 4 files changed, 66 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 521bbb988..1cb120b5c 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -28,6 +28,7 @@ namespace ESM struct Cell; struct Class; struct Potion; + struct Spell; } namespace ESMS @@ -235,6 +236,11 @@ namespace MWBase ///< 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) + = 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) = 0; ///< Create a new recrod (of type class) in the ESM store. diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 02ce763ea..bb066e8ff 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -8,6 +8,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" @@ -297,7 +298,35 @@ namespace MWGui void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) { + if (mEffects.size() <= 0) + { + mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector()); + return; + } + if (mNameEdit->getCaption () == "") + { + mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector()); + return; + } + + ESM::Spell newSpell; + ESM::EffectList effectList; + effectList.mList = mEffects; + newSpell.mEffects = effectList; + newSpell.mName = mNameEdit->getCaption(); + newSpell.mData.mType = ESM::Spell::ST_Spell; + + std::pair result = MWBase::Environment::get().getWorld()->createRecord(newSpell); + + 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); + + MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); + + mWindowManager.removeGuiMode (GM_SpellCreation); } void SpellCreationDialog::open() @@ -372,6 +401,9 @@ namespace MWGui ToolTips::createMagicEffectToolTip (w, *it); } + + mEffects.clear(); + updateEffectsView (); } void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView) @@ -413,6 +445,16 @@ namespace MWGui { short effectId = *sender->getUserData(); + + for (std::vector::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) + { + if (it->mEffectID == effectId) + { + MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}", std::vector()); + return; + } + } + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId); mAddEffectDialog.newEffect (effect); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6fc228f0b..495deb1ad 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -802,6 +802,20 @@ namespace MWWorld return std::make_pair (stream.str(), created); } + std::pair World::createRecord (const ESM::Spell& record) + { + /// \todo See function above. + std::ostringstream stream; + stream << "$dynamic" << mNextDynamicRecord++; + + const ESM::Spell *created = + &mStore.spells.list.insert (std::make_pair (stream.str(), record)).first->second; + + mStore.all.insert (std::make_pair (stream.str(), ESM::REC_SPEL)); + + return std::make_pair (stream.str(), created); + } + const ESM::Cell *World::createRecord (const ESM::Cell& record) { if (record.mData.mFlags & ESM::Cell::Interior) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 90cd2151b..830a29918 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -253,6 +253,10 @@ namespace MWWorld ///< 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); + ///< 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); ///< Create a new recrod (of type class) in the ESM store. /// \return ID, pointer to created record From c9afe222bec803da4035e9e106b73acc55c5af77 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 16 Oct 2012 19:34:29 +0200 Subject: [PATCH 038/255] traveling now takes time --- apps/openmw/mwgui/travelwindow.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index c2eb33c6c..7dbfdf315 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -4,10 +4,13 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" @@ -76,7 +79,6 @@ namespace MWGui toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); - //toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Destination", travelId); toAdd->setUserData(pos); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick); @@ -141,6 +143,7 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { + //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position pos = *_sender->getUserData(); std::string cellname = _sender->getUserString("Destination"); @@ -149,10 +152,23 @@ namespace MWGui MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); MWWorld::CellStore* cell; if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); - else cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + else + { + cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + ESM::Position PlayerPos = player.getRefData().getPosition(); + float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); + int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); + std::cout << time; + for(int i = 0;i < time;i++) + { + MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); + } + MWBase::Environment::get().getWorld()->advanceTime(time); + } MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); mWindowManager.removeGuiMode(GM_Travel); mWindowManager.removeGuiMode(GM_Dialogue); + //MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5); } } From 9583a1b8e94df2721a3b5256215ab0ba9ca18da5 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 16 Oct 2012 19:59:53 +0200 Subject: [PATCH 039/255] FadeOut/In, that's for you scrawl! --- apps/openmw/mwgui/travelwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 7dbfdf315..fcdd80081 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -143,7 +143,7 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) { - //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position pos = *_sender->getUserData(); std::string cellname = _sender->getUserString("Destination"); @@ -168,7 +168,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); mWindowManager.removeGuiMode(GM_Travel); mWindowManager.removeGuiMode(GM_Dialogue); - //MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5); + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); } } From 7d1e659960c2eaffeb9b61adf479bfa390cfd87b Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 16 Oct 2012 20:25:50 +0200 Subject: [PATCH 040/255] fading, greying out destinations you cant afford, warning fix --- apps/openmw/mwgui/loadingscreen.cpp | 5 +++ apps/openmw/mwgui/travelwindow.cpp | 70 +++++++++++++++-------------- extern/shiny | 2 +- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 170fc3bc5..9ffb39221 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,10 +6,12 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -106,6 +108,7 @@ namespace MWGui if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) { + float dt = mTimer.getMilliseconds () - mLastRenderTime; mLastRenderTime = mTimer.getMilliseconds (); if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1) @@ -151,6 +154,8 @@ namespace MWGui } } + MWBase::Environment::get().getWorld ()->getFader ()->update (dt); + mWindow->update(); if (!hasCompositor) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index fcdd80081..da138a42e 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -52,26 +52,28 @@ namespace MWGui void TravelWindow::addDestination(const std::string& travelId,ESM::Position pos,bool interior) { - //std::cout << "travel to" << travelId; - /*const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); - int price = spell->data.cost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat();*/ int price = 0; - MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); - mCurrentY += sLineHeight; - /// \todo price adjustment depending on merchantile skill + if(interior) { - toAdd->setUserString("interior","y"); price = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fMagesGuildTravel")->getFloat(); } else { - toAdd->setUserString("interior","n"); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat(); } + + MyGUI::Button* toAdd = mDestinationsView->createWidget((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); + mCurrentY += sLineHeight; + /// \todo price adjustment depending on merchantile skill + if(interior) + toAdd->setUserString("interior","y"); + else + toAdd->setUserString("interior","n"); + std::ostringstream oss; oss << price; toAdd->setUserString("price",oss.str()); @@ -118,7 +120,7 @@ namespace MWGui addDestination (*iter); }*/ - for(int i = 0;i()->base->mTransport.size();i++) + for(unsigned int i = 0;i()->base->mTransport.size();i++) { std::string cellname = mPtr.get()->base->mTransport[i].mCellName; bool interior = true; @@ -141,35 +143,35 @@ namespace MWGui int price; iss >> price; - if (mWindowManager.getInventoryWindow()->getPlayerGold()>=price) + assert (mWindowManager.getInventoryWindow()->getPlayerGold()>=price); + + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position pos = *_sender->getUserData(); + std::string cellname = _sender->getUserString("Destination"); + int x,y; + bool interior = _sender->getUserString("interior") == "y"; + MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); + MWWorld::CellStore* cell; + if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); + else { - MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - ESM::Position pos = *_sender->getUserData(); - std::string cellname = _sender->getUserString("Destination"); - int x,y; - bool interior = _sender->getUserString("interior") == "y"; - MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y); - MWWorld::CellStore* cell; - if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname); - else + cell = MWBase::Environment::get().getWorld()->getExterior(x,y); + ESM::Position PlayerPos = player.getRefData().getPosition(); + float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); + int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); + std::cout << time; + for(int i = 0;i < time;i++) { - cell = MWBase::Environment::get().getWorld()->getExterior(x,y); - ESM::Position PlayerPos = player.getRefData().getPosition(); - float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); - int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat()); - std::cout << time; - for(int i = 0;i < time;i++) - { - MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); - } - MWBase::Environment::get().getWorld()->advanceTime(time); + MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); } - MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); - mWindowManager.removeGuiMode(GM_Travel); - mWindowManager.removeGuiMode(GM_Dialogue); - MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); + MWBase::Environment::get().getWorld()->advanceTime(time); } + MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]); + mWindowManager.removeGuiMode(GM_Travel); + mWindowManager.removeGuiMode(GM_Dialogue); + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0); + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1); } void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender) diff --git a/extern/shiny b/extern/shiny index 4750676ac..f17c4ebab 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit 4750676ac46a7aaa86bca53dc68c5a1ba11f3bc1 +Subproject commit f17c4ebab0e7a1f3bbb25fd9b3dbef2bd742536a From 5e9153e2b8766ff42b9aadcba6aaba2e5bb50688 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Tue, 16 Oct 2012 23:16:14 +0300 Subject: [PATCH 041/255] Issue #423: Wrong usage of "Version" Remove "Version" line from openmw.desktop file (according to http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s05.html it's not required). Fixes #423 Signed-off-by: Lukasz Gromanowski --- files/openmw.desktop | 1 - 1 file changed, 1 deletion(-) diff --git a/files/openmw.desktop b/files/openmw.desktop index 234f660c6..118cd3bbe 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -1,5 +1,4 @@ [Desktop Entry] -Version=${OPENMW_VERSION} Type=Application Name=OpenMW Launcher GenericName=Role Playing Game From 6acbea822b70b8b7e5f5c6f6222ac892da4a5e26 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 16 Oct 2012 23:59:03 +0200 Subject: [PATCH 042/255] splash screen directory listing --- apps/openmw/mwgui/loadingscreen.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 170fc3bc5..bb3aade61 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" @@ -207,20 +209,16 @@ namespace MWGui void LoadingScreen::changeWallpaper () { - /// \todo use a directory listing here std::vector splash; - splash.push_back ("Splash_Bonelord.tga"); - splash.push_back ("Splash_ClannDaddy.tga"); - splash.push_back ("Splash_Clannfear.tga"); - splash.push_back ("Splash_Daedroth.tga"); - splash.push_back ("Splash_Hunger.tga"); - splash.push_back ("Splash_KwamaWarrior.tga"); - splash.push_back ("Splash_Netch.tga"); - splash.push_back ("Splash_NixHound.tga"); - splash.push_back ("Splash_Siltstriker.tga"); - splash.push_back ("Splash_Skeleton.tga"); - splash.push_back ("Splash_SphereCenturion.tga"); + Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false); + for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it) + { + std::string start = it->substr(0, 6); + boost::to_lower(start); + if (start == "splash") + splash.push_back (*it); + } mBackgroundImage->setImageTexture (splash[rand() % splash.size()]); } } From 84a4fd56c32de6aa954c6e92490191926c4106a7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 12:39:45 +0200 Subject: [PATCH 043/255] consider all files in Splash directory --- apps/openmw/engine.cpp | 5 ++--- apps/openmw/mwgui/loadingscreen.cpp | 6 +++++- components/bsa/bsa_archive.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index adbfca129..9b1a55025 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -163,9 +163,8 @@ void OMW::Engine::loadBSA() std::cout << "Data dir " << dataDirectory << std::endl; Bsa::addDir(dataDirectory, mFSStrict); - // Workaround: Mygui does not find textures in non-BSA subfolders, _unless_ they are explicitely added like this - // For splash screens, this is OK to do, but eventually we will need an investigation why this is necessary - Bsa::addDir(dataDirectory + "/Splash", mFSStrict); + // Workaround until resource listing capabilities are added to DirArchive, we need those to list available splash screens + addResourcesDirectory (dataDirectory); } } diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index bb3aade61..cfe54c91a 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -216,9 +216,13 @@ namespace MWGui { std::string start = it->substr(0, 6); boost::to_lower(start); + if (start == "splash") splash.push_back (*it); } - mBackgroundImage->setImageTexture (splash[rand() % splash.size()]); + std::string randomSplash = splash[rand() % splash.size()]; + + Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General"); + mBackgroundImage->setImageTexture (randomSplash); } } diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 081207b0c..8380b0838 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -375,7 +375,7 @@ void addBSA(const std::string& name, const std::string& group) { insertBSAFactory(); ResourceGroupManager::getSingleton(). - addResourceLocation(name, "BSA", group); + addResourceLocation(name, "BSA", group, true); } void addDir(const std::string& name, const bool& fs, const std::string& group) @@ -384,7 +384,7 @@ void addDir(const std::string& name, const bool& fs, const std::string& group) insertDirFactory(); ResourceGroupManager::getSingleton(). - addResourceLocation(name, "Dir", group); + addResourceLocation(name, "Dir", group, true); } } From 6be092e26819baa5142b1a059079e105b4921690 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 12:41:24 +0200 Subject: [PATCH 044/255] substr check --- apps/openmw/mwgui/loadingscreen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index cfe54c91a..2eccc8f2a 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -214,6 +214,8 @@ namespace MWGui Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false); for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it) { + if (it->size() < 6) + continue; std::string start = it->substr(0, 6); boost::to_lower(start); From 1a2034b4dddfacafd52a2fbd2eeec72e008d4b57 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:03:02 +0200 Subject: [PATCH 045/255] training window --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 3 + apps/openmw/mwgui/dialogue.cpp | 8 + apps/openmw/mwgui/dialogue.hpp | 3 +- apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/trainingwindow.cpp | 152 ++++++++++++++++++ apps/openmw/mwgui/trainingwindow.hpp | 36 +++++ apps/openmw/mwgui/windowmanagerimp.cpp | 16 ++ apps/openmw/mwgui/windowmanagerimp.hpp | 3 + apps/openmw/mwsound/ffmpeg_decoder.hpp | 2 +- components/esm/aipackage.hpp | 2 - files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_trainingwindow.layout | 31 ++++ 14 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 apps/openmw/mwgui/trainingwindow.cpp create mode 100644 apps/openmw/mwgui/trainingwindow.hpp create mode 100644 files/mygui/openmw_trainingwindow.layout diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index bc4e10501..d3698b53e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -30,7 +30,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog + enchantingdialog trainingwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 462aef014..f4c78f5fb 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -230,6 +230,7 @@ namespace MWBase virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0; + virtual void startTraining(MWWorld::Ptr actor) = 0; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 3a51ed2b6..063794eba 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -801,6 +801,9 @@ namespace MWDialogue if (services & ESM::NPC::Spellmaking) windowServices |= MWGui::DialogueWindow::Service_CreateSpells; + if (services & ESM::NPC::Training) + windowServices |= MWGui::DialogueWindow::Service_Training; + if (services & ESM::NPC::Enchanting) windowServices |= MWGui::DialogueWindow::Service_Enchant; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index d03724628..d5b4ca672 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -147,6 +147,11 @@ void DialogueWindow::onSelectTopic(std::string topic) mWindowManager.pushGuiMode(GM_Enchanting); mWindowManager.startEnchanting (mPtr); } + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString()) + { + mWindowManager.pushGuiMode(GM_Training); + mWindowManager.startTraining (mPtr); + } else MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -181,6 +186,9 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mServices & Service_Enchant) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString()); + if (mServices & Service_Training) + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString()); + if (anyService) mTopicsList->addSeparator(); diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index acbe75eed..1592e49ee 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -57,7 +57,8 @@ namespace MWGui Service_Trade = 0x01, Service_BuySpells = 0x02, Service_CreateSpells = 0x04, - Service_Enchant = 0x08 + Service_Enchant = 0x08, + Service_Training = 0x10 }; protected: diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 7fd033f5e..e594a5d0b 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -24,6 +24,7 @@ namespace MWGui GM_SpellBuying, GM_SpellCreation, GM_Enchanting, + GM_Training, GM_Levelup, diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp new file mode 100644 index 000000000..536b3a3a6 --- /dev/null +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -0,0 +1,152 @@ +#include "trainingwindow.hpp" + +#include + +#include + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "../mwmechanics/npcstats.hpp" + +#include "inventorywindow.hpp" +#include "tradewindow.hpp" +#include "tooltips.hpp" + +namespace MWGui +{ + + TrainingWindow::TrainingWindow(MWBase::WindowManager &parWindowManager) + : WindowBase("openmw_trainingwindow.layout", parWindowManager) + , mFadeTimeRemaining(0) + { + getWidget(mTrainingOptions, "TrainingOptions"); + getWidget(mCancelButton, "CancelButton"); + getWidget(mPlayerGold, "PlayerGold"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked); + } + + void TrainingWindow::open() + { + center(); + } + + void TrainingWindow::startTraining (MWWorld::Ptr actor) + { + mPtr = actor; + + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + + MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor); + + // NPC can train you in his best 3 skills + std::vector< std::pair > bestSkills; + bestSkills.push_back (std::make_pair(-1, -1)); + bestSkills.push_back (std::make_pair(-1, -1)); + bestSkills.push_back (std::make_pair(-1, -1)); + + for (int i=0; i bestSkills[j].second) + { + if (j<2) + { + bestSkills[j+1] = bestSkills[j]; + } + bestSkills[j] = std::make_pair(i, value); + break; + } + } + } + + MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator (); + MyGUI::Gui::getInstance ().destroyWidgets (widgets); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + 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 (); + + std::string skin = (price > mWindowManager.getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton"; + + MyGUI::Button* button = mTrainingOptions->createWidget(skin, + MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); + + button->setUserData(bestSkills[i].first); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); + + button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[bestSkills[i].first] + "} - " + boost::lexical_cast(price)); + + button->setSize(button->getTextSize ().width+12, button->getSize().height); + + ToolTips::createSkillToolTip (button, bestSkills[i].first); + } + + center(); + } + + void TrainingWindow::onReferenceUnavailable () + { + mWindowManager.removeGuiMode(GM_Training); + } + + void TrainingWindow::onCancelButtonClicked (MyGUI::Widget *sender) + { + mWindowManager.removeGuiMode (GM_Training); + } + + void TrainingWindow::onTrainingSelected (MyGUI::Widget *sender) + { + int skillId = *sender->getUserData(); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); + + /// \todo mercantile skill + int price = pcStats.getSkill (skillId).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt (); + + if (mWindowManager.getInventoryWindow()->getPlayerGold() *playerRef = player.get(); + const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( + playerRef->base->mClass); + pcStats.increaseSkill (skillId, *class_, true); + + // remove gold + mWindowManager.getTradeWindow()->addOrRemoveGold(-price); + + // go back to game mode + mWindowManager.removeGuiMode (GM_Training); + mWindowManager.removeGuiMode (GM_Dialogue); + + // advance time + MWBase::Environment::get().getWorld ()->advanceTime (2); + + MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25); + mFadeTimeRemaining = 0.5; + } + + void TrainingWindow::onFrame(float dt) + { + if (mFadeTimeRemaining <= 0) + return; + + mFadeTimeRemaining -= dt; + + if (mFadeTimeRemaining <= 0) + MWBase::Environment::get().getWorld ()->getFader()->fadeIn(0.25); + } +} diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp new file mode 100644 index 000000000..f2ef1714e --- /dev/null +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -0,0 +1,36 @@ +#ifndef MWGUI_TRAININGWINDOW_H +#define MWGUI_TRAININGWINDOW_H + +#include "window_base.hpp" +#include "referenceinterface.hpp" + +namespace MWGui +{ + + class TrainingWindow : public WindowBase, public ReferenceInterface + { + public: + TrainingWindow(MWBase::WindowManager& parWindowManager); + + virtual void open(); + + void startTraining(MWWorld::Ptr actor); + + void onFrame(float dt); + + protected: + virtual void onReferenceUnavailable (); + + void onCancelButtonClicked (MyGUI::Widget* sender); + void onTrainingSelected(MyGUI::Widget* sender); + + MyGUI::Widget* mTrainingOptions; + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; + + float mFadeTimeRemaining; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 906bb2ca7..ea5c5b6cb 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -48,6 +48,7 @@ #include "waitdialog.hpp" #include "spellcreationdialog.hpp" #include "enchantingdialog.hpp" +#include "trainingwindow.hpp" using namespace MWGui; @@ -79,6 +80,7 @@ WindowManager::WindowManager( , mWaitDialog(NULL) , mSpellCreationDialog(NULL) , mEnchantingDialog(NULL) + , mTrainingWindow(NULL) , mPlayerClass() , mPlayerName() , mPlayerRaceId() @@ -161,6 +163,7 @@ WindowManager::WindowManager( mWaitDialog = new WaitDialog(*this); mSpellCreationDialog = new SpellCreationDialog(*this); mEnchantingDialog = new EnchantingDialog(*this); + mTrainingWindow = new TrainingWindow(*this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -218,6 +221,7 @@ WindowManager::~WindowManager() delete mWaitDialog; delete mSpellCreationDialog; delete mEnchantingDialog; + delete mTrainingWindow; cleanupGarbage(); @@ -269,6 +273,7 @@ void WindowManager::updateVisible() mWaitDialog->setVisible(false); mSpellCreationDialog->setVisible(false); mEnchantingDialog->setVisible(false); + mTrainingWindow->setVisible(false); mHud->setVisible(true); @@ -375,6 +380,9 @@ void WindowManager::updateVisible() case GM_Enchanting: mEnchantingDialog->setVisible(true); break; + case GM_Training: + mTrainingWindow->setVisible(true); + break; case GM_InterMessageBox: break; case GM_Journal: @@ -574,6 +582,9 @@ void WindowManager::onFrame (float frameDuration) mHud->onFrame(frameDuration); + mTrainingWindow->onFrame (frameDuration); + + mTrainingWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable(); mTradeWindow->checkReferenceAvailable(); mSpellBuyingWindow->checkReferenceAvailable(); @@ -993,3 +1004,8 @@ void WindowManager::startEnchanting (MWWorld::Ptr actor) { mEnchantingDialog->startEnchanting (actor); } + +void WindowManager::startTraining(MWWorld::Ptr actor) +{ + mTrainingWindow->startTraining(actor); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index d3890f635..8b0e744db 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -66,6 +66,7 @@ namespace MWGui class WaitDialog; class SpellCreationDialog; class EnchantingDialog; + class TrainingWindow; class WindowManager : public MWBase::WindowManager { @@ -215,6 +216,7 @@ namespace MWGui virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor); + virtual void startTraining(MWWorld::Ptr actor); private: OEngine::GUI::MyGUIManager *mGuiManager; @@ -245,6 +247,7 @@ namespace MWGui WaitDialog* mWaitDialog; SpellCreationDialog* mSpellCreationDialog; EnchantingDialog* mEnchantingDialog; + TrainingWindow* mTrainingWindow; CharacterCreation* mCharGen; diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index 4344397c7..7b028e1d0 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -54,6 +54,6 @@ namespace MWSound #ifndef DEFAULT_DECODER #define DEFAULT_DECODER (::MWSound::FFmpeg_Decoder) #endif -}; +} #endif diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 8e55b6889..3128fe0c6 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -18,8 +18,6 @@ namespace ESM { // These are probabilities char mHello, mU1, mFight, mFlee, mAlarm, mU2, mU3, mU4; - // The last u's might be the skills that this NPC can train you - // in? int mServices; // See the Services enum }; // 12 bytes diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index a33d59ef6..1354271d5 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -78,6 +78,7 @@ set(MYGUI_FILES openmw_spellcreation_dialog.layout openmw_edit_effect.layout openmw_enchanting_dialog.layout + openmw_trainingwindow.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout new file mode 100644 index 000000000..e9855a33b --- /dev/null +++ b/files/mygui/openmw_trainingwindow.layout @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 125315ebe7115bbe3aad2da6a215c7a1a6539f90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:21:24 +0200 Subject: [PATCH 046/255] remove a cout --- apps/openmw/mwgui/dialogue.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index f0d15aed5..23d2197b7 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -140,10 +140,8 @@ void DialogueWindow::onSelectTopic(std::string topic) } else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString()) { - std::cout << "travel!"; mWindowManager.pushGuiMode(GM_Travel); mWindowManager.getTravelWindow()->startTravel(mPtr); - //mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); } else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellMakingMenuTitle")->getString()) { From e80394c0b57652b95d6899de361a96ef2aaef646 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:48:29 +0200 Subject: [PATCH 047/255] fix training limit --- apps/openmw/mwgui/trainingwindow.cpp | 7 +++++++ files/mygui/openmw_trainingwindow.layout | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 536b3a3a6..af61b3487 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -119,6 +119,13 @@ namespace MWGui if (mWindowManager.getInventoryWindow()->getPlayerGold()()); + return; + } + // increase skill MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout index e9855a33b..aa39d0a5c 100644 --- a/files/mygui/openmw_trainingwindow.layout +++ b/files/mygui/openmw_trainingwindow.layout @@ -21,7 +21,7 @@ - + From 0a19b5603103bfb6a4f81a9112b4122a59e31fe8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:49:49 +0200 Subject: [PATCH 048/255] fix gold label --- files/mygui/openmw_trainingwindow.layout | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/files/mygui/openmw_trainingwindow.layout b/files/mygui/openmw_trainingwindow.layout index aa39d0a5c..c58bd0ab3 100644 --- a/files/mygui/openmw_trainingwindow.layout +++ b/files/mygui/openmw_trainingwindow.layout @@ -17,9 +17,8 @@ - + - From 5fbca239dd4da63fecd0634674d7e80e43e4e0b6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:02:06 +0200 Subject: [PATCH 049/255] Issue #61: potion creation (1st part; still missing some implementations) --- apps/openmw/mwmechanics/alchemy.cpp | 308 +++++++++++++++++++++++++++- apps/openmw/mwmechanics/alchemy.hpp | 62 +++++- components/esm/loadmgef.hpp | 2 + 3 files changed, 369 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 6d3deed3c..c8a3cf162 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,15 +1,259 @@ #include "alchemy.hpp" +#include + #include #include +#include +#include +#include +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/cellstore.hpp" + +#include "magiceffects.hpp" +#include "creaturestats.hpp" +#include "npcstats.hpp" + +std::set MWMechanics::Alchemy::listEffects() const +{ + std::set effects; + + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + { + if (!iter->isEmpty()) + { + const MWWorld::LiveCellRef *ingredient = iter->get(); + + for (int i=0; i<4; ++i) + if (ingredient->base->mData.mEffectID[i]!=-1) + effects.insert (EffectKey ( + ingredient->base->mData.mEffectID[i], ingredient->base->mData.mSkills[i]!=-1 ? + ingredient->base->mData.mSkills[i] : ingredient->base->mData.mAttributes[i])); + } + } + + return effects; +} + +void MWMechanics::Alchemy::filterEffects (std::set& effects) const +{ + std::set::iterator iter = effects.begin(); + + while (iter!=effects.end()) + { + bool remove = false; + + const EffectKey& key = *iter; + + { // dodge pointless g++ warning + for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + { + bool found = false; + + const MWWorld::LiveCellRef *ingredient = iter->get(); + + for (int i=0; i<4; ++i) + if (key.mId==ingredient->base->mData.mEffectID[i] && + (key.mArg==ingredient->base->mData.mSkills[i] || + key.mArg==ingredient->base->mData.mAttributes[i])) + { + found = true; + break; + } + + if (!found) + { + remove = true; + break; + } + } + } + + if (remove) + effects.erase (iter++); + else + ++iter; + } +} + +void MWMechanics::Alchemy::applyTools (int flags, float& value) const +{ + bool magnitude = !(flags & ESM::MagicEffect::NoMagnitude); + bool duration = !(flags & ESM::MagicEffect::NoDuration); + bool negative = flags & (ESM::MagicEffect::Negative | ESM::MagicEffect::Negative2); + + int tool = negative ? ESM::Apparatus::Retort : ESM::Apparatus::Albemic; + + int setup = 0; + + if (!mTools[tool].isEmpty() && !mTools[ESM::Apparatus::Calcinator].isEmpty()) + setup = 1; + else if (!mTools[tool].isEmpty()) + setup = 2; + else if (!mTools[ESM::Apparatus::Calcinator].isEmpty()) + setup = 3; + else + return; + + float toolQuality = setup==1 || setup==2 ? mTools[tool].get()->base->mData.mQuality : 0; + float calcinatorQuality = setup==1 || setup==3 ? + mTools[ESM::Apparatus::Calcinator].get()->base->mData.mQuality : 0; + + float quality = 1; + + switch (setup) + { + case 1: + + quality = negative ? 2 * toolQuality + 3 * calcinatorQuality : + (magnitude && duration ? + 2 * toolQuality + calcinatorQuality : 2/3.0 * (toolQuality + calcinatorQuality) + 0.5); + break; + + case 2: + + quality = negative ? 1+toolQuality : (magnitude && duration ? toolQuality : toolQuality + 0.5); + break; + + case 3: + + quality = magnitude && duration ? calcinatorQuality : calcinatorQuality + 0.5; + break; + } + + if (setup==3 || !negative) + { + value += quality; + } + else + { + if (quality==0) + throw std::runtime_error ("invalid derived alchemy apparatus quality"); + + value /= quality; + } +} + +void MWMechanics::Alchemy::updateEffects() +{ + mEffects.clear(); + + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + if (ingredients<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) + return; + + // find effects + std::set effects (listEffects()); + filterEffects (effects); + + // general alchemy factor + float x = getChance(); + + x *= mTools[ESM::Apparatus::MortarPestle].get()->base->mData.mQuality; + x *= MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionStrengthMult")->getFloat(); + + // build quantified effect list + for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) + { + const ESM::MagicEffect *magicEffect = + MWBase::Environment::get().getWorld()->getStore().magicEffects.find (iter->mId); + + if (magicEffect->mData.mBaseCost<=0) + throw std::runtime_error ("invalid base cost for magic effect " + iter->mId); + + float fPotionT1MagMul = + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMul")->getFloat(); + + if (fPotionT1MagMul<=0) + throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); + + float fPotionT1DurMult = + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1DurMult")->getFloat(); + + if (fPotionT1DurMult<=0) + throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); + + float magnitude = magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude ? + 1 : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; + float duration = magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration ? + 1 : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; + + if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude)) + applyTools (magicEffect->mData.mFlags, magnitude); + + if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration)) + applyTools (magicEffect->mData.mFlags, duration); + + duration = static_cast (duration+0.5); + magnitude = static_cast (magnitude+0.5); + + if (magnitude>0 && duration>0) + { + ESM::ENAMstruct effect; + effect.mEffectID = iter->mId; + + effect.mSkill = effect.mAttribute = iter->mArg; // somewhat hack-ish, but should work + + effect.mRange = 0; + effect.mArea = 0; + + effect.mDuration = duration; + effect.mMagnMin = effect.mMagnMax = magnitude; + + mEffects.push_back (effect); + } + } +} + +const ESM::Potion *MWMechanics::Alchemy::getRecord() const +{ + +} + +void MWMechanics::Alchemy::removeIngredients() +{ + +} + +void MWMechanics::Alchemy::addPotion (const std::string& name) +{ + +} + +void MWMechanics::Alchemy::increaseSkill() +{ + +} + +float MWMechanics::Alchemy::getChance() const +{ + const CreatureStats& creatureStats = MWWorld::Class::get (mAlchemist).getCreatureStats (mAlchemist); + const NpcStats& npcStats = MWWorld::Class::get (mAlchemist).getNpcStats (mAlchemist); + + return + (npcStats.getSkill (ESM::Skill::Alchemy).getModified() + + 0.1 * creatureStats.getAttribute (1).getModified() + + 0.1 * creatureStats.getAttribute (7).getModified()); +} void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { - mNpc = npc; + mAlchemist = npc; mIngredients.resize (4); @@ -19,6 +263,8 @@ void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); + mEffects.clear(); + MWWorld::ContainerStore& store = MWWorld::Class::get (npc).getContainerStore (npc); for (MWWorld::ContainerStoreIterator iter (store.begin (MWWorld::ContainerStore::Type_Apparatus)); @@ -61,9 +307,10 @@ MWMechanics::Alchemy::TIngredientsIterator MWMechanics::Alchemy::endIngredients( void MWMechanics::Alchemy::clear() { - mNpc = MWWorld::Ptr(); + mAlchemist = MWWorld::Ptr(); mTools.clear(); mIngredients.clear(); + mEffects.clear(); } int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) @@ -86,6 +333,8 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) return -1; mIngredients[slot] = ingredient; + + updateEffects(); return slot; } @@ -93,6 +342,61 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) void MWMechanics::Alchemy::removeIngredient (int index) { if (index>=0 && index (mIngredients.size())) + { mIngredients[index] = MWWorld::Ptr(); + updateEffects(); + } } +MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::beginEffects() const +{ + return mEffects.begin(); +} + +MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::endEffects() const +{ + return mEffects.end(); +} + +std::string MWMechanics::Alchemy::getPotionName() const +{ + if (const ESM::Potion *potion = getRecord()) + return potion->mName; + + return ""; +} + +MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& name) +{ + if (mTools[ESM::Apparatus::MortarPestle].isEmpty()) + return Result_NoMortarAndPestle; + + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + if (ingredients<2) + return Result_LessThanTwoIngredients; + + if (name.empty() && getPotionName().empty()) + return Result_NoName; + + if (beginEffects()==endEffects()) + return Result_NoEffects; + + if (getChance() (RAND_MAX)*100) + { + removeIngredients(); + return Result_RandomFailure; + } + + addPotion (name); + + removeIngredients(); + + increaseSkill(); + + return Result_Success; +} diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 7c3cf9e68..73fa7eb18 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -2,11 +2,16 @@ #define GAME_MWMECHANICS_ALCHEMY_H #include +#include + +#include #include "../mwworld/ptr.hpp" namespace MWMechanics { + struct EffectKey; + /// \brief Potion creation via alchemy skill class Alchemy { @@ -17,13 +22,54 @@ namespace MWMechanics typedef std::vector TIngredientsContainer; typedef TIngredientsContainer::const_iterator TIngredientsIterator; + + typedef std::vector TEffectsContainer; + typedef TEffectsContainer::const_iterator TEffectsIterator; + + enum Result + { + Result_Success, + + Result_NoMortarAndPestle, + Result_LessThanTwoIngredients, + Result_NoName, + Result_NoEffects, + Result_RandomFailure + }; private: - MWWorld::Ptr mNpc; + MWWorld::Ptr mAlchemist; TToolsContainer mTools; TIngredientsContainer mIngredients; + TEffectsContainer mEffects; + std::set listEffects() const; + ///< List all effects of all used ingredients. + + void filterEffects (std::set& effects) const; + ///< Filter out effects not shared by all ingredients. + + void applyTools (int flags, float& value) const; + + void updateEffects(); + + const ESM::Potion *getRecord() const; + ///< Return existing recrod for created potion (may return 0) + + void removeIngredients(); + ///< Remove selected ingredients from alchemist's inventory, cleanup selected ingredients and + /// update effect list accordingly. + + void addPotion (const std::string& name); + ///< Add a potion to the alchemist's inventory. + + void increaseSkill(); + ///< Increase alchemist's skill. + + float getChance() const; + ///< Return chance of success. + public: void setAlchemist (const MWWorld::Ptr& npc); @@ -49,6 +95,20 @@ namespace MWMechanics void removeIngredient (int index); ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). + + TEffectsIterator beginEffects() const; + + TEffectsIterator endEffects() const; + + std::string getPotionName() const; + ///< Return the name of the potion that would be created when calling create (if a record for such + /// a potion already exists) or return an empty string. + + Result create (const std::string& name); + ///< Try to create a potion from the ingredients, place it in the inventory of the alchemist and + /// adjust the skills of the alchemist accordingly. + /// \param name must not be an empty string, unless there is already a potion record ( + /// getPotionName() does not return an empty string). }; } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 861f66be0..a763576c3 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -14,6 +14,8 @@ struct MagicEffect enum Flags { NoDuration = 0x4, + NoMagnitude = 0x8, + Negative2 = 0x10, SpellMaking = 0x0200, Enchanting = 0x0400, Negative = 0x0800 // A harmful effect. Will determine whether From 3fe0a73cf24349a8a8abff9c27724dda9812e330 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:38:38 +0200 Subject: [PATCH 050/255] Issue #61: increase alchemy skill on successful potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index bf39afefb..3a5efbaaf 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -237,7 +237,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) void MWMechanics::Alchemy::increaseSkill() { - + MWWorld::Class::get (mAlchemist).skillUsageSucceeded (mAlchemist, ESM::Skill::Alchemy, 0); } float MWMechanics::Alchemy::getChance() const From 3c71378fade9b52cd011034425aa7c585f818444 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:41:57 +0200 Subject: [PATCH 051/255] Issue 61: improved ingredients handling in alchemy and documenation --- apps/openmw/mwmechanics/alchemy.cpp | 29 ++++++++++++++--------------- apps/openmw/mwmechanics/alchemy.hpp | 4 ++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 3a5efbaaf..d59d71306 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -148,13 +148,7 @@ void MWMechanics::Alchemy::updateEffects() { mEffects.clear(); - int ingredients = 0; - - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) - if (!iter->isEmpty()) - ++ingredients; - - if (ingredients<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) + if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) return; // find effects @@ -251,6 +245,17 @@ float MWMechanics::Alchemy::getChance() const + 0.1 * creatureStats.getAttribute (7).getModified()); } +int MWMechanics::Alchemy::countIngredients() const +{ + int ingredients = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + ++ingredients; + + return ingredients; +} + void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { mAlchemist = npc; @@ -370,14 +375,8 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na { if (mTools[ESM::Apparatus::MortarPestle].isEmpty()) return Result_NoMortarAndPestle; - - int ingredients = 0; - - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) - if (!iter->isEmpty()) - ++ingredients; - - if (ingredients<2) + + if (countIngredients()<2) return Result_LessThanTwoIngredients; if (name.empty() && getPotionName().empty()) diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 73fa7eb18..52af29912 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -70,6 +70,8 @@ namespace MWMechanics float getChance() const; ///< Return chance of success. + int countIngredients() const; + public: void setAlchemist (const MWWorld::Ptr& npc); @@ -77,10 +79,12 @@ namespace MWMechanics /// there is no alchemist (alchemy session has ended). TToolsIterator beginTools() const; + ///< \attention Iterates over tool slots, not over tools. Some of the slots may be empty. TToolsIterator endTools() const; TIngredientsIterator beginIngredients() const; + ///< \attention Iterates over ingredient slots, not over ingredients. Some of the slots may be empty. TIngredientsIterator endIngredients() const; From f5caf227b23e602dba92da031648c78eeee84450 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 14:47:23 +0200 Subject: [PATCH 052/255] Issue #61: remove ingredients on potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index d59d71306..f59d87ae7 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -221,7 +221,21 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord() const void MWMechanics::Alchemy::removeIngredients() { - + bool needsUpdate = false; + + for (TIngredientsContainer::iterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + if (!iter->isEmpty()) + { + iter->getRefData().setCount (iter->getRefData().getCount()-1); + if (iter->getRefData().getCount()<1) + { + needsUpdate = true; + *iter = MWWorld::Ptr(); + } + } + + if (needsUpdate) + updateEffects(); } void MWMechanics::Alchemy::addPotion (const std::string& name) From 1864dbe0311da194b720c92da4fb9f4b91f91743 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 18 Oct 2012 15:33:27 +0200 Subject: [PATCH 053/255] Issue #61: potion creation --- apps/openmw/mwmechanics/alchemy.cpp | 72 +++++++++++++++++++++++++++++ apps/openmw/mwmechanics/alchemy.hpp | 1 + 2 files changed, 73 insertions(+) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index f59d87ae7..e37a30210 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -1,6 +1,7 @@ #include "alchemy.hpp" +#include #include #include @@ -19,6 +20,7 @@ #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/manualref.hpp" #include "magiceffects.hpp" #include "creaturestats.hpp" @@ -147,6 +149,7 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const void MWMechanics::Alchemy::updateEffects() { mEffects.clear(); + mValue = 0; if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) return; @@ -161,6 +164,10 @@ void MWMechanics::Alchemy::updateEffects() x *= mTools[ESM::Apparatus::MortarPestle].get()->base->mData.mQuality; x *= MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionStrengthMult")->getFloat(); + // value + mValue = static_cast ( + x * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("iAlchemyMod")->getFloat()); + // build quantified effect list for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) { @@ -216,7 +223,39 @@ void MWMechanics::Alchemy::updateEffects() const ESM::Potion *MWMechanics::Alchemy::getRecord() const { + for (ESMS::RecListWithIDT::MapType::const_iterator iter ( + MWBase::Environment::get().getWorld()->getStore().potions.list.begin()); + iter!=MWBase::Environment::get().getWorld()->getStore().potions.list.end(); ++iter) + { + if (iter->second.mEffects.mList.size()!=mEffects.size()) + continue; + + bool mismatch = false; + for (int i=0; i (iter->second.mEffects.mList.size()); ++iter) + { + const ESM::ENAMstruct& first = iter->second.mEffects.mList[i]; + const ESM::ENAMstruct& second = mEffects[i]; + + if (first.mEffectID!=second.mEffectID || + first.mArea!=second.mArea || + first.mRange!=second.mRange || + first.mSkill!=second.mSkill || + first.mAttribute!=second.mAttribute || + first.mMagnMin!=second.mMagnMin || + first.mMagnMax!=second.mMagnMax || + first.mDuration!=second.mDuration) + { + mismatch = true; + break; + } + } + + if (!mismatch) + return &iter->second; + } + + return 0; } void MWMechanics::Alchemy::removeIngredients() @@ -240,7 +279,40 @@ void MWMechanics::Alchemy::removeIngredients() void MWMechanics::Alchemy::addPotion (const std::string& name) { + const ESM::Potion *record = getRecord(); + + if (!record) + { + ESM::Potion newRecord; + + newRecord.mData.mWeight = 0; + + for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + if (!iter->isEmpty()) + newRecord.mData.mWeight += iter->get()->base->mData.mWeight; + + newRecord.mData.mWeight /= countIngredients(); + + newRecord.mData.mValue = mValue; + newRecord.mData.mAutoCalc = 0; + + newRecord.mName = name; + int index = static_cast (std::rand()/static_cast (RAND_MAX)*6); + assert (index>=0 && index<6); + + static const char *name[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" }; + + newRecord.mModel = "m\\misc_potion_" + std::string (name[index]) + "_01.nif"; + newRecord.mIcon = "m\\tx_potion_" + std::string (name[index]) + "_01.dds"; + + newRecord.mEffects.mList = mEffects; + + record = MWBase::Environment::get().getWorld()->createRecord (newRecord).second; + } + + MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId); + MWWorld::Class::get (mAlchemist).getContainerStore (mAlchemist).add (ref.getPtr()); } void MWMechanics::Alchemy::increaseSkill() diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 52af29912..7f3e2c0ea 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -43,6 +43,7 @@ namespace MWMechanics TToolsContainer mTools; TIngredientsContainer mIngredients; TEffectsContainer mEffects; + int mValue; std::set listEffects() const; ///< List all effects of all used ingredients. From 28cc480ce1d4175d54c1971d2449c0066c27d23a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 18 Oct 2012 22:21:39 +0200 Subject: [PATCH 054/255] fix some alchemy issues and make the gui use the new implementation --- apps/openmw/engine.cpp | 15 +- apps/openmw/mwgui/alchemywindow.cpp | 204 +++++----------------------- apps/openmw/mwgui/alchemywindow.hpp | 12 +- apps/openmw/mwgui/tooltips.cpp | 10 +- apps/openmw/mwmechanics/alchemy.cpp | 15 +- apps/openmw/mwworld/worldimp.cpp | 18 +-- 6 files changed, 58 insertions(+), 216 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index adbfca129..3867cb76a 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -424,21 +424,10 @@ void OMW::Engine::activate() if (handle.empty()) return; - // the faced handle is not updated immediately, so on a cell change it might - // point to an object that doesn't exist anymore - // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case - MWWorld::Ptr ptr; - try - { - ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); - if (ptr.isEmpty()) - return; - } - catch (std::runtime_error&) - { + if (ptr.isEmpty()) return; - } MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index cef5d6e2e..192bbd090 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -70,142 +70,44 @@ namespace MWGui void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender) { + std::string name = mNameEdit->getCaption(); + boost::algorithm::trim(name); + + MWMechanics::Alchemy::Result result = mAlchemy.create (mNameEdit->getCaption ()); + + if (result == MWMechanics::Alchemy::Result_NoName) + { + mWindowManager.messageBox("#{sNotifyMessage37}", std::vector()); + return; + } + // check if mortar & pestle is available (always needed) - /// \todo check albemic, calcinator, retort (sometimes needed) - if (!mApparatus[0]->isUserString("ToolTipType")) + if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle) { mWindowManager.messageBox("#{sNotifyMessage45}", std::vector()); return; } // make sure 2 or more ingredients were selected - int numIngreds = 0; - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - ++numIngreds; - - if (numIngreds < 2) + if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients) { mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector()); return; } - // make sure a name was entered - std::string name = mNameEdit->getCaption(); - boost::algorithm::trim(name); - if (name == "") - { - mWindowManager.messageBox("#{sNotifyMessage37}", std::vector()); - return; - } - - // if there are no created effects, the potion will always fail (but the ingredients won't be destroyed) - if (mEffects.empty()) + if (result == MWMechanics::Alchemy::Result_NoEffects) { mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); return; } - if (rand() % 2 == 0) /// \todo + if (result == MWMechanics::Alchemy::Result_Success) { - ESM::Potion newPotion; - newPotion.mName = mNameEdit->getCaption(); - ESM::EffectList effects; - for (unsigned int i=0; i<4; ++i) - { - if (mEffects.size() >= i+1) - { - ESM::ENAMstruct effect; - effect.mEffectID = mEffects[i].mEffectID; - effect.mArea = 0; - effect.mRange = ESM::RT_Self; - effect.mSkill = mEffects[i].mSkill; - effect.mAttribute = mEffects[i].mAttribute; - effect.mMagnMin = 1; /// \todo - effect.mMagnMax = 10; /// \todo - effect.mDuration = 60; /// \todo - effects.mList.push_back(effect); - } - } - - // UESP Wiki / Morrowind:Alchemy - // "The weight of a potion is an average of the weight of the ingredients, rounded down." - // note by scrawl: not rounding down here, I can't imagine a created potion to - // have 0 weight when using ingredients with 0.1 weight respectively - float weight = 0; - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - weight += mIngredients[i]->getUserData()->get()->base->mData.mWeight; - newPotion.mData.mWeight = weight / float(numIngreds); - - newPotion.mData.mValue = 100; /// \todo - newPotion.mEffects = effects; - // pick a random mesh and icon - std::vector names; - /// \todo is the mesh/icon dependent on alchemy skill? - names.push_back("standard"); - names.push_back("bargain"); - names.push_back("cheap"); - names.push_back("fresh"); - names.push_back("exclusive"); - names.push_back("quality"); - int random = rand() % names.size(); - newPotion.mModel = "m\\misc_potion_" + names[random ] + "_01.nif"; - newPotion.mIcon = "m\\tx_potion_" + names[random ] + "_01.dds"; - - // check if a similiar potion record exists already - bool found = false; - std::string objectId; - typedef std::map PotionMap; - PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list; - for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it) - { - if (found) break; - - if (it->second.mData.mValue == newPotion.mData.mValue - && it->second.mData.mWeight == newPotion.mData.mWeight - && it->second.mName == newPotion.mName - && it->second.mEffects.mList.size() == newPotion.mEffects.mList.size()) - { - // check effects - for (unsigned int i=0; i < it->second.mEffects.mList.size(); ++i) - { - const ESM::ENAMstruct& a = it->second.mEffects.mList[i]; - const ESM::ENAMstruct& b = newPotion.mEffects.mList[i]; - if (a.mEffectID == b.mEffectID - && a.mArea == b.mArea - && a.mRange == b.mRange - && a.mSkill == b.mSkill - && a.mAttribute == b.mAttribute - && a.mMagnMin == b.mMagnMin - && a.mMagnMax == b.mMagnMax - && a.mDuration == b.mDuration) - { - found = true; - objectId = it->first; - break; - } - } - } - } - - if (!found) - { - std::pair result = MWBase::Environment::get().getWorld()->createRecord(newPotion); - objectId = result.first; - } - - // create a reference and add it to player inventory - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId); - MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); - ref.getPtr().getRefData().setCount(1); - store.add(ref.getPtr()); - mWindowManager.messageBox("#{sPotionSuccess}", std::vector()); MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f); } - else + else if (result == MWMechanics::Alchemy::Result_RandomFailure) { // potion failed mWindowManager.messageBox("#{sNotifyMessage8}", std::vector()); @@ -229,7 +131,7 @@ namespace MWGui { openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr setFilter (ContainerBase::Filter_Ingredients); - + mAlchemy.setAlchemist (mPtr); int index = 0; @@ -277,6 +179,9 @@ namespace MWGui if (!mIngredients[i]->isUserString("ToolTipType")) { add = mIngredients[i]; + + mAlchemy.addIngredient(item); + break; } @@ -306,8 +211,6 @@ namespace MWGui void AlchemyWindow::update() { - Widgets::SpellEffectList effects; - for (int i=0; i<4; ++i) { MyGUI::ImageBox* ingredient = mIngredients[i]; @@ -315,19 +218,6 @@ namespace MWGui if (!ingredient->isUserString("ToolTipType")) continue; - // add the effects of this ingredient to list of effects - MWWorld::LiveCellRef* ref = ingredient->getUserData()->get(); - for (int i=0; i<4; ++i) - { - if (ref->base->mData.mEffectID[i] < 0) - continue; - MWGui::Widgets::SpellEffectParams params; - params.mEffectID = ref->base->mData.mEffectID[i]; - params.mAttribute = ref->base->mData.mAttributes[i]; - params.mSkill = ref->base->mData.mSkills[i]; - effects.push_back(params); - } - // update ingredient count labels if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); @@ -340,50 +230,14 @@ namespace MWGui text->setCaption(getCountString(ingredient->getUserData()->getRefData().getCount())); } - // now remove effects that are only present once - Widgets::SpellEffectList::iterator it = effects.begin(); - while (it != effects.end()) + std::vector effects; + ESM::EffectList list; + list.mList = effects; + for (MWMechanics::Alchemy::TEffectsIterator it = mAlchemy.beginEffects (); it != mAlchemy.endEffects (); ++it) { - Widgets::SpellEffectList::iterator next = it; - ++next; - bool found = false; - for (; next != effects.end(); ++next) - { - if (*next == *it) - found = true; - } - - if (!found) - it = effects.erase(it); - else - ++it; + list.mList.push_back(*it); } - // now remove duplicates, and don't allow more than 4 effects - Widgets::SpellEffectList old = effects; - effects.clear(); - int i=0; - for (Widgets::SpellEffectList::iterator it = old.begin(); - it != old.end(); ++it) - { - bool found = false; - for (Widgets::SpellEffectList::iterator it2 = effects.begin(); - it2 != effects.end(); ++it2) - { - // MW considers all "foritfy attribute" effects as the same effect. See the - // "Can't create multi-state boost potions" discussion on http://www.uesp.net/wiki/Morrowind_talk:Alchemy - // thus, we are only checking effectID here and not attribute or skill - if (it2->mEffectID == it->mEffectID) - found = true; - } - if (!found && i<4) - { - ++i; - effects.push_back(*it); - } - } - mEffects = effects; - while (mEffectsBox->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0)); @@ -391,7 +245,9 @@ namespace MWGui Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget ("MW_StatName", coord, MyGUI::Align::Left | MyGUI::Align::Top); effectsWidget->setWindowManager(&mWindowManager); - effectsWidget->setEffectList(effects); + + Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list); + effectsWidget->setEffectList(_list); std::vector effectItems; effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0); @@ -404,5 +260,9 @@ namespace MWGui static_cast(ingredient)->setImageTexture(""); if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); + + for (int i=0; i<4; ++i) + if (mIngredients[i] == ingredient) + mAlchemy.removeIngredient (i); } } diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 179cdd174..5f84e73e9 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -26,8 +26,6 @@ namespace MWGui MyGUI::EditBox* mNameEdit; - Widgets::SpellEffectList mEffects; // effects of created potion - void onCancelButtonClicked(MyGUI::Widget* _sender); void onCreateButtonClicked(MyGUI::Widget* _sender); void onIngredientSelected(MyGUI::Widget* _sender); @@ -41,12 +39,12 @@ namespace MWGui void update(); - private: - - MWMechanics::Alchemy mAlchemy; + private: - std::vector mApparatus; - std::vector mIngredients; + MWMechanics::Alchemy mAlchemy; + + std::vector mApparatus; + std::vector mIngredients; }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 39afba749..5256028eb 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -79,14 +79,10 @@ void ToolTips::onFrame(float frameDuration) || (mWindowManager->getMode() == GM_Inventory))) { std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - try - { - mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); - } - catch (std::exception /* & e */) - { + + mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); + if (mFocusObject.isEmpty ()) return; - } MyGUI::IntSize tooltipSize = getToolTipViaPtr(true); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index e37a30210..583a3c18e 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -62,6 +62,9 @@ void MWMechanics::Alchemy::filterEffects (std::set& effects) const { bool found = false; + if (iter->isEmpty()) + continue; + const MWWorld::LiveCellRef *ingredient = iter->get(); for (int i=0; i<4; ++i) @@ -178,7 +181,7 @@ void MWMechanics::Alchemy::updateEffects() throw std::runtime_error ("invalid base cost for magic effect " + iter->mId); float fPotionT1MagMul = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMul")->getFloat(); + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionT1MagMult")->getFloat(); if (fPotionT1MagMul<=0) throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); @@ -189,15 +192,15 @@ void MWMechanics::Alchemy::updateEffects() if (fPotionT1DurMult<=0) throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); - float magnitude = magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude ? + float magnitude = magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude ? 1 : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; - float duration = magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration ? + float duration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ? 1 : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; - if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoMagnitude)) + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) applyTools (magicEffect->mData.mFlags, magnitude); - if (!(magicEffect->mData.mFlags && ESM::MagicEffect::NoDuration)) + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) applyTools (magicEffect->mData.mFlags, duration); duration = static_cast (duration+0.5); @@ -471,7 +474,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na if (beginEffects()==endEffects()) return Result_NoEffects; - if (getChance() (RAND_MAX)*100) + if (getChance() (RAND_MAX)) { removeIngredients(); return Result_RandomFailure; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6fc228f0b..8d8542bb5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -339,7 +339,7 @@ namespace MWWorld return ptr; } - throw std::runtime_error ("unknown Ogre handle: " + handle); + return MWWorld::Ptr(); } void World::enable (const Ptr& reference) @@ -850,12 +850,13 @@ namespace MWWorld mWeatherManager->update (duration); // inform the GUI about focused object - try - { - MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); - MWBase::Environment::get().getWindowManager()->setFocusObject(object); + MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); - // retrieve object dimensions so we know where to place the floating label + MWBase::Environment::get().getWindowManager()->setFocusObject(object); + + // retrieve object dimensions so we know where to place the floating label + if (!object.isEmpty ()) + { Ogre::SceneNode* node = object.getRefData().getBaseNode(); Ogre::AxisAlignedBox bounds; int i; @@ -871,11 +872,6 @@ namespace MWWorld screenCoords[0], screenCoords[1], screenCoords[2], screenCoords[3]); } } - catch (std::runtime_error&) - { - MWWorld::Ptr null; - MWBase::Environment::get().getWindowManager()->setFocusObject(null); - } if (!mRendering->occlusionQuerySupported()) { From 3f833af46a442e2aa08bdfbab71f39b510848505 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 19 Oct 2012 10:07:27 +0200 Subject: [PATCH 055/255] Issue #407: Fortyfy attribute effects were ignored for the last 3 attributes --- apps/openmw/mwmechanics/actors.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 87a058394..ab332eb96 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -118,18 +118,14 @@ namespace MWMechanics + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ()); } } - - - } - void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) { CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); // attributes - for (int i=0; i<5; ++i) + for (int i=0; i<8; ++i) { int modifier = creatureStats.getMagicEffects().get (EffectKey (79, i)).mMagnitude; From bdca5aff879665aabe13ca923cab28b5791a60b3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 19 Oct 2012 13:10:06 +0200 Subject: [PATCH 056/255] Issue #68: simplified the dynamic stats interface --- apps/openmw/mwclass/creature.cpp | 6 +-- apps/openmw/mwclass/npc.cpp | 6 +-- apps/openmw/mwmechanics/actors.cpp | 54 ++++++++++++------- apps/openmw/mwmechanics/creaturestats.cpp | 25 ++++----- apps/openmw/mwmechanics/creaturestats.hpp | 14 ++--- .../mwmechanics/mechanicsmanagerimp.cpp | 10 ++-- apps/openmw/mwscript/statsextensions.cpp | 27 +++++++--- 7 files changed, 78 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0cf348b14..0fb9daf19 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -55,9 +55,9 @@ namespace MWClass data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance); data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality); data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck); - data->mCreatureStats.getHealth().set (ref->base->mData.mHealth); - data->mCreatureStats.getMagicka().set (ref->base->mData.mMana); - data->mCreatureStats.getFatigue().set (ref->base->mData.mFatigue); + data->mCreatureStats.setHealth (ref->base->mData.mHealth); + data->mCreatureStats.setMagicka (ref->base->mData.mMana); + data->mCreatureStats.setFatigue (ref->base->mData.mFatigue); data->mCreatureStats.setLevel(ref->base->mData.mLevel); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 03b5e56aa..7e7e4937b 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -89,9 +89,9 @@ namespace MWClass data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance); data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality); data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck); - data->mCreatureStats.getHealth().set (ref->base->mNpdt52.mHealth); - data->mCreatureStats.getMagicka().set (ref->base->mNpdt52.mMana); - data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue); + data->mCreatureStats.setHealth (ref->base->mNpdt52.mHealth); + data->mCreatureStats.setMagicka (ref->base->mNpdt52.mMana); + data->mCreatureStats.setFatigue (ref->base->mNpdt52.mFatigue); data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel); } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ab332eb96..43d9e8a3b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -73,13 +73,17 @@ namespace MWMechanics double magickaFactor = creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5; - creatureStats.getHealth().setBase( - static_cast (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ()); + DynamicStat health = creatureStats.getHealth(); + health.setBase (static_cast (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ()); + creatureStats.setHealth (health); - creatureStats.getMagicka().setBase( - static_cast (intelligence + magickaFactor * intelligence)); - - creatureStats.getFatigue().setBase(strength+willpower+agility+endurance); + DynamicStat magicka = creatureStats.getMagicka(); + magicka.setBase (static_cast (intelligence + magickaFactor * intelligence)); + creatureStats.setMagicka (magicka); + + DynamicStat fatigue = creatureStats.getFatigue(); + fatigue.setBase (strength+willpower+agility+endurance); + creatureStats.setFatigue (fatigue); } void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) @@ -92,8 +96,10 @@ namespace MWMechanics bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0; int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); - stats.getHealth().setCurrent(stats.getHealth ().getCurrent () - + 0.1 * endurance); + + DynamicStat health = stats.getHealth(); + health.setCurrent (health.getCurrent() + 0.1 * endurance); + stats.setHealth (health); const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); @@ -109,13 +115,19 @@ namespace MWMechanics float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); x *= fEndFatigueMult * endurance; - stats.getFatigue ().setCurrent (stats.getFatigue ().getCurrent () + 3600 * x); - + + DynamicStat fatigue = stats.getFatigue(); + fatigue.setCurrent (fatigue.getCurrent() + 3600 * x); + stats.setFatigue (fatigue); + if (!stunted) { float fRestMagicMult = store.gameSettings.find("fRestMagicMult")->getFloat (); - stats.getMagicka().setCurrent (stats.getMagicka ().getCurrent () - + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ()); + + DynamicStat magicka = stats.getMagicka(); + magicka.setCurrent (magicka.getCurrent() + + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified()); + stats.setMagicka (magicka); } } } @@ -137,14 +149,16 @@ namespace MWMechanics // dynamic stats MagicEffects effects = creatureStats.getMagicEffects(); - creatureStats.getHealth().setModifier( - effects.get(EffectKey(80)).mMagnitude - effects.get(EffectKey(18)).mMagnitude); - - creatureStats.getMagicka().setModifier( - effects.get(EffectKey(81)).mMagnitude - effects.get(EffectKey(19)).mMagnitude); - - creatureStats.getFatigue().setModifier( - effects.get(EffectKey(82)).mMagnitude - effects.get(EffectKey(20)).mMagnitude); + + for (int i=0; i<3; ++i) + { + DynamicStat stat = creatureStats.getDynamic (i); + + stat.setModifier ( + effects.get (EffectKey(80+i)).mMagnitude - effects.get (EffectKey(18+i)).mMagnitude); + + creatureStats.setDynamic (i, stat); + } } Actors::Actors() : mDuration (0) {} diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index fc0523141..4f699bba0 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -118,22 +118,7 @@ namespace MWMechanics return mAttributes[index]; } - DynamicStat &CreatureStats::getHealth() - { - return mDynamic[0]; - } - - DynamicStat &CreatureStats::getMagicka() - { - return mDynamic[1]; - } - - DynamicStat &CreatureStats::getFatigue() - { - return mDynamic[2]; - } - - DynamicStat &CreatureStats::getDynamic(int index) + const DynamicStat &CreatureStats::getDynamic(int index) const { if (index < 0 || index > 2) { throw std::runtime_error("dynamic stat index is out of range"); @@ -184,6 +169,14 @@ namespace MWMechanics mDynamic[2] = value; } + void CreatureStats::setDynamic (int index, const DynamicStat &value) + { + if (index < 0 || index > 2) + throw std::runtime_error("dynamic stat index is out of range"); + + mDynamic[index] = value; + } + void CreatureStats::setLevel(int level) { mLevel = level; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 7a1e46f56..82988ce8b 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -43,6 +43,8 @@ namespace MWMechanics const DynamicStat & getFatigue() const; + const DynamicStat & getDynamic (int index) const; + const Spells & getSpells() const; const ActiveSpells & getActiveSpells() const; @@ -59,24 +61,14 @@ namespace MWMechanics int getAlarm() const; - Stat & getAttribute(int index); - DynamicStat & getHealth(); - - DynamicStat & getMagicka(); - - DynamicStat & getFatigue(); - - DynamicStat & getDynamic(int index); - Spells & getSpells(); ActiveSpells & getActiveSpells(); MagicEffects & getMagicEffects(); - void setAttribute(int index, const Stat &value); void setHealth(const DynamicStat &value); @@ -85,6 +77,8 @@ namespace MWMechanics void setFatigue(const DynamicStat &value); + void setDynamic (int index, const DynamicStat &value); + void setSpells(const Spells &spells); void setActiveSpells(const ActiveSpells &active); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 364e65321..6d8bdb332 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -153,12 +153,14 @@ namespace MWMechanics // forced update and current value adjustments mActors.updateActor (ptr, 0); - creatureStats.getHealth().setCurrent(creatureStats.getHealth().getModified()); - creatureStats.getMagicka().setCurrent(creatureStats.getMagicka().getModified()); - creatureStats.getFatigue().setCurrent(creatureStats.getFatigue().getModified()); + for (int i=0; i<2; ++i) + { + DynamicStat stat = creatureStats.getDynamic (i); + stat.setCurrent (stat.getModified()); + creatureStats.setDynamic (i, stat); + } } - MechanicsManager::MechanicsManager() : mUpdatePlayer (true), mClassSelected (false), mRaceSelected (false) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 66a5acae0..11548feab 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -188,10 +188,12 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Class::get(ptr) - .getCreatureStats(ptr) - .getDynamic(mIndex) - .setModified(value, 0); + MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) + .getDynamic (mIndex)); + + stat.setModified (value, 0); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat); } }; @@ -215,10 +217,14 @@ namespace MWScript Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent(); - stats.getDynamic(mIndex).setModified( - diff + stats.getDynamic(mIndex).getModified(), 0); + MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) + .getDynamic (mIndex)); - stats.getDynamic(mIndex).setCurrent(diff + current); + stat.setModified (diff + stat.getModified(), 0); + + stat.setCurrent (diff + current); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat); } }; @@ -242,7 +248,12 @@ namespace MWScript Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent(); - stats.getDynamic(mIndex).setCurrent (diff + current); + MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) + .getDynamic (mIndex)); + + stat.setCurrent (diff + current); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat); } }; From a8f294c9ae88efcc487f4a260cd0a056bcabb8e0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 19 Oct 2012 18:01:45 +0200 Subject: [PATCH 057/255] fixed types of dynamic stats script instructions --- apps/openmw/mwscript/statsextensions.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 11548feab..fc57bb654 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -155,7 +155,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value; + Interpreter::Type_Float value; if (mIndex==0 && MWWorld::Class::get (ptr).hasItemHealth (ptr)) { @@ -185,7 +185,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; + Interpreter::Type_Float value = runtime[0].mFloat; runtime.pop(); MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) @@ -210,12 +210,12 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer diff = runtime[0].mInteger; + Interpreter::Type_Float diff = runtime[0].mFloat; runtime.pop(); MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); - Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent(); + Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent(); MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) .getDynamic (mIndex)); @@ -241,12 +241,12 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer diff = runtime[0].mInteger; + Interpreter::Type_Float diff = runtime[0].mFloat; runtime.pop(); MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); - Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent(); + Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent(); MWMechanics::DynamicStat stat (MWWorld::Class::get (ptr).getCreatureStats (ptr) .getDynamic (mIndex)); @@ -687,16 +687,16 @@ namespace MWScript for (int i=0; i Date: Fri, 19 Oct 2012 18:56:22 +0200 Subject: [PATCH 058/255] Issue #68: added dead flag to CreatureStats --- apps/openmw/mwmechanics/creaturestats.cpp | 28 +++++++++++++++++++---- apps/openmw/mwmechanics/creaturestats.hpp | 6 ++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 4f699bba0..1ce7bdb93 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -10,7 +10,7 @@ namespace MWMechanics { CreatureStats::CreatureStats() - : mLevelHealthBonus(0.f) + : mLevel (0), mHello (0), mFight (0), mFlee (0), mAlarm (0), mLevelHealthBonus(0.f), mDead (false) { } @@ -156,17 +156,17 @@ namespace MWMechanics void CreatureStats::setHealth(const DynamicStat &value) { - mDynamic[0] = value; + setDynamic (0, value); } void CreatureStats::setMagicka(const DynamicStat &value) { - mDynamic[1] = value; + setDynamic (1, value); } void CreatureStats::setFatigue(const DynamicStat &value) { - mDynamic[2] = value; + setDynamic (2, value); } void CreatureStats::setDynamic (int index, const DynamicStat &value) @@ -175,6 +175,9 @@ namespace MWMechanics throw std::runtime_error("dynamic stat index is out of range"); mDynamic[index] = value; + + if (index==2 && mDynamic[index].getCurrent()<1) + mDead = true; } void CreatureStats::setLevel(int level) @@ -211,4 +214,21 @@ namespace MWMechanics { mAlarm = value; } + + bool CreatureStats::isDead() const + { + return mDead; + } + + void CreatureStats::resurrect() + { + if (mDead) + { + if (mDynamic[0].getCurrent()<1) + mDynamic[0].setCurrent (1); + + if (mDynamic[0].getCurrent()>=1) + mDead = false; + } + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 82988ce8b..671dcd439 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -29,8 +29,8 @@ namespace MWMechanics int mFlee; int mAlarm; AiSequence mAiSequence; - float mLevelHealthBonus; + bool mDead; public: CreatureStats(); @@ -105,6 +105,10 @@ namespace MWMechanics // small hack to allow the fact that Health permanently increases by 10% of endurance on each level up void increaseLevelHealthBonus(float value); float getLevelHealthBonus() const; + + bool isDead() const; + + void resurrect(); }; } From d76522e7a48ed83c659e782d81bfdbe44ca761a1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 19:48:02 +0200 Subject: [PATCH 059/255] searchPtrViaHandle --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwgui/hud.cpp | 10 +--------- apps/openmw/mwgui/tooltips.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 10 +++++++++- apps/openmw/mwworld/worldimp.hpp | 3 +++ 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 3867cb76a..2ce890363 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -424,7 +424,7 @@ void OMW::Engine::activate() if (handle.empty()) return; - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle (handle); if (ptr.isEmpty()) return; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 521bbb988..9dcdc312f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -142,6 +142,9 @@ namespace MWBase virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0; ///< Return a pointer to a liveCellRef with the given Ogre handle. + virtual MWWorld::Ptr searchPtrViaHandle (const std::string& handle) = 0; + ///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found + /// \todo enable reference in the OGRE scene virtual void enable (const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index ed0e59226..66cc6b21a 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -245,15 +245,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) return; std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - MWWorld::Ptr object; - try - { - object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); - } - catch (std::exception& /* e */) - { - return; - } + MWWorld::Ptr object = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); if (mode == GM_Console) MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 5256028eb..35224613c 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -80,7 +80,7 @@ void ToolTips::onFrame(float frameDuration) { std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); + mFocusObject = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); if (mFocusObject.isEmpty ()) return; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8d8542bb5..2e3d80aa4 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -326,6 +326,14 @@ namespace MWWorld } Ptr World::getPtrViaHandle (const std::string& handle) + { + Ptr res = searchPtrViaHandle (handle); + if (res.isEmpty ()) + throw std::runtime_error ("unknown Ogre handle: " + handle); + return res; + } + + Ptr World::searchPtrViaHandle (const std::string& handle) { if (mPlayer->getPlayer().getRefData().getHandle()==handle) return mPlayer->getPlayer(); @@ -850,7 +858,7 @@ namespace MWWorld mWeatherManager->update (duration); // inform the GUI about focused object - MWWorld::Ptr object = getPtrViaHandle(mFacedHandle); + MWWorld::Ptr object = searchPtrViaHandle(mFacedHandle); MWBase::Environment::get().getWindowManager()->setFocusObject(object); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 90cd2151b..f94882c10 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -163,6 +163,9 @@ namespace MWWorld virtual Ptr getPtrViaHandle (const std::string& handle); ///< Return a pointer to a liveCellRef with the given Ogre handle. + virtual Ptr searchPtrViaHandle (const std::string& handle); + ///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found + virtual void enable (const Ptr& ptr); virtual void disable (const Ptr& ptr); From 8d7514e341f4cd2c554507ea8c6c64772fec9714 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 19:48:54 +0200 Subject: [PATCH 060/255] corrected chance --- apps/openmw/mwmechanics/alchemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 583a3c18e..df7c786b1 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -474,7 +474,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na if (beginEffects()==endEffects()) return Result_NoEffects; - if (getChance() (RAND_MAX)) + if (getChance() (RAND_MAX)*100) { removeIngredients(); return Result_RandomFailure; From fbe3538f3263ee711f70aac8233009235e8c9f7e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:13:37 +0200 Subject: [PATCH 061/255] bug #412: sort birth signs --- apps/openmw/mwgui/birth.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index c8ef35be3..284653aee 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -14,6 +14,16 @@ using namespace MWGui; using namespace Widgets; +namespace +{ + +bool sortBirthSigns(const std::pair& left, const std::pair& right) +{ + return left.second->mName.compare (right.second->mName) < 0; +} + +} + BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) : WindowBase("openmw_chargen_birth.layout", parWindowManager) { @@ -115,11 +125,21 @@ void BirthDialog::updateBirths() ESMS::RecListT::MapType::const_iterator it = store.birthSigns.list.begin(); ESMS::RecListT::MapType::const_iterator end = store.birthSigns.list.end(); int index = 0; - for (; it != end; ++it) + + // sort by name + std::vector < std::pair > birthSigns; + for (; it!=end; ++it) { - const ESM::BirthSign &birth = it->second; - mBirthList->addItem(birth.mName, it->first); - if (boost::iequals(it->first, mCurrentBirthId)) + std::string id = it->first; + const ESM::BirthSign* sign = &it->second; + birthSigns.push_back(std::make_pair(id, sign)); + } + std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns); + + for (std::vector < std::pair >::const_iterator it2 = birthSigns.begin(); it2 != birthSigns.end(); ++it2) + { + mBirthList->addItem(it2->second->mName, it2->first); + if (boost::iequals(it2->first, mCurrentBirthId)) mBirthList->setIndexSelected(index); ++index; } From b2b92547187d46fc71ca5249ae1e4a69a16d8d76 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:44:53 +0200 Subject: [PATCH 062/255] improved the ingredient GUI code (this didnt fix anything, though) --- apps/openmw/mwgui/alchemywindow.cpp | 60 +++++++++-------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 192bbd090..bda76490b 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -151,46 +151,15 @@ namespace MWGui void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) { removeIngredient(_sender); - drawItems(); update(); } void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item) { - MyGUI::ImageBox* add = NULL; + int res = mAlchemy.addIngredient(item); - // don't allow to add an ingredient that is already added - // (which could happen if two similiar ingredients don't stack because of script / owner) - bool alreadyAdded = false; - std::string name = MWWorld::Class::get(item).getName(item); - for (int i=0; i<4; ++i) - if (mIngredients[i]->isUserString("ToolTipType")) - { - MWWorld::Ptr item2 = *mIngredients[i]->getUserData(); - std::string name2 = MWWorld::Class::get(item2).getName(item2); - if (name == name2) - alreadyAdded = true; - } - - if (alreadyAdded) - return; - - for (int i=0; i<4; ++i) - if (!mIngredients[i]->isUserString("ToolTipType")) - { - add = mIngredients[i]; - - mAlchemy.addIngredient(item); - - break; - } - - if (add != NULL) + if (res != -1) { - add->setUserString("ToolTipType", "ItemPtr"); - add->setUserData(item); - add->setImageTexture(getIconPath(item)); - drawItems(); update(); std::string sound = MWWorld::Class::get(item).getUpSoundId(item); @@ -211,17 +180,27 @@ namespace MWGui void AlchemyWindow::update() { + MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients (); for (int i=0; i<4; ++i) { MyGUI::ImageBox* ingredient = mIngredients[i]; - if (!ingredient->isUserString("ToolTipType")) - continue; + MWWorld::Ptr item = *it; + ++it; - // update ingredient count labels if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); + ingredient->setImageTexture(""); + ingredient->clearUserStrings (); + + if (item.isEmpty ()) + continue; + + ingredient->setUserString("ToolTipType", "ItemPtr"); + ingredient->setUserData(item); + ingredient->setImageTexture(getIconPath(item)); + MyGUI::TextBox* text = ingredient->createWidget("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); text->setTextAlign(MyGUI::Align::Right); text->setNeedMouseFocus(false); @@ -230,6 +209,8 @@ namespace MWGui text->setCaption(getCountString(ingredient->getUserData()->getRefData().getCount())); } + drawItems(); + std::vector effects; ESM::EffectList list; list.mList = effects; @@ -256,13 +237,10 @@ namespace MWGui void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient) { - ingredient->clearUserStrings(); - static_cast(ingredient)->setImageTexture(""); - if (ingredient->getChildCount()) - MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); - for (int i=0; i<4; ++i) if (mIngredients[i] == ingredient) mAlchemy.removeIngredient (i); + + update(); } } From 59560e84eb18b8376f383d0b7411b885108de3fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 19 Oct 2012 20:48:15 +0200 Subject: [PATCH 063/255] small addition --- apps/openmw/mwgui/alchemywindow.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index bda76490b..56db47a0f 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -146,6 +146,8 @@ namespace MWGui mApparatus.at (index)->setImageTexture (getIconPath (*iter)); } } + + update(); } void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) @@ -185,8 +187,12 @@ namespace MWGui { MyGUI::ImageBox* ingredient = mIngredients[i]; - MWWorld::Ptr item = *it; - ++it; + MWWorld::Ptr item; + if (it != mAlchemy.endIngredients ()) + { + item = *it; + ++it; + } if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); From f2e25b8a476a2fad5c35d29c7e894bd716a110f3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 20 Oct 2012 10:49:48 +0200 Subject: [PATCH 064/255] Issue #68: Keep dead actors out of the actor list for the current scene --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 ++ apps/openmw/mwmechanics/actors.cpp | 3 ++- apps/openmw/mwmechanics/actors.hpp | 2 ++ apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 39d7e6e1a..c5d721e26 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -39,6 +39,8 @@ namespace MWBase virtual void addActor (const MWWorld::Ptr& ptr) = 0; ///< Register an actor for stats management + /// + /// \note Dead actors are ignored. virtual void removeActor (const MWWorld::Ptr& ptr) = 0; ///< Deregister an actor for stats management diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 43d9e8a3b..63f890d65 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -165,7 +165,8 @@ namespace MWMechanics void Actors::addActor (const MWWorld::Ptr& ptr) { - mActors.insert (ptr); + if (!MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead()) + mActors.insert (ptr); } void Actors::removeActor (const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 7e5a0ac86..f8a00f349 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -40,6 +40,8 @@ namespace MWMechanics void addActor (const MWWorld::Ptr& ptr); ///< Register an actor for stats management + /// + /// \note Dead actors are ignored. void removeActor (const MWWorld::Ptr& ptr); ///< Deregister an actor for stats management diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 3a41e8fa6..205deaf71 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -41,6 +41,8 @@ namespace MWMechanics virtual void addActor (const MWWorld::Ptr& ptr); ///< Register an actor for stats management + /// + /// \note Dead actors are ignored. virtual void removeActor (const MWWorld::Ptr& ptr); ///< Deregister an actor for stats management From 0547f11564efec3fc719d64d0f859478eb0d9450 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 20 Oct 2012 10:54:51 +0200 Subject: [PATCH 065/255] Issue #68: Remove dead actors from actor list --- apps/openmw/mwmechanics/actors.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 63f890d65..a33ef7240 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -199,13 +199,23 @@ namespace MWMechanics { float totalDuration = mDuration; mDuration = 0; + + std::set::iterator iter (mActors.begin()); - for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter) + while (iter!=mActors.end()) { - updateActor (*iter, totalDuration); + if (!MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead()) + { + updateActor (*iter, totalDuration); - if (iter->getTypeName()==typeid (ESM::NPC).name()) - updateNpc (*iter, totalDuration, paused); + if (iter->getTypeName()==typeid (ESM::NPC).name()) + updateNpc (*iter, totalDuration, paused); + } + + if (MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead()) + mActors.erase (iter++); + else + ++iter; } } From 6433b1e0220fe08baff1e242fa2a6cd463f79002 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Mon, 22 Oct 2012 02:25:10 +0200 Subject: [PATCH 066/255] Some minor fixes --- apps/launcher/datafilespage.cpp | 3 ++- apps/launcher/maindialog.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index c0a447e26..ebbfb9960 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -90,6 +90,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) // Set the row height to the size of the checkboxes mMastersTable->verticalHeader()->setDefaultSectionSize(height); + mMastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mMastersTable->verticalHeader()->hide(); mMastersTable->setColumnHidden(1, true); mMastersTable->setColumnHidden(2, true); @@ -110,7 +111,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) mPluginsTable->setAlternatingRowColors(true); mPluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); mPluginsTable->horizontalHeader()->setStretchLastSection(true); - + mPluginsTable->horizontalHeader()->hide(); mPluginsTable->verticalHeader()->setDefaultSectionSize(height); mPluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mPluginsTable->setColumnHidden(1, true); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index f7dafd3af..3ce418ddf 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -244,10 +244,10 @@ void MainDialog::play() const std::string settingspath = (mCfgMgr.getUserPath() / "settings.cfg").string(); mSettings.saveUser(settingspath); -#ifdef Q_WS_WIN +#ifdef Q_OS_WIN QString game = "./openmw.exe"; QFile file(game); -#elif defined(Q_WS_MAC) +#elif defined(Q_OS_MAC) QDir dir(QCoreApplication::applicationDirPath()); QString game = dir.absoluteFilePath("openmw"); QFile file(game); From 9f821e5df20370da3eb3c39f24a69e05c96cdc3b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Oct 2012 16:56:43 +0200 Subject: [PATCH 067/255] fix shaders --- files/materials/objects.shader | 15 ++++++++++++--- files/materials/terrain.shader | 12 ++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 525e4ab63..5ea076342 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -157,10 +157,15 @@ shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart) #endif -#if UNDERWATER +#if (UNDERWATER) || (FOG) shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) - shUniform(float, waterLevel) @shSharedParameter(waterLevel) shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) +#endif + +#if UNDERWATER + + shUniform(float, waterLevel) @shSharedParameter(waterLevel) + shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) shSampler2D(causticMap) @@ -211,8 +216,12 @@ float3 caustics = float3(1,1,1); -#if UNDERWATER + +#if (UNDERWATER) || (FOG) float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough,1)).xyz; +#endif + +#if UNDERWATER float3 waterEyePos = float3(1,1,1); // NOTE: this calculation would be wrong for non-uniform scaling float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 35ce40330..dee733263 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -187,11 +187,13 @@ shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart) #endif +#if (UNDERWATER) || (FOG) + shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) + shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) +#endif #if UNDERWATER - shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) shUniform(float, waterLevel) @shSharedParameter(waterLevel) - shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position) shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) shSampler2D(causticMap) @@ -222,9 +224,12 @@ float3 caustics = float3(1,1,1); +#if (UNDERWATER) || (FOG) + float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; +#endif + #if UNDERWATER - float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; float3 waterEyePos = float3(1,1,1); // NOTE: this calculation would be wrong for non-uniform scaling float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); @@ -373,7 +378,6 @@ shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depth / far,1,1,1); #endif From fe9120bcb31a7653e7cfd772c8ad4cfb51ce059f Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 23 Oct 2012 01:47:07 +0200 Subject: [PATCH 068/255] Added support for the profiles and made creation/editing them more user friendly --- apps/launcher/CMakeLists.txt | 9 +- apps/launcher/datafilespage.cpp | 146 ++++++++++++++++------- apps/launcher/datafilespage.hpp | 11 +- apps/launcher/main.cpp | 2 +- apps/launcher/maindialog.cpp | 2 - apps/launcher/utils/combobox.hpp | 28 ----- apps/launcher/utils/profilescombobox.cpp | 52 ++++++++ apps/launcher/utils/profilescombobox.hpp | 30 +++++ apps/launcher/utils/textinputdialog.cpp | 61 ++++++++++ apps/launcher/utils/textinputdialog.hpp | 28 +++++ 10 files changed, 289 insertions(+), 80 deletions(-) delete mode 100644 apps/launcher/utils/combobox.hpp create mode 100644 apps/launcher/utils/profilescombobox.cpp create mode 100644 apps/launcher/utils/profilescombobox.hpp create mode 100644 apps/launcher/utils/textinputdialog.cpp create mode 100644 apps/launcher/utils/textinputdialog.hpp diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 92903b48d..edc3dcf32 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -12,6 +12,8 @@ set(LAUNCHER utils/filedialog.cpp utils/naturalsort.cpp utils/lineedit.cpp + utils/profilescombobox.cpp + utils/textinputdialog.cpp launcher.rc ) @@ -26,10 +28,12 @@ set(LAUNCHER_HEADER model/modelitem.hpp model/esm/esmfile.hpp - utils/combobox.hpp utils/lineedit.hpp utils/filedialog.hpp utils/naturalsort.hpp + utils/profilescombobox.hpp + utils/textinputdialog.hpp + ) # Headers that must be pre-processed @@ -43,9 +47,10 @@ set(LAUNCHER_HEADER_MOC model/modelitem.hpp model/esm/esmfile.hpp - utils/combobox.hpp utils/lineedit.hpp utils/filedialog.hpp + utils/profilescombobox.hpp + utils/textinputdialog.hpp ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC}) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index ce3d6b31d..01b879842 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -6,10 +6,11 @@ #include "model/datafilesmodel.hpp" #include "model/esm/esmfile.hpp" -#include "utils/combobox.hpp" +#include "utils/profilescombobox.hpp" #include "utils/filedialog.hpp" #include "utils/lineedit.hpp" #include "utils/naturalsort.hpp" +#include "utils/textinputdialog.hpp" #include "datafilespage.hpp" @@ -139,9 +140,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) // Bottom part with profile options QLabel *profileLabel = new QLabel(tr("Current Profile: "), this); - mProfilesComboBox = new ComboBox(this); + mProfilesComboBox = new ProfilesComboBox(this); mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); - mProfilesComboBox->setInsertPolicy(QComboBox::InsertAtBottom); + mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert); + mProfilesComboBox->setDuplicatesEnabled(false); + mProfilesComboBox->setEditEnabled(false); mProfileToolBar = new QToolBar(this); mProfileToolBar->setMovable(false); @@ -156,16 +159,22 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) pageLayout->addWidget(splitter); pageLayout->addWidget(mProfileToolBar); + // Create a dialog for the new profile name input + mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); + + connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); + connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mMastersModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mPluginsModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList))); - connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(const QString))); + connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - connect(mPluginsTable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); + connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&))); + connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString))); + connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString))); createActions(); setupConfig(); @@ -230,12 +239,21 @@ void DataFilesPage::setupConfig() mLauncherConfig->beginGroup("Profiles"); QStringList profiles = mLauncherConfig->childGroups(); - if (profiles.isEmpty()) { - // Add a default profile - profiles.append("Default"); + // Add the profiles to the combobox + foreach (const QString &profile, profiles) { + + if (profile.contains(QRegExp("[^a-zA-Z0-9_]"))) + continue; // Profile name contains garbage + + + qDebug() << "adding " << profile; + mProfilesComboBox->addItem(profile); } - mProfilesComboBox->addItems(profiles); + // Add a default profile + if (mProfilesComboBox->count() == 0) { + mProfilesComboBox->addItem(QString("Default")); + } QString currentProfile = mLauncherConfig->value("CurrentProfile").toString(); @@ -572,33 +590,37 @@ void DataFilesPage::writeConfig(QString profile) void DataFilesPage::newProfile() { - bool ok; - QString text = QInputDialog::getText(this, tr("New Profile"), - tr("Profile Name:"), QLineEdit::Normal, - tr("New Profile"), &ok); - if (ok && !text.isEmpty()) { - if (mProfilesComboBox->findText(text) != -1) { - QMessageBox::warning(this, tr("Profile already exists"), - tr("the profile %0 already exists.").arg(text), - QMessageBox::Ok); - } else { - // Add the new profile to the combobox - mProfilesComboBox->addItem(text); - mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); + if (mNewProfileDialog->exec() == QDialog::Accepted) { - } + const QString text = mNewProfileDialog->lineEdit()->text(); + mProfilesComboBox->addItem(text); + // Copy the currently checked items to cfg + writeConfig(text); + mLauncherConfig->sync(); + + mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); } } +void DataFilesPage::updateOkButton(const QString &text) +{ + if (text.isEmpty()) { + mNewProfileDialog->setOkButtonEnabled(false); + return; + } + + (mProfilesComboBox->findText(text) == -1) + ? mNewProfileDialog->setOkButtonEnabled(true) + : mNewProfileDialog->setOkButtonEnabled(false); +} + void DataFilesPage::deleteProfile() { QString profile = mProfilesComboBox->currentText(); - - if (profile.isEmpty()) { + if (profile.isEmpty()) return; - } QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Delete Profile")); @@ -694,19 +716,17 @@ void DataFilesPage::setCheckState(QModelIndex index) return; if (object->objectName() == QLatin1String("PluginsTable")) { - if (mPluginsModel->checkState(index) == Qt::Checked) { - mPluginsModel->setCheckState(index, Qt::Unchecked); - } else { - mPluginsModel->setCheckState(index, Qt::Checked); - } + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); + + (mPluginsModel->checkState(sourceIndex) == Qt::Checked) + ? mPluginsModel->setCheckState(index, Qt::Unchecked) + : mPluginsModel->setCheckState(index, Qt::Checked); } if (object->objectName() == QLatin1String("MastersTable")) { - if (mMastersModel->checkState(index) == Qt::Checked) { - mMastersModel->setCheckState(index, Qt::Unchecked); - } else { - mMastersModel->setCheckState(index, Qt::Checked); - } + (mMastersModel->checkState(index) == Qt::Checked) + ? mMastersModel->setCheckState(index, Qt::Unchecked) + : mMastersModel->setCheckState(index, Qt::Checked); } return; @@ -721,13 +741,23 @@ void DataFilesPage::filterChanged(const QString filter) void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) { + qDebug() << "Profile is changed from: " << previous << " to " << current; // Prevent the deletion of the default profile - (current == QLatin1String("Default")) ? mDeleteProfileAction->setEnabled(false) - : mDeleteProfileAction->setEnabled(true); + if (current == QLatin1String("Default")) { + mDeleteProfileAction->setEnabled(false); + mProfilesComboBox->setEditEnabled(false); + } else { + mDeleteProfileAction->setEnabled(true); + mProfilesComboBox->setEditEnabled(true); + } if (!previous.isEmpty()) { writeConfig(previous); mLauncherConfig->sync(); + + if (mProfilesComboBox->currentIndex() == -1) + return; + } else { return; } @@ -737,6 +767,36 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre readConfig(); } +void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t) +{ + if (previous.isEmpty()) + return; + + // Save the new profile name + writeConfig(current); + + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + + // Open the profile-name subgroup + mLauncherConfig->beginGroup(previous); + mLauncherConfig->remove(""); // Clear the subgroup + mLauncherConfig->endGroup(); + mLauncherConfig->endGroup(); + mLauncherConfig->sync(); + + // Remove the profile from the combobox + mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous)); + + mMastersModel->uncheckAll(); + mPluginsModel->uncheckAll(); + readConfig(); +} + void DataFilesPage::showContextMenu(const QPoint &point) { // Make sure there are plugins in the view @@ -756,11 +816,9 @@ void DataFilesPage::showContextMenu(const QPoint &point) if (!index.isValid()) return; - if (mPluginsModel->checkState(index) == Qt::Checked) { - mUncheckAction->setEnabled(true); - } else { - mCheckAction->setEnabled(true); - } + (mPluginsModel->checkState(index) == Qt::Checked) + ? mUncheckAction->setEnabled(true) + : mCheckAction->setEnabled(true); } // Show menu diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 64f255b57..8b48c1e12 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -3,7 +3,7 @@ #include #include - +#include "utils/profilescombobox.hpp" #include @@ -13,9 +13,10 @@ class QSettings; class QAction; class QToolBar; class QMenu; -class ComboBox; +class ProfilesComboBox; class DataFilesModel; +class TextInputDialog; namespace Files { struct ConfigurationManager; } @@ -26,7 +27,7 @@ class DataFilesPage : public QWidget public: DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0); - ComboBox *mProfilesComboBox; + ProfilesComboBox *mProfilesComboBox; void writeConfig(QString profile = QString()); bool setupDataFiles(); @@ -37,6 +38,8 @@ public slots: void filterChanged(const QString filter); void showContextMenu(const QPoint &point); void profileChanged(const QString &previous, const QString ¤t); + void profileRenamed(const QString &previous, const QString ¤t); + void updateOkButton(const QString &text); // Action slots void newProfile(); @@ -77,6 +80,8 @@ private: QSettings *mLauncherConfig; + TextInputDialog *mNewProfileDialog; + // const QStringList checkedPlugins(); // const QStringList selectedMasters(); diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 4ae09f844..7c4cb5f7e 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) // Now we make sure the current dir is set to application path QDir dir(QCoreApplication::applicationDirPath()); - #if defined(Q_OS_MAC) + #ifdef Q_OS_MAC if (dir.dirName() == "MacOS") { dir.cdUp(); dir.cdUp(); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d65e51f24..3ce418ddf 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,7 +1,5 @@ #include -#include "utils/combobox.hpp" - #include "maindialog.hpp" #include "playpage.hpp" #include "graphicspage.hpp" diff --git a/apps/launcher/utils/combobox.hpp b/apps/launcher/utils/combobox.hpp deleted file mode 100644 index bc99575d7..000000000 --- a/apps/launcher/utils/combobox.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef COMBOBOX_H -#define COMBOBOX_H - -#include - -class ComboBox : public QComboBox -{ - Q_OBJECT -private: - QString oldText; -public: - ComboBox(QWidget *parent=0) : QComboBox(parent), oldText() - { - connect(this,SIGNAL(editTextChanged(const QString&)), this, - SLOT(textChangedSlot(const QString&))); - connect(this,SIGNAL(currentIndexChanged(const QString&)), this, - SLOT(textChangedSlot(const QString&))); - } -private slots: - void textChangedSlot(const QString &newText) - { - emit textChanged(oldText, newText); - oldText = newText; - } -signals: - void textChanged(const QString &oldText, const QString &newText); -}; -#endif \ No newline at end of file diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp new file mode 100644 index 000000000..8354d4a78 --- /dev/null +++ b/apps/launcher/utils/profilescombobox.cpp @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "profilescombobox.hpp" + +ProfilesComboBox::ProfilesComboBox(QWidget *parent) : + QComboBox(parent) +{ + mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore + + setEditable(true); + setValidator(mValidator); + setCompleter(0); + + connect(this, SIGNAL(currentIndexChanged(int)), this, + SLOT(slotIndexChanged(int))); + connect(lineEdit(), SIGNAL(returnPressed()), this, + SLOT(slotReturnPressed())); +} + +void ProfilesComboBox::setEditEnabled(bool editable) +{ + if (!editable) + return setEditable(false); + + // Reset the completer and validator + setEditable(true); + setValidator(mValidator); + setCompleter(0); +} + +void ProfilesComboBox::slotReturnPressed() +{ + QString current = currentText(); + QString previous = itemText(currentIndex()); + + if (findText(current) != -1) + return; + + setItemText(currentIndex(), current); + emit(profileRenamed(previous, current)); +} + +void ProfilesComboBox::slotIndexChanged(int index) +{ + if (index == -1) + return; + + emit(profileChanged(mOldProfile, currentText())); + mOldProfile = itemText(index); +} diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp new file mode 100644 index 000000000..c7da60d2a --- /dev/null +++ b/apps/launcher/utils/profilescombobox.hpp @@ -0,0 +1,30 @@ +#ifndef PROFILESCOMBOBOX_HPP +#define PROFILESCOMBOBOX_HPP + +#include + +class QString; + +class QRegExpValidator; + +class ProfilesComboBox : public QComboBox +{ + Q_OBJECT +public: + explicit ProfilesComboBox(QWidget *parent = 0); + void setEditEnabled(bool editable); + +signals: + void profileChanged(const QString &previous, const QString ¤t); + void profileRenamed(const QString &oldName, const QString &newName); + +private slots: + void slotReturnPressed(); + void slotIndexChanged(int index); + +private: + QString mOldProfile; + QRegExpValidator *mValidator; +}; + +#endif // PROFILESCOMBOBOX_HPP diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp new file mode 100644 index 000000000..16cadb661 --- /dev/null +++ b/apps/launcher/utils/textinputdialog.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include + +#include "lineedit.hpp" + +#include "textinputdialog.hpp" + +TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : + QDialog(parent) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + mButtonBox = new QDialogButtonBox(this); + mButtonBox->addButton(QDialogButtonBox::Ok); + mButtonBox->addButton(QDialogButtonBox::Cancel); + + setMaximumHeight(height()); + setOkButtonEnabled(false); + setModal(true); + + // Messageboxes on mac have no title +#ifndef Q_OS_MAC + setWindowTitle(title); +#else + Q_UNUSED(title); +#endif + + QLabel *label = new QLabel(this); + label->setText(text); + + // Line edit + QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore + mLineEdit = new LineEdit(this); + mLineEdit->setValidator(validator); + mLineEdit->setCompleter(0); + + QVBoxLayout *dialogLayout = new QVBoxLayout(this); + dialogLayout->addWidget(label); + dialogLayout->addWidget(mLineEdit); + dialogLayout->addWidget(mButtonBox); + + connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +int TextInputDialog::exec() +{ + mLineEdit->clear(); + mLineEdit->setFocus(); + return QDialog::exec(); +} + +void TextInputDialog::setOkButtonEnabled(bool enabled) +{ + + QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok); + okButton->setEnabled(enabled); +} diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp new file mode 100644 index 000000000..cbb453ac8 --- /dev/null +++ b/apps/launcher/utils/textinputdialog.hpp @@ -0,0 +1,28 @@ +#ifndef TEXTINPUTDIALOG_HPP +#define TEXTINPUTDIALOG_HPP + +#include +//#include "lineedit.hpp" + +class QDialogButtonBox; +class LineEdit; + +class TextInputDialog : public QDialog +{ + Q_OBJECT +public: + explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); + inline LineEdit *lineEdit() { return mLineEdit; } + void setOkButtonEnabled(bool enabled); + + LineEdit *mLineEdit; + + int exec(); + +private: + QDialogButtonBox *mButtonBox; + + +}; + +#endif // TEXTINPUTDIALOG_HPP From 234716daa6fca5d0f92069fdf19a03e67cd2b9a9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 23 Oct 2012 11:42:38 +0200 Subject: [PATCH 069/255] finished spell creation --- apps/openmw/mwgui/spellcreationdialog.cpp | 77 +++++++++++++++++-- apps/openmw/mwgui/spellcreationdialog.hpp | 4 + apps/openmw/mwmechanics/spellsuccess.hpp | 26 +++++-- .../mygui/openmw_spellcreation_dialog.layout | 3 - 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index bb066e8ff..4ce056010 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -15,10 +15,14 @@ #include "../mwmechanics/spells.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/spellsuccess.hpp" + #include "tooltips.hpp" #include "widgets.hpp" #include "class.hpp" +#include "inventorywindow.hpp" +#include "tradewindow.hpp" namespace { @@ -310,14 +314,25 @@ namespace MWGui return; } - ESM::Spell newSpell; - ESM::EffectList effectList; - effectList.mList = mEffects; - newSpell.mEffects = effectList; - newSpell.mName = mNameEdit->getCaption(); - newSpell.mData.mType = ESM::Spell::ST_Spell; + if (mMagickaCost->getCaption() == "0") + { + mWindowManager.messageBox ("#{sEnchantmentMenu8}", std::vector()); + return; + } - std::pair result = MWBase::Environment::get().getWorld()->createRecord(newSpell); + if (boost::lexical_cast(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold()) + { + mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector()); + return; + } + + mSpell.mName = mNameEdit->getCaption(); + + mWindowManager.getTradeWindow()->addOrRemoveGold(-boost::lexical_cast(mPriceLabel->getCaption())); + + MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); + + std::pair result = MWBase::Environment::get().getWorld()->createRecord(mSpell); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); @@ -340,6 +355,47 @@ namespace MWGui mWindowManager.removeGuiMode (GM_SpellCreation); } + void SpellCreationDialog::notifyEffectsChanged () + { + float y = 0; + + for (std::vector::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) + { + float x = 0.5 * it->mMagnMin + it->mMagnMax; + + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(it->mEffectID); + x *= 0.1 * effect->mData.mBaseCost; + x *= 1 + it->mDuration; + x += 0.05 * std::max(1, it->mArea) * effect->mData.mBaseCost; + + float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fEffectCostMult")->getFloat(); + y += x * fEffectCostMult; + y = std::max(1.f,y); + + if (effect->mData.mFlags & ESM::MagicEffect::CastTarget) + y *= 1.5; + } + + mSpell.mData.mCost = int(y); + + ESM::EffectList effectList; + effectList.mList = mEffects; + mSpell.mEffects = effectList; + mSpell.mData.mType = ESM::Spell::ST_Spell; + + mMagickaCost->setCaption(boost::lexical_cast(int(y))); + + float fSpellMakingValueMult = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellMakingValueMult")->getFloat(); + + /// \todo mercantile + int price = int(y) * fSpellMakingValueMult; + + mPriceLabel->setCaption(boost::lexical_cast(int(price))); + + float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mSuccessChance->setCaption(boost::lexical_cast(int(chance))); + } + // ------------------------------------------------------------------------------------------------ @@ -443,6 +499,11 @@ namespace MWGui void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender) { + if (mEffects.size() >= 8) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}", std::vector()); + return; + } short effectId = *sender->getUserData(); @@ -534,6 +595,8 @@ namespace MWGui } mUsedEffectsView->setCanvasSize(size); + + notifyEffectsChanged(); } void EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect) diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 255b04cf6..4d27ec1c6 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -116,6 +116,7 @@ namespace MWGui void startEditing(); void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); + virtual void notifyEffectsChanged () {} }; class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase @@ -133,6 +134,7 @@ namespace MWGui void onCancelButtonClicked (MyGUI::Widget* sender); void onBuyButtonClicked (MyGUI::Widget* sender); + virtual void notifyEffectsChanged (); MyGUI::EditBox* mNameEdit; MyGUI::TextBox* mMagickaCost; @@ -143,6 +145,8 @@ namespace MWGui Widgets::MWEffectList* mUsedEffectsList; + ESM::Spell mSpell; + }; } diff --git a/apps/openmw/mwmechanics/spellsuccess.hpp b/apps/openmw/mwmechanics/spellsuccess.hpp index 43db42aab..a46667cdc 100644 --- a/apps/openmw/mwmechanics/spellsuccess.hpp +++ b/apps/openmw/mwmechanics/spellsuccess.hpp @@ -27,9 +27,8 @@ namespace MWMechanics return schoolSkillMap[school]; } - inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor) + inline int getSpellSchool(const ESM::Spell* spell, const MWWorld::Ptr& actor) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); // determine the spell's school @@ -60,27 +59,34 @@ namespace MWMechanics return school; } + inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); + return getSpellSchool(spell, actor); + } + // UESP wiki / Morrowind/Spells: // Chance of success is (Spell's skill * 2 + Willpower / 5 + Luck / 10 - Spell cost - Sound magnitude) * (Current fatigue + Maximum Fatigue * 1.5) / Maximum fatigue * 2 /** - * @param spellId ID of spell + * @param spell spell to cast * @param actor calculate spell success chance for this actor (depends on actor's skills) * @attention actor has to be an NPC and not a creature! * @return success chance from 0 to 100 (in percent) */ - inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor) + inline float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); - if (spell->mData.mFlags & ESM::Spell::F_Always // spells with this flag always succeed (usually birthsign spells) || spell->mData.mType == ESM::Spell::ST_Power) // powers always succeed, but can be cast only once per day return 100.0; + if (spell->mEffects.mList.size() == 0) + return 0.0; + NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); - int skillLevel = stats.getSkill (getSpellSchool(spellId, actor)).getModified(); + int skillLevel = stats.getSkill (getSpellSchool(spell, actor)).getModified(); // Sound magic effect (reduces spell casting chance) int soundMagnitude = creatureStats.getMagicEffects().get (MWMechanics::EffectKey (48)).mMagnitude; @@ -98,6 +104,12 @@ namespace MWMechanics return chance; } + + inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); + return getSpellSuccessChance(spell, actor); + } } #endif diff --git a/files/mygui/openmw_spellcreation_dialog.layout b/files/mygui/openmw_spellcreation_dialog.layout index 499224362..78d3f3de7 100644 --- a/files/mygui/openmw_spellcreation_dialog.layout +++ b/files/mygui/openmw_spellcreation_dialog.layout @@ -22,7 +22,6 @@ - @@ -31,7 +30,6 @@ - @@ -64,7 +62,6 @@ - From 9172c3ec4d840b9b3960ef3cae03e14fe90b8dff Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Oct 2012 13:54:36 +0200 Subject: [PATCH 070/255] Issue #68: stop NPCs from instantly dropping dead --- apps/openmw/mwclass/npc.cpp | 7 +++++++ apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/creaturestats.cpp | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 7e7e4937b..bcde31b26 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -98,6 +98,13 @@ namespace MWClass else { /// \todo do something with mNpdt12 maybe:p + for (int i=0; i<8; ++i) + data->mCreatureStats.getAttribute (i).set (10); + + for (int i=0; i<3; ++i) + data->mCreatureStats.setDynamic (i, 10); + + data->mCreatureStats.setLevel (1); } data->mCreatureStats.setHello(ref->base->mAiData.mHello); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index a33ef7240..e8b6fc14d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -24,8 +24,8 @@ namespace MWMechanics { // magic effects adjustMagicEffects (ptr); - calculateCreatureStatModifiers (ptr); calculateDynamicStats (ptr); + calculateCreatureStatModifiers (ptr); // AI CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 1ce7bdb93..8be4b9369 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -173,9 +173,9 @@ namespace MWMechanics { if (index < 0 || index > 2) throw std::runtime_error("dynamic stat index is out of range"); - + mDynamic[index] = value; - + if (index==2 && mDynamic[index].getCurrent()<1) mDead = true; } From 4ca0eb93eec7ef18f453ac8d086911bcc34f8a04 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 24 Oct 2012 17:47:03 +0200 Subject: [PATCH 071/255] fix markers used for raycasting and blocking activation --- components/nifbullet/bullet_nif_loader.cpp | 7 ++++--- libs/openengine/bullet/BulletShapeLoader.cpp | 3 ++- libs/openengine/bullet/BulletShapeLoader.h | 4 +++- libs/openengine/bullet/physic.cpp | 10 +++++++--- libs/openengine/bullet/physic.hpp | 3 ++- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 6449ad246..d2ec7ca82 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -71,7 +71,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) { cShape = static_cast(resource); resourceName = cShape->getName(); - cShape->collide = false; + cShape->mCollide = false; mBoundingBox = NULL; cShape->boxTranslation = Ogre::Vector3(0,0,0); cShape->boxRotation = Ogre::Quaternion::IDENTITY; @@ -108,7 +108,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) handleNode(node,0,NULL,hasCollisionNode,false,false); //if collide = false, then it does a second pass which create a shape for raycasting. - if(cShape->collide == false) + if(cShape->mCollide == false) { handleNode(node,0,NULL,hasCollisionNode,false,true); } @@ -177,6 +177,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, if (node->name.find("marker") != std::string::npos) { flags |= 0x800; + cShape->mIgnore = true; } // Check for extra data @@ -254,7 +255,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, } else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) { - cShape->collide = !(flags&0x800); + cShape->mCollide = !(flags&0x800); handleNiTriShape(dynamic_cast(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly); } else if(node->recType == Nif::RC_RootCollisionNode) diff --git a/libs/openengine/bullet/BulletShapeLoader.cpp b/libs/openengine/bullet/BulletShapeLoader.cpp index 59a414f30..dd3bca692 100644 --- a/libs/openengine/bullet/BulletShapeLoader.cpp +++ b/libs/openengine/bullet/BulletShapeLoader.cpp @@ -16,7 +16,8 @@ Ogre::Resource(creator, name, handle, group, isManual, loader) we have none as such. Full details can be set through scripts. */ Shape = NULL; - collide = true; + mCollide = true; + mIgnore = false; createParamDictionary("BulletShape"); } diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index 8640fd54f..21d21777a 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -34,7 +34,9 @@ public: Ogre::Vector3 boxTranslation; Ogre::Quaternion boxRotation; //this flag indicate if the shape is used for collision or if it's for raycasting only. - bool collide; + bool mCollide; + + bool mIgnore; }; /** diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 4f16a4143..d78e25ce7 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -169,6 +169,7 @@ namespace Physic RigidBody::RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name) : btRigidBody(CI) , mName(name) + , mIgnore(false) { } @@ -327,7 +328,7 @@ namespace Physic btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,hfShape); RigidBody* body = new RigidBody(CI,name); - body->collide = true; + body->mCollide = true; body->getWorldTransform().setOrigin(btVector3( (x+0.5)*triSize*(sqrtVerts-1), (y+0.5)*triSize*(sqrtVerts-1), (maxh+minh)/2.f)); HeightField hf; @@ -397,7 +398,8 @@ namespace Physic //create the real body btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); RigidBody* body = new RigidBody(CI,name); - body->collide = shape->collide; + body->mCollide = shape->mCollide; + body->mIgnore = shape->mIgnore; if(scaledBoxTranslation != 0) *scaledBoxTranslation = shape->boxTranslation * scale; @@ -414,7 +416,9 @@ namespace Physic { if(body) { - if(body->collide) + if (body->mIgnore) + return; + if(body->mCollide) { dynamicsWorld->addRigidBody(body,COL_WORLD,COL_WORLD|COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL); } diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index e4e71706f..f320d009d 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -152,7 +152,8 @@ namespace Physic std::string mName; //is this body used for raycasting only? - bool collide; + bool mCollide; + bool mIgnore; }; struct HeightField From 0ab432b074243f157520a80fd79e7df5ede9acde Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 25 Oct 2012 12:22:48 +0200 Subject: [PATCH 072/255] Issue #68: fixed death detection --- apps/openmw/mwmechanics/creaturestats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 8be4b9369..1e57ba313 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -176,7 +176,7 @@ namespace MWMechanics mDynamic[index] = value; - if (index==2 && mDynamic[index].getCurrent()<1) + if (index==0 && mDynamic[index].getCurrent()<1) mDead = true; } From 21c24dedb63971c6c1d61b136ff4414964cd8b9f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 25 Oct 2012 12:28:45 +0200 Subject: [PATCH 073/255] Issue #68: Stop player from dying (temporary workaround) --- apps/openmw/mwmechanics/actors.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index e8b6fc14d..0623db4b1 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -213,7 +213,27 @@ namespace MWMechanics } if (MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead()) + { + // workaround: always keep player alive for now + // \todo remove workaround, once player death can be handled + if (iter->getRefData().getHandle()=="player") + { + MWMechanics::DynamicStat stat ( + MWWorld::Class::get (*iter).getCreatureStats (*iter).getHealth()); + + if (stat.getModified()<1) + { + stat.setModified (1, 0); + MWWorld::Class::get (*iter).getCreatureStats (*iter).setHealth (stat); + } + + MWWorld::Class::get (*iter).getCreatureStats (*iter).resurrect(); + ++iter; + continue; + } + mActors.erase (iter++); + } else ++iter; } From 9f923e7963a00e13e6e288e1867f6f1089434d4f Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 25 Oct 2012 15:14:34 +0400 Subject: [PATCH 074/255] fix crashing if /home/greye/.cache not exist --- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 21299e25c..5b5fdce68 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -67,7 +67,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const // material system sh::OgrePlatform* platform = new sh::OgrePlatform("General", (resDir / "materials").string()); if (!boost::filesystem::exists (cacheDir)) - boost::filesystem::create_directory (cacheDir); + boost::filesystem::create_directories (cacheDir); platform->setCacheFolder (cacheDir.string()); mFactory = new sh::Factory(platform); From 5d45d328b8e1d6359555dd95c757ac83d76d78b5 Mon Sep 17 00:00:00 2001 From: bwrsandman Date: Fri, 26 Oct 2012 21:28:22 -0400 Subject: [PATCH 075/255] Fixed uninitialized variable that caused a segfault when going to previous page. --- apps/openmw/mwgui/journalwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 597c27c6d..9d5d236be 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -85,6 +85,7 @@ MWGui::JournalWindow::JournalWindow (MWBase::WindowManager& parWindowManager) : WindowBase("openmw_journal.layout", parWindowManager) , mLastPos(0) , mVisible(false) + , mPageNumber(0) { //setCoord(0,0,498, 342); center(); From 6b09b3ad61ac9959c640fb70b0051264dce06739 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Oct 2012 10:36:42 +0200 Subject: [PATCH 076/255] Issue #68: Play death animations --- apps/openmw/mwmechanics/actors.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0623db4b1..5c1560032 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -167,6 +167,8 @@ namespace MWMechanics { if (!MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead()) mActors.insert (ptr); + else + MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, "death1", 2); } void Actors::removeActor (const MWWorld::Ptr& ptr) @@ -231,7 +233,9 @@ namespace MWMechanics ++iter; continue; } - + + MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0); + mActors.erase (iter++); } else From f72c35fc172c5d66596fdac5588b8eebe2a5123e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Oct 2012 11:15:52 +0200 Subject: [PATCH 077/255] Issue #68: tally deaths --- apps/openmw/mwmechanics/actors.cpp | 2 ++ apps/openmw/mwmechanics/actors.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 5c1560032..0b1d0ba04 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -234,6 +234,8 @@ namespace MWMechanics continue; } + ++mDeathCount[MWWorld::Class::get (*iter).getId (*iter)]; + MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0); mActors.erase (iter++); diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index f8a00f349..fb6a42c47 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace Ogre { @@ -22,6 +23,7 @@ namespace MWMechanics { std::set mActors; float mDuration; + std::map mDeathCount; void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused); From 453f347ee8f0d801cc67dd9be63afa7574358fc7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Oct 2012 11:33:18 +0200 Subject: [PATCH 078/255] Issue #68: added getdeadcount script function --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 +++ apps/openmw/mwmechanics/actors.cpp | 10 ++++++++++ apps/openmw/mwmechanics/actors.hpp | 3 +++ apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 5 +++++ apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 4 ++++ apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/statsextensions.cpp | 17 +++++++++++++++++ 7 files changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index c5d721e26..750fc2fff 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -76,6 +76,9 @@ namespace MWBase virtual void restoreDynamicStats() = 0; ///< If the player is sleeping, this should be called every hour. + + virtual int countDeaths (const std::string& id) const = 0; + ///< Return the number of deaths for actors with the given ID. }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0b1d0ba04..1c9fefa16 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -262,4 +262,14 @@ namespace MWMechanics calculateRestoration (*iter, 3600); } } + + int Actors::countDeaths (const std::string& id) const + { + std::map::const_iterator iter = mDeathCount.find (id); + + if (iter!=mDeathCount.end()) + return iter->second; + + return 0; + } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index fb6a42c47..79ae16fc3 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -63,6 +63,9 @@ namespace MWMechanics void restoreDynamicStats(); ///< If the player is sleeping, this should be called every hour. + + int countDeaths (const std::string& id) const; + ///< Return the number of deaths for actors with the given ID. }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 6d8bdb332..873dd9498 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -326,4 +326,9 @@ namespace MWMechanics buildPlayer(); mUpdatePlayer = true; } + + int MechanicsManager::countDeaths (const std::string& id) const + { + return mActors.countDeaths (id); + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 205deaf71..38536d3bd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -78,6 +78,10 @@ namespace MWMechanics virtual void restoreDynamicStats(); ///< If the player is sleeping, this should be called every hour. + + virtual int countDeaths (const std::string& id) const; + ///< Return the number of deaths for actors with the given ID. + }; } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 584a29926..cb984e257 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -206,5 +206,6 @@ op 0x200019f: GetPcSleep op 0x20001a0: ShowMap op 0x20001a1: FillMap op 0x20001a2: WakeUpPc -opcodes 0x20001a3-0x3ffffff unused +op 0x20001a3: GetDeadCount +opcodes 0x20001a4-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index fc57bb654..0d69608e1 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -17,6 +17,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -591,6 +592,17 @@ namespace MWScript /// \todo modify disposition towards the player } }; + + class OpGetDeadCount : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths (id); + } + }; const int numberOfAttributes = 8; @@ -643,6 +655,8 @@ namespace MWScript const int opcodeGetLevelExplicit = 0x200018d; const int opcodeSetLevel = 0x200018e; const int opcodeSetLevelExplicit = 0x200018f; + + const int opcodeGetDeadCount = 0x20001a3; void registerExtensions (Compiler::Extensions& extensions) { @@ -729,6 +743,8 @@ namespace MWScript extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit); extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit); + + extensions.registerFunction("getdeadcount", 'l', "c", opcodeGetDeadCount); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -806,6 +822,7 @@ namespace MWScript interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel); interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel); + interpreter.installSegment5 (opcodeGetDeadCount, new OpGetDeadCount); } } } From ed3641b21445f26de214cd2ea7a64d50d98b9ddc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Oct 2012 13:33:54 +0200 Subject: [PATCH 079/255] Issue #68: check for essential actors --- apps/openmw/mwclass/creature.cpp | 8 ++++++++ apps/openmw/mwclass/creature.hpp | 3 +++ apps/openmw/mwclass/npc.cpp | 8 ++++++++ apps/openmw/mwclass/npc.hpp | 3 +++ apps/openmw/mwmechanics/actors.cpp | 4 ++++ apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 5 +++++ 7 files changed, 36 insertions(+) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0fb9daf19..e007c50ab 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -149,6 +149,14 @@ namespace MWClass return ref->base->mScript; } + bool Creature::isEssential (const MWWorld::Ptr& ptr) const + { + MWWorld::LiveCellRef *ref = + ptr.get(); + + return ref->base->mFlags & ESM::Creature::Essential; + } + void Creature::registerSelf() { boost::shared_ptr instance (new Creature); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 4de877b31..a158fa743 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -56,6 +56,9 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. + virtual bool isEssential (const MWWorld::Ptr& ptr) const; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + static void registerSelf(); virtual std::string getModel(const MWWorld::Ptr &ptr) const; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index bcde31b26..ef3946efe 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -315,7 +315,15 @@ namespace MWClass return vector; } + + bool Npc::isEssential (const MWWorld::Ptr& ptr) const + { + MWWorld::LiveCellRef *ref = + ptr.get(); + return ref->base->mFlags & ESM::NPC::Essential; + } + void Npc::registerSelf() { boost::shared_ptr instance (new Npc); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index edb6ca40f..20c2da4b1 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -90,6 +90,9 @@ namespace MWClass virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; + virtual bool isEssential (const MWWorld::Ptr& ptr) const; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + static void registerSelf(); virtual std::string getModel(const MWWorld::Ptr &ptr) const; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 1c9fefa16..f3b6b1616 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -238,6 +238,10 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0); + if (MWWorld::Class::get (*iter).isEssential (*iter)) + MWBase::Environment::get().getWindowManager()->messageBox ( + "#{sKilledEssential}", std::vector()); + mActors.erase (iter++); } else diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 5267e368d..8c639a874 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -157,6 +157,11 @@ namespace MWWorld throw std::runtime_error ("encumbrance not supported by class"); } + bool Class::isEssential (const MWWorld::Ptr& ptr) const + { + return false; + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 3c3b0e34b..4662cbab6 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -186,6 +186,11 @@ namespace MWWorld /// /// (default implementations: throws an exception) + virtual bool isEssential (const MWWorld::Ptr& ptr) const; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + /// + /// (default implementation: return false) + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. From d7add0b9e679c1a7db6c2df0a288fc2bdafac083 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 28 Oct 2012 14:07:36 +0100 Subject: [PATCH 080/255] Issue #61: fixed alchemy skill --- apps/openmw/mwmechanics/alchemy.cpp | 62 +++++++---------------------- apps/openmw/mwmechanics/alchemy.hpp | 5 +-- 2 files changed, 15 insertions(+), 52 deletions(-) diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index df7c786b1..962350472 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -28,7 +29,7 @@ std::set MWMechanics::Alchemy::listEffects() const { - std::set effects; + std::map effects; for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) { @@ -38,57 +39,23 @@ std::set MWMechanics::Alchemy::listEffects() const for (int i=0; i<4; ++i) if (ingredient->base->mData.mEffectID[i]!=-1) - effects.insert (EffectKey ( + { + EffectKey key ( ingredient->base->mData.mEffectID[i], ingredient->base->mData.mSkills[i]!=-1 ? - ingredient->base->mData.mSkills[i] : ingredient->base->mData.mAttributes[i])); + ingredient->base->mData.mSkills[i] : ingredient->base->mData.mAttributes[i]); + + ++effects[key]; + } } } - return effects; -} - -void MWMechanics::Alchemy::filterEffects (std::set& effects) const -{ - std::set::iterator iter = effects.begin(); + std::set effects2; - while (iter!=effects.end()) - { - bool remove = false; - - const EffectKey& key = *iter; - - { // dodge pointless g++ warning - for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) - { - bool found = false; - - if (iter->isEmpty()) - continue; - - const MWWorld::LiveCellRef *ingredient = iter->get(); - - for (int i=0; i<4; ++i) - if (key.mId==ingredient->base->mData.mEffectID[i] && - (key.mArg==ingredient->base->mData.mSkills[i] || - key.mArg==ingredient->base->mData.mAttributes[i])) - { - found = true; - break; - } - - if (!found) - { - remove = true; - break; - } - } - } - - if (remove) - effects.erase (iter++); - else - ++iter; - } + for (std::map::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) + if (iter->second>1) + effects2.insert (iter->first); + + return effects2; } void MWMechanics::Alchemy::applyTools (int flags, float& value) const @@ -159,7 +126,6 @@ void MWMechanics::Alchemy::updateEffects() // find effects std::set effects (listEffects()); - filterEffects (effects); // general alchemy factor float x = getChance(); diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 7f3e2c0ea..957e3122c 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -46,10 +46,7 @@ namespace MWMechanics int mValue; std::set listEffects() const; - ///< List all effects of all used ingredients. - - void filterEffects (std::set& effects) const; - ///< Filter out effects not shared by all ingredients. + ///< List all effects shared by at least two ingredients. void applyTools (int flags, float& value) const; From a04df37f83097ac5b88a6fd98a43623eea2caa97 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 28 Oct 2012 16:04:33 +0100 Subject: [PATCH 081/255] implemented looting corpses --- apps/openmw/mwclass/creature.cpp | 6 +++++- apps/openmw/mwclass/npc.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index e007c50ab..e4ff3c95b 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -12,6 +12,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" +#include "../mwworld/actionopen.hpp" #include "../mwworld/customdata.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/physicssystem.hpp" @@ -130,7 +131,10 @@ namespace MWClass boost::shared_ptr Creature::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); + if (MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead()) + return boost::shared_ptr (new MWWorld::ActionOpen(ptr)); + else + return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); } MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ef3946efe..2e21f8f63 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -20,6 +20,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" +#include "../mwworld/actionopen.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/customdata.hpp" #include "../mwworld/physicssystem.hpp" @@ -189,7 +190,10 @@ namespace MWClass boost::shared_ptr Npc::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); + if (MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead()) + return boost::shared_ptr (new MWWorld::ActionOpen(ptr)); + else + return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); } MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr) From d065b56948954a2809b22e78d6515a8725cb827c Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 04:21:31 +0100 Subject: [PATCH 082/255] Fixed default profile adding and made switching profiles more efficient --- apps/launcher/datafilespage.cpp | 4 +++- apps/launcher/maindialog.cpp | 21 ++------------------- apps/launcher/maindialog.hpp | 1 - 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 01b879842..696b37819 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -251,7 +251,7 @@ void DataFilesPage::setupConfig() } // Add a default profile - if (mProfilesComboBox->count() == 0) { + if (mProfilesComboBox->findText(QString("Default")) == -1) { mProfilesComboBox->addItem(QString("Default")); } @@ -359,6 +359,8 @@ bool DataFilesPage::setupDataFiles() ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")); + //boost::program_options::notify(variables); + mCfgMgr.readConfiguration(variables, desc); // Put the paths in a boost::filesystem vector to use with Files::Collections diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 3ce418ddf..674ccdf67 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -141,11 +141,11 @@ void MainDialog::createPages() connect(mPlayPage->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(profileChanged(int))); + mDataFilesPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); connect(mDataFilesPage->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(profileChanged(int))); + mPlayPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); } @@ -196,23 +196,6 @@ bool MainDialog::setup() return true; } -void MainDialog::profileChanged(int index) -{ - // Just to be sure, should always have a selection - if (!mIconWidget->selectionModel()->hasSelection()) { - return; - } - - QString currentPage = mIconWidget->currentItem()->data(Qt::DisplayRole).toString(); - if (currentPage == QLatin1String("Play")) { - mDataFilesPage->mProfilesComboBox->setCurrentIndex(index); - } - - if (currentPage == QLatin1String("Data Files")) { - mPlayPage->mProfilesComboBox->setCurrentIndex(index); - } -} - void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { if (!current) diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index 683cd58c2..bf98011cc 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -27,7 +27,6 @@ public: public slots: void changePage(QListWidgetItem *current, QListWidgetItem *previous); void play(); - void profileChanged(int index); bool setup(); private: From ef11a32fee482b630def1e7282d3c170c9832080 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 05:03:58 +0100 Subject: [PATCH 083/255] Fixed a bug where a non-existant openmw.cfg would crash the launcher --- apps/launcher/datafilespage.cpp | 87 +++++++++++++++++++-------------- apps/launcher/datafilespage.hpp | 1 + 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 696b37819..50502f6e2 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -347,6 +347,47 @@ void DataFilesPage::readConfig() } +bool DataFilesPage::showDataFilesWarning() +{ + + QMessageBox msgBox; + msgBox.setWindowTitle("Error detecting Morrowind installation"); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("
Could not find the Data Files location

\ + The directory containing the data files was not found.

\ + Press \"Browse...\" to specify the location manually.
")); + + QAbstractButton *dirSelectButton = + msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole); + + msgBox.exec(); + + if (msgBox.clickedButton() == dirSelectButton) { + + // Show a custom dir selection dialog which only accepts valid dirs + QString selectedDir = FileDialog::getExistingDirectory( + this, tr("Select Data Files Directory"), + QDir::currentPath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + // Add the user selected data directory + if (!selectedDir.isEmpty()) { + mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString())); + mCfgMgr.processPaths(mDataDirs); + } else { + // Cancel from within the dir selection dialog + return false; + } + + } else { + // Cancel + return false; + } + + return true; +} + bool DataFilesPage::setupDataFiles() { // We use the Configuration Manager to retrieve the configuration values @@ -359,12 +400,16 @@ bool DataFilesPage::setupDataFiles() ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")); - //boost::program_options::notify(variables); + boost::program_options::notify(variables); mCfgMgr.readConfiguration(variables, desc); - // Put the paths in a boost::filesystem vector to use with Files::Collections - mDataDirs = Files::PathContainer(variables["data"].as()); + if (variables["data"].empty()) { + if (!showDataFilesWarning()) + return false; + } else { + mDataDirs = Files::PathContainer(variables["data"].as()); + } std::string local = variables["data-local"].as(); if (!local.empty()) { @@ -374,43 +419,11 @@ bool DataFilesPage::setupDataFiles() mCfgMgr.processPaths(mDataDirs); mCfgMgr.processPaths(mDataLocal); + // Second chance to display the warning, the data= entries are invalid while (mDataDirs.empty()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Error detecting Morrowind installation"); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("
Could not find the Data Files location

\ - The directory containing the data files was not found.

\ - Press \"Browse...\" to specify the location manually.
")); - - QAbstractButton *dirSelectButton = - msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() == dirSelectButton) { - - // Show a custom dir selection dialog which only accepts valid dirs - QString selectedDir = FileDialog::getExistingDirectory( - this, tr("Select Data Files Directory"), - QDir::currentPath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - // Add the user selected data directory - if (!selectedDir.isEmpty()) { - mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString())); - mCfgMgr.processPaths(mDataDirs); - } else { - // Cancel from within the dir selection dialog - return false; - } - - } else { - // Cancel + if (!showDataFilesWarning()) return false; - } } - // Add the paths to the respective models for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { QString path = QString::fromStdString(it->string()); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 8b48c1e12..13668ec30 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -30,6 +30,7 @@ public: ProfilesComboBox *mProfilesComboBox; void writeConfig(QString profile = QString()); + bool showDataFilesWarning(); bool setupDataFiles(); public slots: From 1c06a06f91b6e9ae41e9dd316663aae4eb426b98 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 06:47:39 +0100 Subject: [PATCH 084/255] Files are now sorted by modified timestamp, fixes Bug #415 --- apps/launcher/datafilespage.cpp | 11 +++-- apps/launcher/model/datafilesmodel.cpp | 57 +++++++++++++++++--------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 50502f6e2..782c4fb01 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -424,6 +424,7 @@ bool DataFilesPage::setupDataFiles() if (!showDataFilesWarning()) return false; } + // Add the paths to the respective models for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { QString path = QString::fromStdString(it->string()); @@ -440,8 +441,10 @@ bool DataFilesPage::setupDataFiles() mPluginsModel->addPlugins(path); } -// mMastersModel->sort(0); -// mPluginsModel->sort(0); + mMastersModel->sort(0); + mPluginsModel->sort(0); +// mMastersTable->sortByColumn(3, Qt::AscendingOrder); +// mPluginsTable->sortByColumn(3, Qt::AscendingOrder); readConfig(); @@ -734,8 +737,8 @@ void DataFilesPage::setCheckState(QModelIndex index) QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); (mPluginsModel->checkState(sourceIndex) == Qt::Checked) - ? mPluginsModel->setCheckState(index, Qt::Unchecked) - : mPluginsModel->setCheckState(index, Qt::Checked); + ? mPluginsModel->setCheckState(sourceIndex, Qt::Unchecked) + : mPluginsModel->setCheckState(sourceIndex, Qt::Checked); } if (object->objectName() == QLatin1String("MastersTable")) { diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index 0aa29a337..d4674b953 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -96,15 +96,11 @@ QVariant DataFilesModel::data(const QModelIndex &index, int role) const case Qt::TextAlignmentRole: { switch (column) { case 0: - return Qt::AlignLeft + Qt::AlignVCenter; case 1: return Qt::AlignLeft + Qt::AlignVCenter; case 2: - return Qt::AlignRight + Qt::AlignVCenter; case 3: - return Qt::AlignRight + Qt::AlignVCenter; case 4: - return Qt::AlignRight + Qt::AlignVCenter; case 5: return Qt::AlignRight + Qt::AlignVCenter; default: @@ -218,20 +214,34 @@ void DataFilesModel::sort(int column, Qt::SortOrder order) // TODO: Make this more efficient emit layoutAboutToBeChanged(); - // A reference list we can sort - QStringList all = uncheckedItems(); - //all.append(uncheckedItems()); - // Sort the list of items naturally - qSort(all.begin(), all.end(), naturalSortLessThanCI); + QMap timestamps; - for (int i = 0; i < all.size(); ++i) { - const QString currentItem = all.at(i); - QModelIndex index = indexFromItem(findItem(currentItem)); + QList::ConstIterator it; + QList::ConstIterator itEnd = mFiles.constEnd(); - // Move the actual item from the old position to the new - if (index.isValid()) + // Make a list of files sorted by timestamp + int i = 0; + for (it = mFiles.constBegin(); it != itEnd; ++it) { + EsmFile *file = item(i); + ++i; + timestamps[file->modified().toString(Qt::ISODate)] = file->fileName(); + } + + + // Now sort the actual list of files by timestamp + i = 0; + QMapIterator ti(timestamps); + while (ti.hasNext()) { + ti.next(); + i++; + + QModelIndex index = indexFromItem(findItem(ti.value())); + + if (index.isValid()) { mFiles.swap(index.row(), i); + } + } emit layoutChanged(); @@ -381,13 +391,20 @@ EsmFile* DataFilesModel::item(int row) QStringList DataFilesModel::checkedItems() { QStringList list; - QHash::ConstIterator it; - QHash::ConstIterator itEnd = mCheckStates.constEnd(); - for (it = mCheckStates.constBegin(); it != itEnd; ++it) { - if (it.value() == Qt::Checked) { - list << it.key(); - } + QList::ConstIterator it; + QList::ConstIterator itEnd = mFiles.constEnd(); + + int i = 0; + for (it = mFiles.constBegin(); it != itEnd; ++it) { + EsmFile *file = item(i); + ++i; + + QString name = file->fileName(); + + // Only add the items that are in the checked list and available + if (mCheckStates[name] == Qt::Checked && mAvailableFiles.contains(name)) + list << name; } return list; From 6e758af05c4898634a4f97dd1b2e41848800947a Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 06:51:22 +0100 Subject: [PATCH 085/255] Launcher cfg is stored in the user location only, fixes Bug #414 --- apps/launcher/datafilespage.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 782c4fb01..32bd9acb7 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -220,16 +220,9 @@ void DataFilesPage::createActions() void DataFilesPage::setupConfig() { - QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "launcher.cfg").string()); - QFile file(config); - - if (!file.exists()) { - config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); - } - // Open our config file + QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); mLauncherConfig = new QSettings(config, QSettings::IniFormat); - file.close(); // Make sure we have no groups open while (!mLauncherConfig->group().isEmpty()) { From 6920958e160149705c2c407839adba6e713d72ea Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 10:08:24 +0100 Subject: [PATCH 086/255] Oops, forgot to add timestamps for master files --- apps/launcher/model/datafilesmodel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index d4674b953..40dd78fce 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -281,6 +281,7 @@ void DataFilesModel::addMasters(const QString &path) continue; EsmFile *file = new EsmFile(master); + file->setDates(info.lastModified(), info.lastRead()); // Add the master to the table if (findItem(master) == 0) @@ -299,9 +300,12 @@ void DataFilesModel::addMasters(const QString &path) dir.setNameFilters(QStringList(QLatin1String("*.esm"))); foreach (const QString &path, dir.entryList()) { + QFileInfo info(dir.absoluteFilePath(path)); if (findItem(path) == 0) { EsmFile *file = new EsmFile(path); + file->setDates(info.lastModified(), info.lastRead()); + addFile(file); } From 433773e0eadb28823fff44151ba5059b1ab56c81 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 11:10:06 +0100 Subject: [PATCH 087/255] Fixed segfault in datafilesmodel because of invalid modelindex row --- apps/launcher/model/datafilesmodel.cpp | 13 ++++++++----- apps/launcher/model/datafilesmodel.hpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index 40dd78fce..30453425b 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -60,10 +60,10 @@ QVariant DataFilesModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); -// if (index.row() < 0 || index.row() >= mPlugins.size()) -// return QVariant(); + EsmFile *file = item(index.row()); - EsmFile *file = mFiles.at(index.row()); + if (!file) + return QVariant(); const int column = index.column(); @@ -146,7 +146,10 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::NoItemFlags; - EsmFile *file = mFiles.at(index.row()); + EsmFile *file = item(index.row()); + + if (!file) + return Qt::NoItemFlags; if (mAvailableFiles.contains(file->fileName())) { if (index.column() == 0) { @@ -384,7 +387,7 @@ EsmFile* DataFilesModel::findItem(const QString &name) return 0; } -EsmFile* DataFilesModel::item(int row) +EsmFile* DataFilesModel::item(int row) const { if (row >= 0 && row < mFiles.count()) return mFiles.at(row); diff --git a/apps/launcher/model/datafilesmodel.hpp b/apps/launcher/model/datafilesmodel.hpp index 8710ba88d..d45788c3c 100644 --- a/apps/launcher/model/datafilesmodel.hpp +++ b/apps/launcher/model/datafilesmodel.hpp @@ -47,7 +47,7 @@ public: QModelIndex indexFromItem(EsmFile *item) const; EsmFile* findItem(const QString &name); - EsmFile* item(int row); + EsmFile* item(int row) const; signals: void checkedItemsChanged(const QStringList checkedItems, const QStringList unCheckedItems); From 64c348c39ed6cc6fe5de0e042d7b1fb53c14cf25 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 30 Oct 2012 11:26:48 +0100 Subject: [PATCH 088/255] Added support for different encodings --- apps/launcher/datafilespage.cpp | 7 +++++++ apps/launcher/model/datafilesmodel.cpp | 10 ++++++++-- apps/launcher/model/datafilesmodel.hpp | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 32bd9acb7..6b0539c1d 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -418,6 +418,13 @@ bool DataFilesPage::setupDataFiles() return false; } + // Set the charset for reading the esm/esp files + QString encoding = QString::fromStdString(variables["encoding"].as()); + if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) { + mMastersModel->setEncoding(encoding); + mPluginsModel->setEncoding(encoding); + } + // Add the paths to the respective models for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { QString path = QString::fromStdString(it->string()); diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index 30453425b..68f9336f2 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -13,12 +13,18 @@ DataFilesModel::DataFilesModel(QObject *parent) : QAbstractTableModel(parent) { + mEncoding = QString("win1252"); } DataFilesModel::~DataFilesModel() { } +void DataFilesModel::setEncoding(const QString &encoding) +{ + mEncoding = encoding; +} + void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) { setData(index, state, Qt::CheckStateRole); @@ -268,7 +274,7 @@ void DataFilesModel::addMasters(const QString &path) try { ESM::ESMReader fileReader; - fileReader.setEncoding(std::string("win1252")); + fileReader.setEncoding(mEncoding.toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString()); ESM::ESMReader::MasterList mlist = fileReader.getMasters(); @@ -328,7 +334,7 @@ void DataFilesModel::addPlugins(const QString &path) try { ESM::ESMReader fileReader; - fileReader.setEncoding(std::string("win1252")); + fileReader.setEncoding(mEncoding.toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString()); ESM::ESMReader::MasterList mlist = fileReader.getMasters(); diff --git a/apps/launcher/model/datafilesmodel.hpp b/apps/launcher/model/datafilesmodel.hpp index d45788c3c..29a770a86 100644 --- a/apps/launcher/model/datafilesmodel.hpp +++ b/apps/launcher/model/datafilesmodel.hpp @@ -32,6 +32,8 @@ public: inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const { return QAbstractTableModel::index(row, column, parent); } + void setEncoding(const QString &encoding); + void addFile(EsmFile *file); void addMasters(const QString &path); @@ -62,6 +64,8 @@ private: QHash mDependencies; QHash mCheckStates; + QString mEncoding; + }; #endif // DATAFILESMODEL_HPP From 60aea3653fcf0703a9fc8ba2625295d0b8e24fca Mon Sep 17 00:00:00 2001 From: pvdk Date: Tue, 30 Oct 2012 18:58:17 +0100 Subject: [PATCH 089/255] Modified sorting, should not crash anymore --- apps/launcher/model/datafilesmodel.cpp | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index 68f9336f2..70b9d0ca7 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -223,36 +223,34 @@ void DataFilesModel::sort(int column, Qt::SortOrder order) // TODO: Make this more efficient emit layoutAboutToBeChanged(); + QList sortedFiles; - QMap timestamps; + QMultiMap timestamps; - QList::ConstIterator it; - QList::ConstIterator itEnd = mFiles.constEnd(); + foreach (EsmFile *file, mFiles) + timestamps.insert(file->modified().toString(Qt::ISODate), file->fileName()); - // Make a list of files sorted by timestamp - int i = 0; - for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = item(i); - ++i; - timestamps[file->modified().toString(Qt::ISODate)] = file->fileName(); - } - - - // Now sort the actual list of files by timestamp - i = 0; QMapIterator ti(timestamps); + while (ti.hasNext()) { ti.next(); - i++; QModelIndex index = indexFromItem(findItem(ti.value())); - if (index.isValid()) { - mFiles.swap(index.row(), i); - } + if (!index.isValid()) + continue; + EsmFile *file = item(index.row()); + + if (!file) + continue; + + sortedFiles.append(file); } + mFiles.clear(); + mFiles = sortedFiles; + emit layoutChanged(); } @@ -301,6 +299,7 @@ void DataFilesModel::addMasters(const QString &path) } catch(std::runtime_error &e) { // An error occurred while reading the .esp + qWarning() << "Error reading esp: " << e.what(); continue; } } @@ -361,6 +360,7 @@ void DataFilesModel::addPlugins(const QString &path) addFile(file); } catch(std::runtime_error &e) { // An error occurred while reading the .esp + qWarning() << "Error reading esp: " << e.what(); continue; } From b0647d6c8a8f4057594f1b2e6c61f51fa1badc9f Mon Sep 17 00:00:00 2001 From: pvdk Date: Tue, 30 Oct 2012 19:05:44 +0100 Subject: [PATCH 090/255] Fix for Bug #413: resolutions no longer appear multiple times on Windows --- apps/launcher/graphicspage.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 7685cb3c2..2c4f3430c 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -281,20 +281,18 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) assert (tokens.size() >= 3); QString resolutionStr = tokens.at(0) + QString(" x ") + tokens.at(2); - // do not add duplicate resolutions - if (!result.contains(resolutionStr)) { + QString aspect = getAspect(tokens.at(0).toInt(),tokens.at(2).toInt()); - QString aspect = getAspect(tokens.at(0).toInt(),tokens.at(2).toInt()); + if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { + resolutionStr.append(tr("\t(Widescreen ") + aspect + ")"); - if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { - resolutionStr.append(tr("\t(Widescreen ") + aspect + ")"); - - } else if (aspect == QLatin1String("4:3")) { - resolutionStr.append(tr("\t(Standard 4:3)")); - } - - result << resolutionStr; + } else if (aspect == QLatin1String("4:3")) { + resolutionStr.append(tr("\t(Standard 4:3)")); } + + // do not add duplicate resolutions + if (!result.contains(resolutionStr)) + result << resolutionStr; } } From 648b53ef9352477cbedc7ae36a512f1736ff52c7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 31 Oct 2012 10:09:27 +0100 Subject: [PATCH 091/255] removed unused launcher.cfg file --- CMakeLists.txt | 1 - apps/launcher/CMakeLists.txt | 5 ----- files/launcher.cfg | 5 ----- 3 files changed, 11 deletions(-) delete mode 100644 files/launcher.cfg diff --git a/CMakeLists.txt b/CMakeLists.txt index b10562eef..a6fdfceb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -659,7 +659,6 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE) #INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" ) INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" ) INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" ) - INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.cfg" DESTINATION "${SYSCONFDIR}" ) # Install resources INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" ) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index edc3dcf32..09beaf59d 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -101,8 +101,6 @@ endif() if (APPLE) configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss "${APP_BUNDLE_DIR}/../launcher.qss") - configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg - "${APP_BUNDLE_DIR}/../launcher.cfg") else() configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/resources/launcher.qss") @@ -110,9 +108,6 @@ else() # Fallback in case getGlobalDataPath does not point to resources configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss") - - configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg - "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.cfg") endif() if (BUILD_WITH_CODE_COVERAGE) diff --git a/files/launcher.cfg b/files/launcher.cfg deleted file mode 100644 index bc0e2b7fb..000000000 --- a/files/launcher.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[Profiles] -CurrentProfile=Default -Default\Master0=Morrowind.esm -Default\Master1=Tribunal.esm -Default\Master2=Bloodmoon.esm From 4bc4ca775cfd36b6fdd97dbaa071dc79a3c947ec Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Nov 2012 15:11:13 +0100 Subject: [PATCH 092/255] Issue #432: fixed MWWorld::ContainerStore::clear --- apps/openmw/mwworld/containerstore.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 3bc06b581..5c4dd03a4 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -167,18 +167,8 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS: void MWWorld::ContainerStore::clear() { - potions.list.clear(); - appas.list.clear(); - armors.list.clear(); - books.list.clear(); - clothes.list.clear(); - ingreds.list.clear(); - lights.list.clear(); - lockpicks.list.clear(); - miscItems.list.clear(); - probes.list.clear(); - repairs.list.clear(); - weapons.list.clear(); + for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter) + iter->getRefData().setCount (0); flagAsModified(); } From 37a42c7dbc1f700ee71a8abca41dea0717e7568d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 1 Nov 2012 16:38:07 +0100 Subject: [PATCH 093/255] increased version number; updated changelog --- CMakeLists.txt | 2 +- readme.txt | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6fdfceb1..78388e20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 18) +set (OPENMW_VERSION_MINOR 19) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") diff --git a/readme.txt b/readme.txt index 20aff18ae..9a9010994 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.18.0 +Version: 0.19.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org @@ -97,6 +97,32 @@ Allowed options: CHANGELOG +0.19.0 + +Bug #374: Character shakes in 3rd person mode near the origin +Bug #404: Gamma correct rendering +Bug #407: Shoes of St. Rilm do not work +Bug #408: Rugs has collision even if they are not supposed to +Bug #412: Birthsign menu sorted incorrectly +Bug #413: Resolutions presented multiple times in launcher +Bug #414: launcher.cfg file stored in wrong directory +Bug #415: Wrong esm order in openmw.cfg +Bug #418: Sound listener position updates incorrectly +Bug #423: wrong usage of "Version" entry in openmw.desktop +Bug #426: Do not use hardcoded splash images +Bug #431: Don't use markers for raycast +Bug #432: Crash after picking up items from an NPC +Feature #21/#95: Sleeping/resting +Feature #61: Alchemy Skill +Feature #68: Death +Feature #69/#86: Spell Creation +Feature #72/#84: Travel +Feature #76: Global Map, 1st Layer +Feature #120: Trainer Window +Feature #152: Skill Increase from Skill Books +Feature #160: Record Saving +Task #400: Review GMST access + 0.18.0 Bug #310: Button of the "preferences menu" are too small From 8cdd1e553968b76d893ae3731b5e2c08f72ff295 Mon Sep 17 00:00:00 2001 From: pvdk Date: Fri, 2 Nov 2012 15:06:14 +0100 Subject: [PATCH 094/255] Fixed problem with sorting of the masters in the launcher --- apps/launcher/model/datafilesmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index 70b9d0ca7..47811dcaf 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -268,8 +268,6 @@ void DataFilesModel::addMasters(const QString &path) // Read the dependencies from the plugins foreach (const QString &path, dir.entryList()) { - QFileInfo info(dir.absoluteFilePath(path)); - try { ESM::ESMReader fileReader; fileReader.setEncoding(mEncoding.toStdString()); @@ -287,6 +285,8 @@ void DataFilesModel::addMasters(const QString &path) if (master.endsWith(".esp", Qt::CaseInsensitive)) continue; + QFileInfo info(dir.absoluteFilePath(master)); + EsmFile *file = new EsmFile(master); file->setDates(info.lastModified(), info.lastRead()); From 15f972cc6256b26044ac1af4fbbf947c0e8bc037 Mon Sep 17 00:00:00 2001 From: emoose Date: Fri, 2 Nov 2012 20:33:08 +0000 Subject: [PATCH 095/255] fixes: compile: cast error; doors: key id case comparison; character creation: going from CharacterCreation to BirthDialog loses data; character creation: Class/Race/BirthDialog allowing no data; code: clean up a bit todo: going from CharacterCreation back to CreateClassDialog loses data --- apps/openmw/mwclass/door.cpp | 8 +++++- apps/openmw/mwgui/birth.cpp | 2 ++ apps/openmw/mwgui/charactercreation.cpp | 1 + apps/openmw/mwgui/class.cpp | 4 +++ apps/openmw/mwgui/race.cpp | 2 ++ apps/openmw/mwgui/stats_window.cpp | 2 +- apps/openmw/mwworld/physicssystem.cpp | 6 +---- apps/openmw/mwworld/scene.cpp | 33 +++++-------------------- 8 files changed, 24 insertions(+), 34 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index b94a24ed5..4687a8230 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -81,9 +81,15 @@ namespace MWClass bool needKey = ptr.getCellRef().mLockLevel>0; bool hasKey = false; std::string keyName; + + // make key id lowercase + std::string keyId = ptr.getCellRef().mKey; + std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { - if (it->getCellRef ().mRefID == ptr.getCellRef().mKey) + std::string refId = it->getCellRef().mRefID; + std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + if (refId == keyId) { hasKey = true; keyName = MWWorld::Class::get(*it).getName(*it); diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 284653aee..1cd542221 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -93,6 +93,8 @@ void BirthDialog::setBirthId(const std::string &birthId) void BirthDialog::onOkClicked(MyGUI::Widget* _sender) { + if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) + return; eventDone(this); } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index e5bcdbaf8..ad9866eca 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -232,6 +232,7 @@ void CharacterCreation::spawnDialog(const char id) mBirthSignDialog = 0; mBirthSignDialog = new BirthDialog(*mWM); mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen); + mBirthSignDialog->setBirthId(mPlayerBirthSignId); mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone); mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack); mBirthSignDialog->setVisible(true); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 8757b62a3..4c889d42d 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -148,6 +148,8 @@ void PickClassDialog::setClassId(const std::string &classId) void PickClassDialog::onOkClicked(MyGUI::Widget* _sender) { + if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE) + return; eventDone(this); } @@ -641,6 +643,8 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow) void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) { + if(getName().size() <= 0) + return; eventDone(this); } diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 019a59cf4..c68c0edad 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -149,6 +149,8 @@ void RaceDialog::close() void RaceDialog::onOkClicked(MyGUI::Widget* _sender) { + if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) + return; eventDone(this); } diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 5a670968e..665caaae1 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -67,7 +67,7 @@ StatsWindow::StatsWindow (MWBase::WindowManager& parWindowManager) for (int i = 0; i < ESM::Skill::Length; ++i) { mSkillValues.insert(std::pair >(i, MWMechanics::Stat())); - mSkillWidgetMap.insert(std::pair(i, nullptr)); + mSkillWidgetMap.insert(std::pair(i, (MyGUI::TextBox*)nullptr)); } MyGUI::WindowPtr t = static_cast(mMainWidget); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 8fa1976ac..a2825fee9 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -345,11 +345,7 @@ namespace MWWorld bool PhysicsSystem::toggleCollisionMode() { - if(playerphysics->ps.move_type==PM_NOCLIP) - playerphysics->ps.move_type=PM_NORMAL; - - else - playerphysics->ps.move_type=PM_NOCLIP; + playerphysics->ps.move_type = (playerphysics->ps.move_type == PM_NOCLIP ? PM_NORMAL : PM_NOCLIP); for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { if (it->first=="player") diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index f16077202..517025fb2 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -70,17 +70,9 @@ namespace MWWorld { std::cout << "Unloading cell\n"; ListHandles functor; - - - - - - + (*iter)->forEach(functor); - { - - // silence annoying g++ warning for (std::vector::const_iterator iter2 (functor.mHandles.begin()); iter2!=functor.mHandles.end(); ++iter2){ @@ -96,27 +88,20 @@ namespace MWWorld } } - mRendering.removeCell(*iter); - //mPhysics->removeObject("Unnamed_43"); + mRendering.removeCell(*iter); + //mPhysics->removeObject("Unnamed_43"); MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter); MWBase::Environment::get().getMechanicsManager()->dropActors (*iter); MWBase::Environment::get().getSoundManager()->stopSound (*iter); - mActiveCells.erase(*iter); - - - + mActiveCells.erase(*iter); } void Scene::loadCell (Ptr::CellStore *cell) { // register local scripts MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell); - - - - std::pair result = - mActiveCells.insert(cell); + std::pair result = mActiveCells.insert(cell); if(result.second) { @@ -138,16 +123,10 @@ namespace MWWorld mRendering.configureAmbient(*cell); mRendering.requestMap(cell); mRendering.configureAmbient(*cell); - } - } - void - Scene::playerCellChange( - MWWorld::CellStore *cell, - const ESM::Position& pos, - bool adjustPlayerPos) + void Scene::playerCellChange(MWWorld::CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos) { bool hasWater = cell->cell->mData.mFlags & cell->cell->HasWater; mPhysics->setCurrentWater(hasWater, cell->cell->mWater); From 4a9821dc652cd5e50dd76ed257d06a37bdfa6332 Mon Sep 17 00:00:00 2001 From: emoose Date: Fri, 2 Nov 2012 20:43:07 +0000 Subject: [PATCH 096/255] fix kdevelop indentation... --- apps/openmw/mwclass/door.cpp | 12 ++++++------ apps/openmw/mwgui/birth.cpp | 2 +- apps/openmw/mwgui/charactercreation.cpp | 2 +- apps/openmw/mwgui/class.cpp | 2 +- apps/openmw/mwgui/race.cpp | 2 +- apps/openmw/mwworld/physicssystem.cpp | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 4687a8230..f944391e1 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -81,14 +81,14 @@ namespace MWClass bool needKey = ptr.getCellRef().mLockLevel>0; bool hasKey = false; std::string keyName; - - // make key id lowercase - std::string keyId = ptr.getCellRef().mKey; - std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); + + // make key id lowercase + std::string keyId = ptr.getCellRef().mKey; + std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { - std::string refId = it->getCellRef().mRefID; - std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + std::string refId = it->getCellRef().mRefID; + std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); if (refId == keyId) { hasKey = true; diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 1cd542221..e79eee236 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -94,7 +94,7 @@ void BirthDialog::setBirthId(const std::string &birthId) void BirthDialog::onOkClicked(MyGUI::Widget* _sender) { if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) - return; + return; eventDone(this); } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index ad9866eca..e4b77287c 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -232,7 +232,7 @@ void CharacterCreation::spawnDialog(const char id) mBirthSignDialog = 0; mBirthSignDialog = new BirthDialog(*mWM); mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen); - mBirthSignDialog->setBirthId(mPlayerBirthSignId); + mBirthSignDialog->setBirthId(mPlayerBirthSignId); mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone); mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack); mBirthSignDialog->setVisible(true); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 4c889d42d..3e293a1b0 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -149,7 +149,7 @@ void PickClassDialog::setClassId(const std::string &classId) void PickClassDialog::onOkClicked(MyGUI::Widget* _sender) { if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE) - return; + return; eventDone(this); } diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index c68c0edad..9abb05390 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -150,7 +150,7 @@ void RaceDialog::close() void RaceDialog::onOkClicked(MyGUI::Widget* _sender) { if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) - return; + return; eventDone(this); } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index a2825fee9..3be85c7f3 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -345,7 +345,7 @@ namespace MWWorld bool PhysicsSystem::toggleCollisionMode() { - playerphysics->ps.move_type = (playerphysics->ps.move_type == PM_NOCLIP ? PM_NORMAL : PM_NOCLIP); + playerphysics->ps.move_type = (playerphysics->ps.move_type == PM_NOCLIP ? PM_NORMAL : PM_NOCLIP); for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { if (it->first=="player") From 96b56d98032b7453cc8e25b4f9d4a15f4697fc1a Mon Sep 17 00:00:00 2001 From: emoose Date: Fri, 2 Nov 2012 21:18:37 +0000 Subject: [PATCH 097/255] fixes: containers: key id case comparison --- apps/openmw/mwclass/container.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 28fa72378..07f1c26ce 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -95,9 +95,15 @@ namespace MWClass bool needKey = ptr.getCellRef().mLockLevel>0; bool hasKey = false; std::string keyName; + + // make key id lowercase + std::string keyId = ptr.getCellRef().mKey; + std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { - if (it->getCellRef ().mRefID == ptr.getCellRef().mKey) + std::string refId = it->getCellRef().mRefID; + std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + if (refId == keyId) { hasKey = true; keyName = MWWorld::Class::get(*it).getName(*it); From 1c8e941f0d49a439273169130e08c5b3e7a33b83 Mon Sep 17 00:00:00 2001 From: emoose Date: Fri, 2 Nov 2012 21:21:32 +0000 Subject: [PATCH 098/255] fix kdevelop indentation again... --- apps/openmw/mwclass/container.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 07f1c26ce..237f451f3 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -95,14 +95,14 @@ namespace MWClass bool needKey = ptr.getCellRef().mLockLevel>0; bool hasKey = false; std::string keyName; - - // make key id lowercase - std::string keyId = ptr.getCellRef().mKey; - std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); + + // make key id lowercase + std::string keyId = ptr.getCellRef().mKey; + std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { - std::string refId = it->getCellRef().mRefID; - std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + std::string refId = it->getCellRef().mRefID; + std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); if (refId == keyId) { hasKey = true; From b70b8cc4bc32ad8867e716e61f28973d0dd50a99 Mon Sep 17 00:00:00 2001 From: emoose Date: Sat, 3 Nov 2012 06:02:33 +0000 Subject: [PATCH 099/255] Fixed: character creation: make OK button grayed out/disabled (loses the hoverover when it's re-enabled though...) --- apps/openmw/mwgui/birth.cpp | 8 ++++++++ apps/openmw/mwgui/class.cpp | 8 ++++++++ apps/openmw/mwgui/race.cpp | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index e79eee236..56e566ffb 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -48,6 +48,7 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); + okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); updateBirths(); updateSpells(); @@ -82,6 +83,9 @@ void BirthDialog::setBirthId(const std::string &birthId) if (boost::iequals(*mBirthList->getItemDataAt(i), birthId)) { mBirthList->setIndexSelected(i); + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); break; } } @@ -108,6 +112,10 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + const std::string *birthId = mBirthList->getItemDataAt(_index); if (boost::iequals(mCurrentBirthId, *birthId)) return; diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 3e293a1b0..a798ca232 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -104,6 +104,7 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); + okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); updateClasses(); updateStats(); @@ -137,6 +138,9 @@ void PickClassDialog::setClassId(const std::string &classId) if (boost::iequals(*mClassList->getItemDataAt(i), classId)) { mClassList->setIndexSelected(i); + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); break; } } @@ -163,6 +167,10 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + const std::string *classId = mClassList->getItemDataAt(_index); if (boost::iequals(mCurrentClassId, *classId)) return; diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 9abb05390..b1d51db09 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -80,6 +80,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); + okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); updateRaces(); updateSkills(); @@ -121,6 +122,9 @@ void RaceDialog::setRaceId(const std::string &raceId) if (boost::iequals(*mRaceList->getItemDataAt(i), raceId)) { mRaceList->setIndexSelected(i); + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); break; } } @@ -202,6 +206,9 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; + MyGUI::ButtonPtr okButton; + getWidget(okButton, "OKButton"); + okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); const std::string *raceId = mRaceList->getItemDataAt(_index); if (boost::iequals(mCurrentRaceId, *raceId)) return; From c8cc6b6e65f04fff1b18d504c6f601dd8e66bb6e Mon Sep 17 00:00:00 2001 From: emoose Date: Sat, 3 Nov 2012 16:39:32 +0000 Subject: [PATCH 100/255] Fixed: engine: Bug #437 Stop animations when paused; tooltips: capitalize first letter (eg paper -> Paper) --- apps/openmw/engine.cpp | 3 ++- apps/openmw/mwgui/tooltips.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 617689bc6..5f1d0dd5f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -101,7 +101,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); // update world - MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame); + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame); // update GUI Ogre::RenderWindow* window = mOgre->getWindow(); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 35224613c..02a4f0c39 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -364,6 +364,9 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) if (text.size() > 0 && text[0] == '\n') text.erase(0, 1); + if(caption.size() > 0 && isalnum(caption[0])) + caption[0] = toupper(caption[0]); + const ESM::Enchantment* enchant = 0; const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (info.enchant != "") From cadc753216fda012917005c1d14c3d5b85b68698 Mon Sep 17 00:00:00 2001 From: emoose Date: Sat, 3 Nov 2012 19:29:55 +0000 Subject: [PATCH 101/255] Fixed: engine: Bug #437 Stop animations when paused better fix; scene: Bug #430 Teleporting and using loading doors linking within the same cell reloads the cell Bug #437 fix only pauses the RenderingManager, and still updates the mOcclusionQuery Bug #430 fix is only tested in interiors (ToddTest) --- apps/openmw/engine.cpp | 3 +- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 8 ++- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwworld/scene.cpp | 81 +++++++++++++---------- apps/openmw/mwworld/scene.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 4 +- apps/openmw/mwworld/worldimp.hpp | 2 +- 8 files changed, 60 insertions(+), 44 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 5f1d0dd5f..a75a60223 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -101,8 +101,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); // update world - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame); + MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame, MWBase::Environment::get().getWindowManager()->isGuiMode()); // update GUI Ogre::RenderWindow* window = mOgre->getWindow(); diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index d29e23c18..6710fc68b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -265,7 +265,7 @@ namespace MWBase ///< Skip the animation for the given MW-reference for one frame. Calls to this function for /// references that are currently not in the rendered scene should be ignored. - virtual void update (float duration) = 0; + virtual void update (float duration, bool paused) = 0; virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0; ///< place an object into the gameworld at the specified cursor position diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5b5fdce68..3bf6573bd 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -313,7 +313,7 @@ RenderingManager::moveObjectToCell( child->setPosition(pos); } -void RenderingManager::update (float duration) +void RenderingManager::update (float duration, bool paused) { Ogre::Vector3 orig, dest; mPlayer->setCameraDistance(); @@ -328,12 +328,16 @@ void RenderingManager::update (float duration) mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); } } + mOcclusionQuery->update(duration); + + if(paused) + return; + mPlayer->update(duration); mActors.update (duration); mObjects.update (duration); - mOcclusionQuery->update(duration); mSkyManager->update(duration); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 359809b71..86346d1d6 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -125,7 +125,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList /// \param store Cell the object was in previously (\a ptr has already been updated to the new cell). void moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::CellStore *store); - void update (float duration); + void update (float duration, bool paused); void setAmbientColour(const Ogre::ColourValue& colour); void setSunColour(const Ogre::ColourValue& colour); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 517025fb2..3982b9b12 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -62,8 +62,8 @@ namespace namespace MWWorld { - void Scene::update (float duration){ - mRendering.update (duration); + void Scene::update (float duration, bool paused){ + mRendering.update (duration, paused); } void Scene::unloadCell (CellStoreCollection::iterator iter) @@ -306,45 +306,58 @@ namespace MWWorld { std::cout << "Changing to interior\n"; - CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); - // remove active - CellStoreCollection::iterator active = mActiveCells.begin(); - - // count number of cells to unload - int numUnload = 0; - while (active!=mActiveCells.end()) + bool loadcell = (mCurrentCell == NULL); + if(!loadcell) { - ++active; - ++numUnload; + std::string nam = std::string(cellName); + std::string curnam = std::string(mCurrentCell->cell->mName); + std::transform(nam.begin(), nam.end(), nam.begin(), ::tolower); + std::transform(curnam.begin(), curnam.end(), curnam.begin(), ::tolower); + loadcell = nam != curnam; } - - // unload - int current = 0; - active = mActiveCells.begin(); - while (active!=mActiveCells.end()) + if(loadcell) { - MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); + CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); - unloadCell (active++); - ++current; + // remove active + CellStoreCollection::iterator active = mActiveCells.begin(); + + // count number of cells to unload + int numUnload = 0; + while (active!=mActiveCells.end()) + { + ++active; + ++numUnload; + } + + // unload + int current = 0; + active = mActiveCells.begin(); + while (active!=mActiveCells.end()) + { + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); + + unloadCell (active++); + ++current; + } + + // Load cell. + std::cout << "cellName:" << cellName << std::endl; + + + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); + loadCell (cell); + + mCurrentCell = cell; + + // adjust fog + mRendering.switchToInterior(); + mRendering.configureFog(*cell); } - - // Load cell. - std::cout << "cellName:" << cellName << std::endl; - - - MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); - loadCell (cell); - // adjust player - mCurrentCell = cell; - playerCellChange (cell, position); - - // adjust fog - mRendering.switchToInterior(); - mRendering.configureFog(*cell); - + playerCellChange (mCurrentCell, position); + // Sky system MWBase::Environment::get().getWorld()->adjustSky(); diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 59e13dafe..ad6ad1559 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -88,7 +88,7 @@ namespace MWWorld void insertCell (Ptr::CellStore &cell); - void update (float duration); + void update (float duration, bool paused); void addObjectToScene (const Ptr& ptr); ///< Add an object that already exists in the world model to the scene. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c7f0de245..7b938be5e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -858,11 +858,11 @@ namespace MWWorld mRendering->skipAnimation (ptr); } - void World::update (float duration) + void World::update (float duration, bool paused) { /// \todo split this function up into subfunctions - mWorldScene->update (duration); + mWorldScene->update (duration, paused); float pitch, yaw; Ogre::Vector3 eyepos; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 527a608a6..ad541048b 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -280,7 +280,7 @@ namespace MWWorld ///< Skip the animation for the given MW-reference for one frame. Calls to this function for /// references that are currently not in the rendered scene should be ignored. - virtual void update (float duration); + virtual void update (float duration, bool paused); virtual bool placeObject (const Ptr& object, float cursorX, float cursorY); ///< place an object into the gameworld at the specified cursor position From ba2fc2d6f8369047d21bfdae4e0dc363c334978e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 4 Nov 2012 11:37:47 +0100 Subject: [PATCH 102/255] better fix for chargen button colors --- apps/openmw/mwgui/birth.cpp | 6 +++--- apps/openmw/mwgui/class.cpp | 6 +++--- apps/openmw/mwgui/race.cpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 56e566ffb..e7862c4e7 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -48,7 +48,7 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); - okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); + okButton->setEnabled(false); updateBirths(); updateSpells(); @@ -85,7 +85,7 @@ void BirthDialog::setBirthId(const std::string &birthId) mBirthList->setIndexSelected(i); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); break; } } @@ -114,7 +114,7 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); const std::string *birthId = mBirthList->getItemDataAt(_index); if (boost::iequals(mCurrentBirthId, *birthId)) diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index a798ca232..f020010ec 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -104,7 +104,7 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); - okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); + okButton->setEnabled(false); updateClasses(); updateStats(); @@ -140,7 +140,7 @@ void PickClassDialog::setClassId(const std::string &classId) mClassList->setIndexSelected(i); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); break; } } @@ -169,7 +169,7 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); const std::string *classId = mClassList->getItemDataAt(_index); if (boost::iequals(mCurrentClassId, *classId)) diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index b1d51db09..d681bc69d 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -80,7 +80,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); - okButton->setTextColour(MyGUI::Colour(0.6f, 0.56f, 0.45f)); + okButton->setEnabled(false); updateRaces(); updateSkills(); @@ -124,7 +124,7 @@ void RaceDialog::setRaceId(const std::string &raceId) mRaceList->setIndexSelected(i); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); break; } } @@ -208,7 +208,7 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->setTextColour(MyGUI::Colour(0.75f, 0.6f, 0.35f)); + okButton->setEnabled(true); const std::string *raceId = mRaceList->getItemDataAt(_index); if (boost::iequals(mCurrentRaceId, *raceId)) return; From b7aa7e4cef5f27feeb76487b26404df42ad97989 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 4 Nov 2012 11:57:51 +0100 Subject: [PATCH 103/255] pause all animations --- apps/openmw/mwrender/renderingmanager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3bf6573bd..bcc3a311d 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -331,8 +332,13 @@ void RenderingManager::update (float duration, bool paused) mOcclusionQuery->update(duration); if(paused) + { + Ogre::ControllerManager::getSingleton().setTimeFactor(0.f); return; - + } + Ogre::ControllerManager::getSingleton().setTimeFactor( + MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); + mPlayer->update(duration); mActors.update (duration); From 38828acac97fe39b1cb2561c3dac829f5d0946eb Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 4 Nov 2012 12:13:04 +0100 Subject: [PATCH 104/255] transparent overlay --- apps/openmw/mwgui/map_window.cpp | 9 ++++++ apps/openmw/mwgui/map_window.hpp | 2 ++ apps/openmw/mwgui/windowmanagerimp.cpp | 2 ++ apps/openmw/mwrender/globalmap.cpp | 43 ++++++++++++++++++++++++++ apps/openmw/mwrender/globalmap.hpp | 9 ++++++ apps/openmw/mwrender/localmap.hpp | 1 - apps/openmw/mwrender/player.cpp | 3 +- files/mygui/openmw_map_window.layout | 1 + 8 files changed, 68 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp index 1913ed8dd..ef6703765 100644 --- a/apps/openmw/mwgui/map_window.cpp +++ b/apps/openmw/mwgui/map_window.cpp @@ -266,13 +266,17 @@ MapWindow::MapWindow(MWBase::WindowManager& parWindowManager, const std::string& mGlobalMapRender = new MWRender::GlobalMap(cacheDir); mGlobalMapRender->render(); + mGlobalMapRender->exploreCell(0,0); + getWidget(mLocalMap, "LocalMap"); getWidget(mGlobalMap, "GlobalMap"); getWidget(mGlobalMapImage, "GlobalMapImage"); + getWidget(mGlobalMapOverlay, "GlobalMapOverlay"); getWidget(mPlayerArrowLocal, "CompassLocal"); getWidget(mPlayerArrowGlobal, "CompassGlobal"); mGlobalMapImage->setImageTexture("GlobalMap.png"); + mGlobalMapOverlay->setImageTexture("GlobalMapOverlay"); mGlobalMap->setVisible (false); @@ -328,6 +332,11 @@ void MapWindow::addVisitedLocation(const std::string& name, int x, int y) markerWidget->setUserString("Caption_Text", name); } +void MapWindow::cellExplored(int x, int y) +{ + mGlobalMapRender->exploreCell(x,y); +} + void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp index 73eaad1cd..4e2dd6756 100644 --- a/apps/openmw/mwgui/map_window.hpp +++ b/apps/openmw/mwgui/map_window.hpp @@ -70,6 +70,7 @@ namespace MWGui void setCellName(const std::string& cellName); void addVisitedLocation(const std::string& name, int x, int y); // adds the marker to the global map + void cellExplored(int x, int y); virtual void open(); @@ -82,6 +83,7 @@ namespace MWGui MyGUI::ScrollView* mGlobalMap; MyGUI::ImageBox* mGlobalMapImage; + MyGUI::ImageBox* mGlobalMapOverlay; MyGUI::ImageBox* mPlayerArrowLocal; MyGUI::ImageBox* mPlayerArrowGlobal; MyGUI::Button* mButton; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 0350581e4..734b46633 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -621,6 +621,8 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) name = getGameSettingString("sDefaultCellname", "Wilderness"); } + mMap->cellExplored(cell->cell->getGridX(), cell->cell->getGridY()); + mMap->setCellName( name ); mHud->setCellName( name ); diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 7a799a2e4..889e9d189 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -47,6 +48,7 @@ namespace MWRender mWidth = cellSize*(mMaxX-mMinX+1); mHeight = cellSize*(mMaxY-mMinY+1); + mExploredBuffer.resize((mMaxX-mMinX+1) * (mMaxY-mMinY+1) * 4); //if (!boost::filesystem::exists(mCacheDir + "/GlobalMap.png")) if (1) @@ -179,5 +181,46 @@ namespace MWRender imageY = 1.f-float(y - mMinY + 1) / (mMaxY - mMinY + 1); } + void GlobalMap::exploreCell(int cellX, int cellY) + { + mExploredCells.push_back(std::make_pair(cellX, cellY)); + int width = mMaxX-mMinX+1; + int height = mMaxY-mMinY+1; + if (mOverlayTexture.isNull()) + { + mOverlayTexture = Ogre::TextureManager::getSingleton().createManual("GlobalMapOverlay", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC_WRITE_ONLY); + } + + for (int x = mMinX; x <= mMaxX; ++x) + { + for (int y = mMinY; y <= mMaxY; ++y) + { + unsigned char r,g,b,a; + r = 0; + g = 0; + b = 0; + if (std::find(mExploredCells.begin(), mExploredCells.end(), std::make_pair(x, y)) != mExploredCells.end()) + a = 0; + else + a = 128; + int texelX = (x-mMinX); + int texelY = (height-1) - (y-mMinY); + + assert( static_cast(texelY * width * 4 + texelX * 4+3) < mExploredBuffer.size()); + mExploredBuffer[texelY * width * 4 + texelX * 4] = r; + mExploredBuffer[texelY * width * 4 + texelX * 4+1] = g; + mExploredBuffer[texelY * width * 4 + texelX * 4+2] = b; + mExploredBuffer[texelY * width * 4 + texelX * 4+3] = a; + } + } + + Ogre::Image image; + image.loadDynamicImage(&mExploredBuffer[0], width, height, Ogre::PF_A8B8G8R8); + + memcpy(mOverlayTexture->getBuffer()->lock(Ogre::HardwareBuffer::HBL_DISCARD), + &mExploredBuffer[0], width*height*4); + mOverlayTexture->getBuffer()->unlock(); + } } diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp index 01f5fdb9e..c01182c5b 100644 --- a/apps/openmw/mwrender/globalmap.hpp +++ b/apps/openmw/mwrender/globalmap.hpp @@ -3,6 +3,8 @@ #include +#include + namespace MWRender { @@ -22,9 +24,16 @@ namespace MWRender void cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY); + void exploreCell (int cellX, int cellY); + private: std::string mCacheDir; + std::vector< std::pair > mExploredCells; + + Ogre::TexturePtr mOverlayTexture; + std::vector mExploredBuffer; + int mWidth; int mHeight; diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 056d2498a..ede221d94 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -58,7 +58,6 @@ namespace MWRender */ void saveFogOfWar(MWWorld::CellStore* cell); - /** * Get the interior map texture index and normalized position * on this texture, given a world position (in ogre coordinates) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index bbc75cade..d0b4641b9 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -23,7 +23,8 @@ namespace MWRender mFreeLook(true), mHeight(128.f), mCameraDistance(300.f), - mDistanceAdjusted(false) + mDistanceAdjusted(false), + mAnimation(NULL) { mVanity.enabled = false; mVanity.allowed = true; diff --git a/files/mygui/openmw_map_window.layout b/files/mygui/openmw_map_window.layout index 20cfbbd6e..b5479b676 100644 --- a/files/mygui/openmw_map_window.layout +++ b/files/mygui/openmw_map_window.layout @@ -19,6 +19,7 @@ + From aabb1b8f3fa004faf87db6d0597559cb99ae6dda Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 4 Nov 2012 13:26:04 +0100 Subject: [PATCH 105/255] Issue #219: implemented death count filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 62f7df679..52b048b4b 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -14,6 +14,7 @@ #include "../mwbase/scriptmanager.hpp" #include "../mwbase/journal.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/refdata.hpp" @@ -368,9 +369,12 @@ namespace MWDialogue return true; - - case '6'://dead - if(!selectCompare(comp,0,select.mI)) return false; + case '6': // dead +{ +std::cout<<"### "<countDeaths (toLower (name))< (comp, + MWBase::Environment::get().getMechanicsManager()->countDeaths (toLower (name)), select.mI); case '7':// not ID if(select.mType==ESM::VT_String ||select.mType==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string From 6f7a621b6f4a6913950055411e1f747c8dd042f5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 4 Nov 2012 23:15:20 +0100 Subject: [PATCH 106/255] disabled enchanting unfinished enchantment GUI for now --- apps/openmw/mwgui/dialogue.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 23d2197b7..96b85b4c4 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -192,8 +192,8 @@ void DialogueWindow::setKeywords(std::list keyWords) if (mServices & Service_CreateSpells) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellmakingMenuTitle")->getString()); - if (mServices & Service_Enchant) - mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString()); +// if (mServices & Service_Enchant) +// mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString()); if (mServices & Service_Training) mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString()); From accf8b2f71bb52d3ddfe7384dfef4148166ed57c Mon Sep 17 00:00:00 2001 From: emoose Date: Sun, 4 Nov 2012 23:22:30 +0000 Subject: [PATCH 107/255] Updated Bug #430 fix so it only moves the player now --- apps/openmw/mwworld/scene.cpp | 94 ++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 3982b9b12..37cc23f5f 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -304,60 +304,62 @@ namespace MWWorld void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) { - std::cout << "Changing to interior\n"; - - + CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); bool loadcell = (mCurrentCell == NULL); + if(!loadcell) + loadcell = *mCurrentCell != *cell; + if(!loadcell) { - std::string nam = std::string(cellName); - std::string curnam = std::string(mCurrentCell->cell->mName); - std::transform(nam.begin(), nam.end(), nam.begin(), ::tolower); - std::transform(curnam.begin(), curnam.end(), curnam.begin(), ::tolower); - loadcell = nam != curnam; + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->moveObject(world->getPlayer().getPlayer(), position.pos[0], position.pos[1], position.pos[2]); + + float x = Ogre::Radian(position.rot[0]).valueDegrees(); + float y = Ogre::Radian(position.rot[1]).valueDegrees(); + float z = Ogre::Radian(position.rot[2]).valueDegrees(); + world->rotateObject(world->getPlayer().getPlayer(), x, y, z); + return; } - if(loadcell) + + std::cout << "Changing to interior\n"; + + // remove active + CellStoreCollection::iterator active = mActiveCells.begin(); + + // count number of cells to unload + int numUnload = 0; + while (active!=mActiveCells.end()) { - CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); - - // remove active - CellStoreCollection::iterator active = mActiveCells.begin(); - - // count number of cells to unload - int numUnload = 0; - while (active!=mActiveCells.end()) - { - ++active; - ++numUnload; - } - - // unload - int current = 0; - active = mActiveCells.begin(); - while (active!=mActiveCells.end()) - { - MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); - - unloadCell (active++); - ++current; - } - - // Load cell. - std::cout << "cellName:" << cellName << std::endl; - - - MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); - loadCell (cell); - - mCurrentCell = cell; - - // adjust fog - mRendering.switchToInterior(); - mRendering.configureFog(*cell); + ++active; + ++numUnload; } + + // unload + int current = 0; + active = mActiveCells.begin(); + while (active!=mActiveCells.end()) + { + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); + + unloadCell (active++); + ++current; + } + + // Load cell. + std::cout << "cellName: " << cell->cell->mName << std::endl; + + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); + loadCell (cell); + + mCurrentCell = cell; + + // adjust fog + mRendering.switchToInterior(); + mRendering.configureFog(*mCurrentCell); + // adjust player playerCellChange (mCurrentCell, position); - + // Sky system MWBase::Environment::get().getWorld()->adjustSky(); From f72f898bd9ea8c49c143ae650bcc94b0e45c5ef4 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 5 Nov 2012 11:07:43 +0100 Subject: [PATCH 108/255] 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 3c2ce25f5f3e889a54654cca360f10c5cfed8337 Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 5 Nov 2012 16:07:59 +0400 Subject: [PATCH 109/255] m prefix for mwworld/cellstore.hpp --- apps/openmw/mwclass/activator.cpp | 16 +-- apps/openmw/mwclass/apparatus.cpp | 30 ++--- apps/openmw/mwclass/armor.cpp | 46 +++---- apps/openmw/mwclass/book.cpp | 32 ++--- apps/openmw/mwclass/clothing.cpp | 42 +++--- apps/openmw/mwclass/container.cpp | 26 ++-- apps/openmw/mwclass/creature.cpp | 54 ++++---- apps/openmw/mwclass/door.cpp | 42 +++--- apps/openmw/mwclass/ingredient.cpp | 38 +++--- apps/openmw/mwclass/light.cpp | 50 ++++---- apps/openmw/mwclass/lockpick.cpp | 32 ++--- apps/openmw/mwclass/misc.cpp | 42 +++--- apps/openmw/mwclass/npc.cpp | 70 +++++----- apps/openmw/mwclass/potion.cpp | 32 ++--- apps/openmw/mwclass/probe.cpp | 32 ++--- apps/openmw/mwclass/repair.cpp | 32 ++--- apps/openmw/mwclass/static.cpp | 6 +- apps/openmw/mwclass/weapon.cpp | 72 +++++------ apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 26 ++-- apps/openmw/mwgui/bookwindow.cpp | 2 +- apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwgui/scrollwindow.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 24 ++-- apps/openmw/mwgui/trainingwindow.cpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 12 +- apps/openmw/mwgui/windowmanagerimp.cpp | 22 ++-- apps/openmw/mwmechanics/alchemy.cpp | 18 +-- .../mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwrender/creatureanimation.cpp | 6 +- apps/openmw/mwrender/debugging.cpp | 16 +-- apps/openmw/mwrender/localmap.cpp | 10 +- apps/openmw/mwrender/npcanimation.cpp | 42 +++--- apps/openmw/mwrender/objects.cpp | 12 +- apps/openmw/mwrender/renderingmanager.cpp | 26 ++-- apps/openmw/mwrender/terrain.cpp | 8 +- apps/openmw/mwscript/cellextensions.cpp | 9 +- apps/openmw/mwscript/statsextensions.cpp | 2 +- apps/openmw/mwsound/soundmanagerimp.cpp | 8 +- apps/openmw/mwworld/actionread.cpp | 12 +- apps/openmw/mwworld/cells.cpp | 62 ++++----- apps/openmw/mwworld/cellstore.cpp | 61 ++++----- apps/openmw/mwworld/cellstore.hpp | 120 +++++++++--------- apps/openmw/mwworld/containerstore.cpp | 116 ++++++++--------- apps/openmw/mwworld/localscripts.cpp | 42 +++--- apps/openmw/mwworld/manualref.hpp | 4 +- apps/openmw/mwworld/player.cpp | 4 +- apps/openmw/mwworld/ptr.hpp | 2 +- apps/openmw/mwworld/scene.cpp | 116 +++++++++-------- apps/openmw/mwworld/weather.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 77 ++++++----- 50 files changed, 788 insertions(+), 775 deletions(-) diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index e815549d8..a7f73278e 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -39,9 +39,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -53,7 +53,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } std::string Activator::getScript (const MWWorld::Ptr& ptr) const @@ -61,7 +61,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } void Activator::registerSelf() @@ -76,7 +76,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -85,11 +85,11 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); std::string text; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); info.text = text; return info; @@ -101,6 +101,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.activators.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index a05c24e86..9b2d0795c 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -42,9 +42,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -56,7 +56,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Apparatus::activate (const MWWorld::Ptr& ptr, @@ -75,7 +75,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Apparatus::getValue (const MWWorld::Ptr& ptr) const @@ -83,7 +83,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Apparatus::registerSelf() @@ -108,7 +108,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const @@ -116,7 +116,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -125,17 +125,17 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -154,6 +154,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.appas.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 7254c37f8..36a1b25c4 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -45,9 +45,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -59,7 +59,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, @@ -82,7 +82,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mHealth; + return ref->mBase->mData.mHealth; } std::string Armor::getScript (const MWWorld::Ptr& ptr) const @@ -90,7 +90,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -118,7 +118,7 @@ namespace MWClass }; for (int i=0; ibase->mData.mType) + if (sMapping[i][0]==ref->mBase->mData.mType) { slots.push_back (int (sMapping[i][1])); break; @@ -134,7 +134,7 @@ namespace MWClass std::string typeGmst; - switch (ref->base->mData.mType) + switch (ref->mBase->mData.mType) { case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break; case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break; @@ -155,11 +155,11 @@ namespace MWClass float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->getInt(); if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->getFloat()>= - ref->base->mData.mWeight) + ref->mBase->mData.mWeight) return ESM::Skill::LightArmor; if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->getFloat()>= - ref->base->mData.mWeight) + ref->mBase->mData.mWeight) return ESM::Skill::MediumArmor; return ESM::Skill::HeavyArmor; @@ -170,7 +170,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Armor::registerSelf() @@ -207,7 +207,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const @@ -215,7 +215,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -224,8 +224,8 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; @@ -239,20 +239,20 @@ namespace MWClass else typeText = "#{sHeavy}"; - text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->base->mData.mArmor); + text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor); /// \todo store the current armor health somewhere - text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); + text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")"; - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")"; + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } - info.enchant = ref->base->mEnchant; + info.enchant = ref->mBase->mEnchant; info.text = text; @@ -264,7 +264,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mEnchant; + return ref->mBase->mEnchant; } boost::shared_ptr Armor::use (const MWWorld::Ptr& ptr) const @@ -282,6 +282,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.armors.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 4a2ad1dcb..150865b5d 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -41,9 +41,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -55,7 +55,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Book::activate (const MWWorld::Ptr& ptr, @@ -70,7 +70,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Book::getValue (const MWWorld::Ptr& ptr) const @@ -78,7 +78,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Book::registerSelf() @@ -103,7 +103,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Book::hasToolTip (const MWWorld::Ptr& ptr) const @@ -111,7 +111,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -120,20 +120,20 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } - info.enchant = ref->base->mEnchant; + info.enchant = ref->mBase->mEnchant; info.text = text; @@ -145,7 +145,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mEnchant; + return ref->mBase->mEnchant; } boost::shared_ptr Book::use (const MWWorld::Ptr& ptr) const @@ -159,6 +159,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.books.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index d746350df..ab0db50fa 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -43,9 +43,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -57,7 +57,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, @@ -75,7 +75,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -85,7 +85,7 @@ namespace MWClass std::vector slots; - if (ref->base->mData.mType==ESM::Clothing::Ring) + if (ref->mBase->mData.mType==ESM::Clothing::Ring) { slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing)); slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing)); @@ -108,7 +108,7 @@ namespace MWClass }; for (int i=0; ibase->mData.mType) + if (sMapping[i][0]==ref->mBase->mData.mType) { slots.push_back (int (sMapping[i][1])); break; @@ -123,7 +123,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mData.mType==ESM::Clothing::Shoes) + if (ref->mBase->mData.mType==ESM::Clothing::Shoes) return ESM::Skill::Unarmored; return -1; @@ -134,7 +134,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Clothing::registerSelf() @@ -149,7 +149,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mData.mType == 8) + if (ref->mBase->mData.mType == 8) { return std::string("Item Ring Up"); } @@ -161,7 +161,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mData.mType == 8) + if (ref->mBase->mData.mType == 8) { return std::string("Item Ring Down"); } @@ -173,7 +173,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const @@ -181,7 +181,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -190,20 +190,20 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } - info.enchant = ref->base->mEnchant; + info.enchant = ref->mBase->mEnchant; info.text = text; @@ -215,7 +215,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mEnchant; + return ref->mBase->mEnchant; } boost::shared_ptr Clothing::use (const MWWorld::Ptr& ptr) const @@ -233,6 +233,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.clothes.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 237f451f3..e4350324c 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -74,9 +74,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -149,7 +149,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) @@ -165,7 +165,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } void Container::registerSelf() @@ -180,7 +180,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -189,17 +189,17 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName; + info.caption = ref->mBase->mName; std::string text; - if (ref->ref.mLockLevel > 0) - text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel); - if (ref->ref.mTrap != "") + if (ref->mRef.mLockLevel > 0) + text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); + if (ref->mRef.mTrap != "") text += "\n#{sTrapped}"; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -212,7 +212,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mWeight; + return ref->mBase->mWeight; } float Container::getEncumbrance (const MWWorld::Ptr& ptr) const @@ -239,6 +239,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.containers.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index e4ff3c95b..361dbc308 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -48,28 +48,28 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); // creature stats - data->mCreatureStats.getAttribute(0).set (ref->base->mData.mStrength); - data->mCreatureStats.getAttribute(1).set (ref->base->mData.mIntelligence); - data->mCreatureStats.getAttribute(2).set (ref->base->mData.mWillpower); - data->mCreatureStats.getAttribute(3).set (ref->base->mData.mAgility); - data->mCreatureStats.getAttribute(4).set (ref->base->mData.mSpeed); - data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance); - data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality); - data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck); - data->mCreatureStats.setHealth (ref->base->mData.mHealth); - data->mCreatureStats.setMagicka (ref->base->mData.mMana); - data->mCreatureStats.setFatigue (ref->base->mData.mFatigue); + data->mCreatureStats.getAttribute(0).set (ref->mBase->mData.mStrength); + data->mCreatureStats.getAttribute(1).set (ref->mBase->mData.mIntelligence); + data->mCreatureStats.getAttribute(2).set (ref->mBase->mData.mWillpower); + data->mCreatureStats.getAttribute(3).set (ref->mBase->mData.mAgility); + data->mCreatureStats.getAttribute(4).set (ref->mBase->mData.mSpeed); + data->mCreatureStats.getAttribute(5).set (ref->mBase->mData.mEndurance); + data->mCreatureStats.getAttribute(6).set (ref->mBase->mData.mPersonality); + data->mCreatureStats.getAttribute(7).set (ref->mBase->mData.mLuck); + data->mCreatureStats.setHealth (ref->mBase->mData.mHealth); + data->mCreatureStats.setMagicka (ref->mBase->mData.mMana); + data->mCreatureStats.setFatigue (ref->mBase->mData.mFatigue); - data->mCreatureStats.setLevel(ref->base->mData.mLevel); + data->mCreatureStats.setLevel(ref->mBase->mData.mLevel); - data->mCreatureStats.setHello(ref->base->mAiData.mHello); - data->mCreatureStats.setFight(ref->base->mAiData.mFight); - data->mCreatureStats.setFlee(ref->base->mAiData.mFlee); - data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm); + data->mCreatureStats.setHello(ref->mBase->mAiData.mHello); + data->mCreatureStats.setFight(ref->mBase->mAiData.mFight); + data->mCreatureStats.setFlee(ref->mBase->mAiData.mFlee); + data->mCreatureStats.setAlarm(ref->mBase->mAiData.mAlarm); // spells - for (std::vector::const_iterator iter (ref->base->mSpells.mList.begin()); - iter!=ref->base->mSpells.mList.end(); ++iter) + for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); + iter!=ref->mBase->mSpells.mList.end(); ++iter) data->mCreatureStats.getSpells().add (*iter); // store @@ -82,7 +82,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mId; + return ref->mBase->mId; } void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -104,9 +104,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert (ref->base != NULL); + assert (ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -118,7 +118,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const @@ -150,7 +150,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } bool Creature::isEssential (const MWWorld::Ptr& ptr) const @@ -158,7 +158,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mFlags & ESM::Creature::Essential; + return ref->mBase->mFlags & ESM::Creature::Essential; } void Creature::registerSelf() @@ -181,11 +181,11 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName; + info.caption = ref->mBase->mName; std::string text; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); info.text = text; return info; @@ -219,6 +219,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.creatures.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index f944391e1..3c4b94cd9 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -44,9 +44,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -58,10 +58,10 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->ref.mTeleport && !ref->ref.mDestCell.empty()) // TODO doors that lead to exteriors - return ref->ref.mDestCell; + if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors + return ref->mRef.mDestCell; - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Door::activate (const MWWorld::Ptr& ptr, @@ -70,8 +70,8 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - const std::string &openSound = ref->base->mOpenSound; - //const std::string &closeSound = ref->base->closeSound; + const std::string &openSound = ref->mBase->mOpenSound; + //const std::string &closeSound = ref->mBase->closeSound; const std::string lockedSound = "LockedDoor"; const std::string trapActivationSound = "Disarm Trap Fail"; @@ -119,13 +119,13 @@ namespace MWClass return action; } - if (ref->ref.mTeleport) + if (ref->mRef.mTeleport) { // teleport door /// \todo remove this if clause once ActionTeleport can also support other actors if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor) { - boost::shared_ptr action(new MWWorld::ActionTeleport (ref->ref.mDestCell, ref->ref.mDoorDest)); + boost::shared_ptr action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); action->setSound(openSound); @@ -177,7 +177,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } void Door::registerSelf() @@ -192,7 +192,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -201,25 +201,25 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName; + info.caption = ref->mBase->mName; std::string text; const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - if (ref->ref.mTeleport) + if (ref->mRef.mTeleport) { std::string dest; - if (ref->ref.mDestCell != "") + if (ref->mRef.mDestCell != "") { // door leads to an interior, use interior name as tooltip - dest = ref->ref.mDestCell; + dest = ref->mRef.mDestCell; } else { // door leads to exterior, use cell name (if any), otherwise translated region name int x,y; - MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.mDoorDest.pos[0], ref->ref.mDoorDest.pos[1], x, y); + MWBase::Environment::get().getWorld()->positionToIndex (ref->mRef.mDoorDest.pos[0], ref->mRef.mDoorDest.pos[1], x, y); const ESM::Cell* cell = store.cells.findExt(x,y); if (cell->mName != "") dest = cell->mName; @@ -233,13 +233,13 @@ namespace MWClass text += "\n"+dest; } - if (ref->ref.mLockLevel > 0) - text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel); - if (ref->ref.mTrap != "") + if (ref->mRef.mLockLevel > 0) + text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); + if (ref->mRef.mTrap != "") text += "\n#{sTrapped}"; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); info.text = text; @@ -252,6 +252,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.doors.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 45779287f..7f87befe6 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -25,7 +25,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mId; + return ref->mBase->mId; } void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -50,9 +50,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -64,7 +64,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, @@ -82,7 +82,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Ingredient::getValue (const MWWorld::Ptr& ptr) const @@ -90,7 +90,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } @@ -125,7 +125,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const @@ -133,7 +133,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -142,28 +142,28 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } MWGui::Widgets::SpellEffectList list; for (int i=0; i<4; ++i) { - if (ref->base->mData.mEffectID[i] < 0) + if (ref->mBase->mData.mEffectID[i] < 0) continue; MWGui::Widgets::SpellEffectParams params; - params.mEffectID = ref->base->mData.mEffectID[i]; - params.mAttribute = ref->base->mData.mAttributes[i]; - params.mSkill = ref->base->mData.mSkills[i]; + params.mEffectID = ref->mBase->mData.mEffectID[i]; + params.mAttribute = ref->mBase->mData.mAttributes[i]; + params.mSkill = ref->mBase->mData.mSkills[i]; list.push_back(params); } info.effects = list; @@ -179,6 +179,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.ingreds.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 6ae9ed661..c2ac7c342 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -27,9 +27,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert (ref->base != NULL); + assert (ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; MWRender::Objects& objects = renderingInterface.getObjects(); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); @@ -37,11 +37,11 @@ namespace MWClass if (!model.empty()) objects.insertMesh(ptr, "meshes\\" + model); - const int color = ref->base->mData.mColor; + const int color = ref->mBase->mData.mColor; const float r = ((color >> 0) & 0xFF) / 255.0f; const float g = ((color >> 8) & 0xFF) / 255.0f; const float b = ((color >> 16) & 0xFF) / 255.0f; - const float radius = float (ref->base->mData.mRadius); + const float radius = float (ref->mBase->mData.mRadius); objects.insertLight (ptr, r, g, b, radius); } @@ -49,15 +49,15 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert (ref->base != NULL); + assert (ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if(!model.empty()) { physics.insertObjectPhysics(ptr, "meshes\\" + model); } - if (!ref->base->mSound.empty()) { - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop); + if (!ref->mBase->mSound.empty()) { + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop); } } @@ -65,9 +65,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert (ref->base != NULL); + assert (ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -79,10 +79,10 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mModel.empty()) + if (ref->mBase->mModel.empty()) return ""; - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Light::activate (const MWWorld::Ptr& ptr, @@ -91,7 +91,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (!(ref->base->mData.mFlags & ESM::Light::Carry)) + if (!(ref->mBase->mData.mFlags & ESM::Light::Carry)) return boost::shared_ptr (new MWWorld::NullAction); boost::shared_ptr action(new MWWorld::ActionTake (ptr)); @@ -106,7 +106,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -116,7 +116,7 @@ namespace MWClass std::vector slots; - if (ref->base->mData.mFlags & ESM::Light::Carry) + if (ref->mBase->mData.mFlags & ESM::Light::Carry) slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft)); return std::make_pair (slots, false); @@ -127,7 +127,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Light::registerSelf() @@ -153,7 +153,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Light::hasToolTip (const MWWorld::Ptr& ptr) const @@ -161,7 +161,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -170,17 +170,17 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -203,6 +203,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.lights.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index a0ec65c98..62cf0e872 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -43,9 +43,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -57,7 +57,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, @@ -75,7 +75,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -92,7 +92,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Lockpick::registerSelf() @@ -117,7 +117,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const @@ -125,7 +125,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -134,21 +134,21 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; /// \todo store remaining uses somewhere - text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -171,6 +171,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.lockpicks.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index edcfc7daa..133ba1adc 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -46,9 +46,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -60,7 +60,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, @@ -78,7 +78,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const @@ -86,7 +86,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Miscellaneous::registerSelf() @@ -101,7 +101,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) + if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { return std::string("Item Gold Up"); } @@ -113,7 +113,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) + if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { return std::string("Item Gold Down"); } @@ -125,7 +125,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const @@ -133,7 +133,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -147,9 +147,9 @@ namespace MWClass int count = ptr.getRefData().getCount(); - bool isGold = (ref->base->mName == store.gameSettings.find("sGold")->getString()); + bool isGold = (ref->mBase->mName == store.gameSettings.find("sGold")->getString()); if (isGold && count == 1) - count = ref->base->mData.mValue; + count = ref->mBase->mData.mValue; std::string countString; if (!isGold) @@ -157,12 +157,12 @@ namespace MWClass else // gold displays its count also if it's 1. countString = " (" + boost::lexical_cast(count) + ")"; - info.caption = ref->base->mName + countString; - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + countString; + info.icon = ref->mBase->mIcon; - if (ref->ref.mSoul != "") + if (ref->mRef.mSoul != "") { - const ESM::Creature *creature = store.creatures.search(ref->ref.mSoul); + const ESM::Creature *creature = store.creatures.search(ref->mRef.mSoul); info.caption += " (" + creature->mName + ")"; } @@ -170,13 +170,13 @@ namespace MWClass if (!isGold) { - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); } if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -210,11 +210,11 @@ namespace MWClass MWWorld::ManualRef newRef(store, base); MWWorld::LiveCellRef *ref = newRef.getPtr().get(); - newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell); + newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell); } else { MWWorld::LiveCellRef *ref = ptr.get(); - newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell); + newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell); } return newPtr; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 2e21f8f63..9da02895b 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -62,39 +62,39 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); // NPC stats - if (!ref->base->mFaction.empty()) + if (!ref->mBase->mFaction.empty()) { - std::string faction = ref->base->mFaction; + std::string faction = ref->mBase->mFaction; boost::algorithm::to_lower(faction); - if(ref->base->mNpdt52.mGold != -10) + if(ref->mBase->mNpdt52.mGold != -10) { - data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt52.mRank; + data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank; } else { - data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt12.mRank; + data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt12.mRank; } } // creature stats - if(ref->base->mNpdt52.mGold != -10) + if(ref->mBase->mNpdt52.mGold != -10) { for (int i=0; i<27; ++i) - data->mNpcStats.getSkill (i).setBase (ref->base->mNpdt52.mSkills[i]); + data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]); - data->mCreatureStats.getAttribute(0).set (ref->base->mNpdt52.mStrength); - data->mCreatureStats.getAttribute(1).set (ref->base->mNpdt52.mIntelligence); - data->mCreatureStats.getAttribute(2).set (ref->base->mNpdt52.mWillpower); - data->mCreatureStats.getAttribute(3).set (ref->base->mNpdt52.mAgility); - data->mCreatureStats.getAttribute(4).set (ref->base->mNpdt52.mSpeed); - data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance); - data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality); - data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck); - data->mCreatureStats.setHealth (ref->base->mNpdt52.mHealth); - data->mCreatureStats.setMagicka (ref->base->mNpdt52.mMana); - data->mCreatureStats.setFatigue (ref->base->mNpdt52.mFatigue); + data->mCreatureStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength); + data->mCreatureStats.getAttribute(1).set (ref->mBase->mNpdt52.mIntelligence); + data->mCreatureStats.getAttribute(2).set (ref->mBase->mNpdt52.mWillpower); + data->mCreatureStats.getAttribute(3).set (ref->mBase->mNpdt52.mAgility); + data->mCreatureStats.getAttribute(4).set (ref->mBase->mNpdt52.mSpeed); + data->mCreatureStats.getAttribute(5).set (ref->mBase->mNpdt52.mEndurance); + data->mCreatureStats.getAttribute(6).set (ref->mBase->mNpdt52.mPersonality); + data->mCreatureStats.getAttribute(7).set (ref->mBase->mNpdt52.mLuck); + data->mCreatureStats.setHealth (ref->mBase->mNpdt52.mHealth); + data->mCreatureStats.setMagicka (ref->mBase->mNpdt52.mMana); + data->mCreatureStats.setFatigue (ref->mBase->mNpdt52.mFatigue); - data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel); + data->mCreatureStats.setLevel(ref->mBase->mNpdt52.mLevel); } else { @@ -108,14 +108,14 @@ namespace MWClass data->mCreatureStats.setLevel (1); } - data->mCreatureStats.setHello(ref->base->mAiData.mHello); - data->mCreatureStats.setFight(ref->base->mAiData.mFight); - data->mCreatureStats.setFlee(ref->base->mAiData.mFlee); - data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm); + data->mCreatureStats.setHello(ref->mBase->mAiData.mHello); + data->mCreatureStats.setFight(ref->mBase->mAiData.mFight); + data->mCreatureStats.setFlee(ref->mBase->mAiData.mFlee); + data->mCreatureStats.setAlarm(ref->mBase->mAiData.mAlarm); // spells - for (std::vector::const_iterator iter (ref->base->mSpells.mList.begin()); - iter!=ref->base->mSpells.mList.end(); ++iter) + for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); + iter!=ref->mBase->mSpells.mList.end(); ++iter) data->mCreatureStats.getSpells().add (*iter); // store @@ -128,7 +128,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mId; + return ref->mBase->mId; } void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -146,9 +146,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - std::string headID = ref->base->mHead; + std::string headID = ref->mBase->mHead; int end = headID.find_last_of("head_") - 4; std::string bodyRaceID = headID.substr(0, end); @@ -170,7 +170,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const @@ -217,7 +217,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const @@ -325,7 +325,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mFlags & ESM::NPC::Essential; + return ref->mBase->mFlags & ESM::NPC::Essential; } void Npc::registerSelf() @@ -347,11 +347,11 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName; + info.caption = ref->mBase->mName; std::string text; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); info.text = text; return info; @@ -396,7 +396,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( - ref->base->mClass); + ref->mBase->mClass); stats.useSkill (skill, *class_, usageType); } @@ -413,6 +413,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.npcs.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index f641cc719..883ba3c6a 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -43,9 +43,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -57,7 +57,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, @@ -76,7 +76,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Potion::getValue (const MWWorld::Ptr& ptr) const @@ -84,7 +84,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Potion::registerSelf() @@ -109,7 +109,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const @@ -117,7 +117,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -126,20 +126,20 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->mEffects); + info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); info.isPotion = true; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -157,7 +157,7 @@ namespace MWClass MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); boost::shared_ptr action ( - new MWWorld::ActionApply (actor, ref->base->mId)); + new MWWorld::ActionApply (actor, ref->mBase->mId)); action->setSound ("Drink"); @@ -170,6 +170,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.potions.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 39472f2ec..5a6e37385 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -43,9 +43,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -57,7 +57,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const @@ -74,7 +74,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -91,7 +91,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Probe::registerSelf() @@ -116,7 +116,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const @@ -124,7 +124,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -133,21 +133,21 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; /// \todo store remaining uses somewhere - text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -170,6 +170,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.probes.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 7ccb34913..25ec7c7ba 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -41,9 +41,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -55,7 +55,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, @@ -73,7 +73,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } int Repair::getValue (const MWWorld::Ptr& ptr) const @@ -81,7 +81,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Repair::registerSelf() @@ -106,7 +106,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const @@ -114,7 +114,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -123,21 +123,21 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; std::string text; /// \todo store remaining uses somewhere - text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -151,6 +151,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.repairs.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 07ab54256..1ef215bee 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -33,9 +33,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -60,6 +60,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.statics.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mStatics.insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index fee0dfdf1..c59fb0ac6 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -43,9 +43,9 @@ namespace MWClass { MWWorld::LiveCellRef *ref = ptr.get(); - assert(ref->base != NULL); + assert(ref->mBase != NULL); - const std::string &model = ref->base->mModel; + const std::string &model = ref->mBase->mModel; if (!model.empty()) { return "meshes\\" + model; } @@ -57,7 +57,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mName; + return ref->mBase->mName; } boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, @@ -80,7 +80,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mHealth; + return ref->mBase->mData.mHealth; } std::string Weapon::getScript (const MWWorld::Ptr& ptr) const @@ -88,7 +88,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mScript; + return ref->mBase->mScript; } std::pair, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const @@ -99,12 +99,12 @@ namespace MWClass std::vector slots; bool stack = false; - if (ref->base->mData.mType==ESM::Weapon::Arrow || ref->base->mData.mType==ESM::Weapon::Bolt) + if (ref->mBase->mData.mType==ESM::Weapon::Arrow || ref->mBase->mData.mType==ESM::Weapon::Bolt) { slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition)); stack = true; } - else if (ref->base->mData.mType==ESM::Weapon::MarksmanThrown) + else if (ref->mBase->mData.mType==ESM::Weapon::MarksmanThrown) { slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); stack = true; @@ -139,7 +139,7 @@ namespace MWClass }; for (int i=0; ibase->mData.mType) + if (sMapping[i][0]==ref->mBase->mData.mType) return sMapping[i][1]; return -1; @@ -150,7 +150,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mData.mValue; + return ref->mBase->mData.mValue; } void Weapon::registerSelf() @@ -165,7 +165,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - int type = ref->base->mData.mType; + int type = ref->mBase->mData.mType; // Ammo if (type == 12 || type == 13) { @@ -211,7 +211,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - int type = ref->base->mData.mType; + int type = ref->mBase->mData.mType; // Ammo if (type == 12 || type == 13) { @@ -257,7 +257,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mIcon; + return ref->mBase->mIcon; } bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const @@ -265,7 +265,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return (ref->base->mName != ""); + return (ref->mBase->mName != ""); } MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const @@ -274,15 +274,15 @@ namespace MWClass ptr.get(); MWGui::ToolTipInfo info; - info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); - info.icon = ref->base->mIcon; + info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); + info.icon = ref->mBase->mIcon; const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); std::string text; // weapon type & damage. arrows / bolts don't have his info. - if (ref->base->mData.mType < 12) + if (ref->mBase->mData.mType < 12) { text += "\n#{sType} "; @@ -300,49 +300,49 @@ namespace MWClass mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", ""); mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", ""); - std::string type = mapping[ref->base->mData.mType].first; - std::string oneOrTwoHanded = mapping[ref->base->mData.mType].second; + std::string type = mapping[ref->mBase->mData.mType].first; + std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second; text += store.gameSettings.find(type)->getString() + ((oneOrTwoHanded != "") ? ", " + store.gameSettings.find(oneOrTwoHanded)->getString() : ""); // weapon damage - if (ref->base->mData.mType >= 9) + if (ref->mBase->mData.mType >= 9) { // marksman text += "\n#{sAttack}: " - + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[0])) - + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[1])); + + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1])); } else { // Chop text += "\n#{sChop}: " - + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[0])) - + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[1])); + + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1])); // Slash text += "\n#{sSlash}: " - + MWGui::ToolTips::toString(static_cast(ref->base->mData.mSlash[0])) - + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mSlash[1])); + + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mSlash[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mSlash[1])); // Thrust text += "\n#{sThrust}: " - + MWGui::ToolTips::toString(static_cast(ref->base->mData.mThrust[0])) - + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mThrust[1])); + + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mThrust[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mThrust[1])); } } /// \todo store the current weapon health somewhere - if (ref->base->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity - text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); + if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity + text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - info.enchant = ref->base->mEnchant; + info.enchant = ref->mBase->mEnchant; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { - text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); - text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); + text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } info.text = text; @@ -355,7 +355,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return ref->base->mEnchant; + return ref->mBase->mEnchant; } boost::shared_ptr Weapon::use (const MWWorld::Ptr& ptr) const @@ -373,6 +373,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.weapons.insert(*ref), &cell); + return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell); } } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 62f7df679..899257239 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -391,7 +391,7 @@ namespace MWDialogue if(select.mType==ESM::VT_Int) { MWWorld::LiveCellRef* npc = actor.get(); - int isFaction = int(toLower(npc->base->mFaction) == toLower(name)); + int isFaction = int(toLower(npc->mBase->mFaction) == toLower(name)); if(selectCompare(comp,!isFaction,select.mI)) return false; } @@ -408,7 +408,7 @@ namespace MWDialogue if(select.mType==ESM::VT_Int) { MWWorld::LiveCellRef* npc = actor.get(); - int isClass = int(toLower(npc->base->mClass) == toLower(name)); + int isClass = int(toLower(npc->mBase->mClass) == toLower(name)); if(selectCompare(comp,!isClass,select.mI)) return false; } @@ -425,7 +425,7 @@ namespace MWDialogue if(select.mType==ESM::VT_Int) { MWWorld::LiveCellRef* npc = actor.get(); - int isRace = int(toLower(npc->base->mRace) == toLower(name)); + int isRace = int(toLower(npc->mBase->mRace) == toLower(name)); if(selectCompare(comp,!isRace,select.mI)) return false; } @@ -438,7 +438,7 @@ namespace MWDialogue case 'B'://not Cell if(select.mType==ESM::VT_Int) { - int isCell = int(toLower(actor.getCell()->cell->mName) == toLower(name)); + int isCell = int(toLower(actor.getCell()->mCell->mName) == toLower(name)); if(selectCompare(comp,!isCell,select.mI)) return false; } @@ -496,7 +496,7 @@ namespace MWDialogue if (!cellRef) return false; - if (toLower (info.mRace)!=toLower (cellRef->base->mRace)) + if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace)) return false; } @@ -511,7 +511,7 @@ namespace MWDialogue if (!cellRef) return false; - if (toLower (info.mClass)!=toLower (cellRef->base->mClass)) + if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass)) return false; } @@ -557,7 +557,7 @@ namespace MWDialogue if (!isCreature) { MWWorld::LiveCellRef* npc = actor.get(); - if(npc->base->mFlags & npc->base->Female) + if(npc->mBase->mFlags & npc->mBase->Female) { if(static_cast (info.mData.mGender)==0) return false; } @@ -569,7 +569,7 @@ namespace MWDialogue // check cell if (!info.mCell.empty()) - if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->mName != info.mCell) + if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mName != info.mCell) return false; // TODO check DATAstruct @@ -770,14 +770,14 @@ namespace MWDialogue if (mActor.getTypeName() == typeid(ESM::NPC).name()) { MWWorld::LiveCellRef* ref = mActor.get(); - if (ref->base->mHasAI) - services = ref->base->mAiData.mServices; + if (ref->mBase->mHasAI) + services = ref->mBase->mAiData.mServices; } else if (mActor.getTypeName() == typeid(ESM::Creature).name()) { MWWorld::LiveCellRef* ref = mActor.get(); - if (ref->base->mHasAI) - services = ref->base->mAiData.mServices; + if (ref->mBase->mHasAI) + services = ref->mBase->mAiData.mServices; } int windowServices = 0; @@ -795,7 +795,7 @@ namespace MWDialogue || services & ESM::NPC::Misc) windowServices |= MWGui::DialogueWindow::Service_Trade; - if( !mActor.get()->base->mTransport.empty()) + if( !mActor.get()->mBase->mTransport.empty()) windowServices |= MWGui::DialogueWindow::Service_Travel; if (services & ESM::NPC::Spells) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index cb142db60..bc3cd7b40 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -60,7 +60,7 @@ void BookWindow::open (MWWorld::Ptr book) MWWorld::LiveCellRef *ref = mBook.get(); BookTextParser parser; - std::vector results = parser.split(ref->base->mText, mLeftPage->getSize().width, mLeftPage->getSize().height); + std::vector results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height); int i=0; for (std::vector::iterator it=results.begin(); diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 5c202941f..ff94e5151 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -274,7 +274,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) if (mPtr.getTypeName() == typeid(ESM::Container).name()) { MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->base->mFlags & ESM::Container::Organic) + if (ref->mBase->mFlags & ESM::Container::Organic) { // user notification MWBase::Environment::get().getWindowManager()-> diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index c839e9b73..8317025e0 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -36,7 +36,7 @@ void ScrollWindow::open (MWWorld::Ptr scroll) MWWorld::LiveCellRef *ref = mScroll.get(); BookTextParser parser; - MyGUI::IntSize size = parser.parse(ref->base->mText, mTextView, 390); + MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390); if (size.height > mTextView->getSize().height) mTextView->setCanvasSize(MyGUI::IntSize(410, size.height)); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 64710c279..0e755f49d 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -156,15 +156,15 @@ namespace MWGui if (mPtr.getTypeName() == typeid(ESM::NPC).name()) { MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->base->mNpdt52.mGold == -10) - merchantgold = ref->base->mNpdt12.mGold; + if (ref->mBase->mNpdt52.mGold == -10) + merchantgold = ref->mBase->mNpdt12.mGold; else - merchantgold = ref->base->mNpdt52.mGold; + merchantgold = ref->mBase->mNpdt52.mGold; } else // ESM::Creature { MWWorld::LiveCellRef* ref = mPtr.get(); - merchantgold = ref->base->mData.mGold; + merchantgold = ref->mBase->mData.mGold; } if (mCurrentBalance > 0 && merchantgold < mCurrentBalance) { @@ -217,15 +217,15 @@ namespace MWGui if (mPtr.getTypeName() == typeid(ESM::NPC).name()) { MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->base->mNpdt52.mGold == -10) - merchantgold = ref->base->mNpdt12.mGold; + if (ref->mBase->mNpdt52.mGold == -10) + merchantgold = ref->mBase->mNpdt12.mGold; else - merchantgold = ref->base->mNpdt52.mGold; + merchantgold = ref->mBase->mNpdt52.mGold; } else // ESM::Creature { MWWorld::LiveCellRef* ref = mPtr.get(); - merchantgold = ref->base->mData.mGold; + merchantgold = ref->mBase->mData.mGold; } mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast(merchantgold)); @@ -261,14 +261,14 @@ namespace MWGui if (mPtr.getTypeName() == typeid(ESM::NPC).name()) { MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->base->mHasAI) - services = ref->base->mAiData.mServices; + if (ref->mBase->mHasAI) + services = ref->mBase->mAiData.mServices; } else if (mPtr.getTypeName() == typeid(ESM::Creature).name()) { MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->base->mHasAI) - services = ref->base->mAiData.mServices; + if (ref->mBase->mHasAI) + services = ref->mBase->mAiData.mServices; } /// \todo what about potions, there doesn't seem to be a flag for them?? diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index af61b3487..226167ba3 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -129,7 +129,7 @@ namespace MWGui // increase skill MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( - playerRef->base->mClass); + playerRef->mBase->mClass); pcStats.increaseSkill (skillId, *class_, true); // remove gold diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index c19639aa6..6431aa76e 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -104,15 +104,15 @@ namespace MWGui MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - for(unsigned int i = 0;i()->base->mTransport.size();i++) + for(unsigned int i = 0;i()->mBase->mTransport.size();i++) { - std::string cellname = mPtr.get()->base->mTransport[i].mCellName; + std::string cellname = mPtr.get()->mBase->mTransport[i].mCellName; bool interior = true; int x,y; - MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->base->mTransport[i].mPos.pos[0], - mPtr.get()->base->mTransport[i].mPos.pos[1],x,y); - if(cellname == "") {cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->mName; interior= false;} - addDestination(cellname,mPtr.get()->base->mTransport[i].mPos,interior); + MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->mBase->mTransport[i].mPos.pos[0], + mPtr.get()->mBase->mTransport[i].mPos.pos[1],x,y); + if(cellname == "") {cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->mCell->mName; interior= false;} + addDestination(cellname,mPtr.get()->mBase->mTransport[i].mPos,interior); } updateLabels(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 0350581e4..d5d88960a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -604,17 +604,17 @@ void WindowManager::onFrame (float frameDuration) void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) { - if (!(cell->cell->mData.mFlags & ESM::Cell::Interior)) + if (cell->mCell->isExterior()) { std::string name; - if (cell->cell->mName != "") + if (cell->mCell->mName != "") { - name = cell->cell->mName; - mMap->addVisitedLocation (name, cell->cell->getGridX (), cell->cell->getGridY ()); + name = cell->mCell->mName; + mMap->addVisitedLocation (name, cell->mCell->getGridX (), cell->mCell->getGridY ()); } else { - const ESM::Region* region = MWBase::Environment::get().getWorld()->getStore().regions.search(cell->cell->mRegion); + const ESM::Region* region = MWBase::Environment::get().getWorld()->getStore().regions.search(cell->mCell->mRegion); if (region) name = region->mName; else @@ -626,15 +626,15 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) mMap->setCellPrefix("Cell"); mHud->setCellPrefix("Cell"); - mMap->setActiveCell( cell->cell->mData.mX, cell->cell->mData.mY ); - mHud->setActiveCell( cell->cell->mData.mX, cell->cell->mData.mY ); + mMap->setActiveCell( cell->mCell->getGridX(), cell->mCell->getGridY() ); + mHud->setActiveCell( cell->mCell->getGridX(), cell->mCell->getGridY() ); } else { - mMap->setCellName( cell->cell->mName ); - mHud->setCellName( cell->cell->mName ); - mMap->setCellPrefix( cell->cell->mName ); - mHud->setCellPrefix( cell->cell->mName ); + mMap->setCellName( cell->mCell->mName ); + mHud->setCellName( cell->mCell->mName ); + mMap->setCellPrefix( cell->mCell->mName ); + mHud->setCellPrefix( cell->mCell->mName ); } } diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 962350472..d3564382f 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -38,11 +38,11 @@ std::set MWMechanics::Alchemy::listEffects() const const MWWorld::LiveCellRef *ingredient = iter->get(); for (int i=0; i<4; ++i) - if (ingredient->base->mData.mEffectID[i]!=-1) + if (ingredient->mBase->mData.mEffectID[i]!=-1) { EffectKey key ( - ingredient->base->mData.mEffectID[i], ingredient->base->mData.mSkills[i]!=-1 ? - ingredient->base->mData.mSkills[i] : ingredient->base->mData.mAttributes[i]); + ingredient->mBase->mData.mEffectID[i], ingredient->mBase->mData.mSkills[i]!=-1 ? + ingredient->mBase->mData.mSkills[i] : ingredient->mBase->mData.mAttributes[i]); ++effects[key]; } @@ -77,9 +77,9 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const else return; - float toolQuality = setup==1 || setup==2 ? mTools[tool].get()->base->mData.mQuality : 0; + float toolQuality = setup==1 || setup==2 ? mTools[tool].get()->mBase->mData.mQuality : 0; float calcinatorQuality = setup==1 || setup==3 ? - mTools[ESM::Apparatus::Calcinator].get()->base->mData.mQuality : 0; + mTools[ESM::Apparatus::Calcinator].get()->mBase->mData.mQuality : 0; float quality = 1; @@ -130,7 +130,7 @@ void MWMechanics::Alchemy::updateEffects() // general alchemy factor float x = getChance(); - x *= mTools[ESM::Apparatus::MortarPestle].get()->base->mData.mQuality; + x *= mTools[ESM::Apparatus::MortarPestle].get()->mBase->mData.mQuality; x *= MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fPotionStrengthMult")->getFloat(); // value @@ -258,7 +258,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) if (!iter->isEmpty()) - newRecord.mData.mWeight += iter->get()->base->mData.mWeight; + newRecord.mData.mWeight += iter->get()->mBase->mData.mWeight; newRecord.mData.mWeight /= countIngredients(); @@ -332,13 +332,13 @@ void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) { MWWorld::LiveCellRef* ref = iter->get(); - int type = ref->base->mData.mType; + int type = ref->mBase->mData.mType; if (type<0 || type>=static_cast (mTools.size())) throw std::runtime_error ("invalid apparatus type"); if (!mTools[type].isEmpty()) - if (ref->base->mData.mQuality<=mTools[type].get()->base->mData.mQuality) + if (ref->mBase->mData.mQuality<=mTools[type].get()->mBase->mData.mQuality) continue; mTools[type] = *iter; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 873dd9498..293b7cab1 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -19,7 +19,7 @@ namespace MWMechanics MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr); - const ESM::NPC *player = ptr.get()->base; + const ESM::NPC *player = ptr.get()->mBase; // reset creatureStats.setLevel(player->mNpdt52.mLevel); diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index afd114972..7ee361a6f 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -21,10 +21,10 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr): Animation() mInsert = ptr.getRefData().getBaseNode(); MWWorld::LiveCellRef *ref = ptr.get(); - assert (ref->base != NULL); - if(!ref->base->mModel.empty()) + assert (ref->mBase != NULL); + if(!ref->mBase->mModel.empty()) { - std::string mesh = "meshes\\" + ref->base->mModel; + std::string mesh = "meshes\\" + ref->mBase->mModel; mEntityList = NifOgre::NIFLoader::createEntities(mInsert, &mTextKeys, mesh); for(size_t i = 0;i < mEntityList.mEntities.size();i++) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 4f7150754..8f16d5f78 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -228,22 +228,22 @@ void Debugging::togglePathgrid() void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { - ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().pathgrids.search(*store->cell); + ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().pathgrids.search(*store->mCell); if (!pathgrid) return; Vector3 cellPathGridPos(0, 0, 0); - if (store->cell->isExterior()) + if (store->mCell->isExterior()) { - cellPathGridPos.x = store->cell->mData.mX * ESM::Land::REAL_SIZE; - cellPathGridPos.y = store->cell->mData.mY * ESM::Land::REAL_SIZE; + cellPathGridPos.x = store->mCell->mData.mX * ESM::Land::REAL_SIZE; + cellPathGridPos.y = store->mCell->mData.mY * ESM::Land::REAL_SIZE; } SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos); cellPathGrid->attachObject(createPathgridLines(pathgrid)); cellPathGrid->attachObject(createPathgridPoints(pathgrid)); - if (store->cell->isExterior()) + if (store->mCell->isExterior()) { - mExteriorPathgridNodes[std::make_pair(store->cell->mData.mX, store->cell->mData.mY)] = cellPathGrid; + mExteriorPathgridNodes[std::make_pair(store->mCell->getGridX(), store->mCell->getGridY())] = cellPathGrid; } else { @@ -254,10 +254,10 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store) { - if (store->cell->isExterior()) + if (store->mCell->isExterior()) { ExteriorPathgridNodes::iterator it = - mExteriorPathgridNodes.find(std::make_pair(store->cell->mData.mX, store->cell->mData.mY)); + mExteriorPathgridNodes.find(std::make_pair(store->mCell->getGridX(), store->mCell->getGridY())); if (it != mExteriorPathgridNodes.end()) { destroyCellPathgridNode(it->second); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 1bdbce6d9..d7614a78c 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -108,10 +108,10 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) mCameraRotNode->setOrientation(Quaternion::IDENTITY); - std::string name = "Cell_"+coordStr(cell->cell->mData.mX, cell->cell->mData.mY); + int x = cell->mCell->getGridX(); + int y = cell->mCell->getGridY(); - int x = cell->cell->mData.mX; - int y = cell->cell->mData.mY; + std::string name = "Cell_"+coordStr(x, y); mCameraPosNode->setPosition(Vector3(0,0,0)); @@ -163,7 +163,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, const int segsX = std::ceil( length.x / sSize ); const int segsY = std::ceil( length.y / sSize ); - mInteriorName = cell->cell->mName; + mInteriorName = cell->mCell->mName; for (int x=0; xcell->mName + "_" + coordStr(x,y)); + cell->mCell->mName + "_" + coordStr(x,y)); } } } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 5c2b05aca..6a25818c1 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -63,18 +63,18 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor } const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Race *race = store.races.find(ref->base->mRace); + const ESM::Race *race = store.races.find(ref->mBase->mRace); - std::string hairID = ref->base->mHair; - std::string headID = ref->base->mHead; + std::string hairID = ref->mBase->mHair; + std::string headID = ref->mBase->mHead; headModel = "meshes\\" + store.bodyParts.find(headID)->mModel; hairModel = "meshes\\" + store.bodyParts.find(hairID)->mModel; - npcName = ref->base->mName; + npcName = ref->mBase->mName; - isFemale = !!(ref->base->mFlags&ESM::NPC::Female); + isFemale = !!(ref->mBase->mFlags&ESM::NPC::Female); isBeast = !!(race->mData.mFlags&ESM::Race::Beast); - bodyRaceID = "b_n_"+ref->base->mRace; + bodyRaceID = "b_n_"+ref->mBase->mRace; std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); @@ -170,7 +170,7 @@ void NpcAnimation::updateParts() { MWWorld::Ptr ptr = *robe; - const ESM::Clothing *clothes = (ptr.get())->base; + const ESM::Clothing *clothes = (ptr.get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts); reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5); @@ -190,7 +190,7 @@ void NpcAnimation::updateParts() { MWWorld::Ptr ptr = *skirtiter; - const ESM::Clothing *clothes = (ptr.get())->base; + const ESM::Clothing *clothes = (ptr.get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Skirt, 4, parts); reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Skirt, 4); @@ -201,32 +201,32 @@ void NpcAnimation::updateParts() if(helmet != mInv.end()) { removeIndividualPart(ESM::PRT_Hair); - const ESM::Armor *armor = (helmet->get())->base; + const ESM::Armor *armor = (helmet->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts); } if(cuirass != mInv.end()) { - const ESM::Armor *armor = (cuirass->get())->base; + const ESM::Armor *armor = (cuirass->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts); } if(greaves != mInv.end()) { - const ESM::Armor *armor = (greaves->get())->base; + const ESM::Armor *armor = (greaves->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); } if(leftpauldron != mInv.end()) { - const ESM::Armor *armor = (leftpauldron->get())->base; + const ESM::Armor *armor = (leftpauldron->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts); } if(rightpauldron != mInv.end()) { - const ESM::Armor *armor = (rightpauldron->get())->base; + const ESM::Armor *armor = (rightpauldron->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); } @@ -234,13 +234,13 @@ void NpcAnimation::updateParts() { if(boots->getTypeName() == typeid(ESM::Clothing).name()) { - const ESM::Clothing *clothes = (boots->get())->base; + const ESM::Clothing *clothes = (boots->get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts); } else if(boots->getTypeName() == typeid(ESM::Armor).name()) { - const ESM::Armor *armor = (boots->get())->base; + const ESM::Armor *armor = (boots->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts); } @@ -249,13 +249,13 @@ void NpcAnimation::updateParts() { if(leftglove->getTypeName() == typeid(ESM::Clothing).name()) { - const ESM::Clothing *clothes = (leftglove->get())->base; + const ESM::Clothing *clothes = (leftglove->get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts); } else { - const ESM::Armor *armor = (leftglove->get())->base; + const ESM::Armor *armor = (leftglove->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts); } @@ -264,13 +264,13 @@ void NpcAnimation::updateParts() { if(rightglove->getTypeName() == typeid(ESM::Clothing).name()) { - const ESM::Clothing *clothes = (rightglove->get())->base; + const ESM::Clothing *clothes = (rightglove->get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts); } else { - const ESM::Armor *armor = (rightglove->get())->base; + const ESM::Armor *armor = (rightglove->get())->mBase; std::vector parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts); } @@ -279,13 +279,13 @@ void NpcAnimation::updateParts() if(shirt != mInv.end()) { - const ESM::Clothing *clothes = (shirt->get())->base; + const ESM::Clothing *clothes = (shirt->get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts); } if(pants != mInv.end()) { - const ESM::Clothing *clothes = (pants->get())->base; + const ESM::Clothing *clothes = (pants->get())->mBase; std::vector parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts); } diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 69c853d86..36f09e6d9 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -219,18 +219,18 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f info.radius = radius; info.colour = Ogre::ColourValue(r, g, b); - if (ref->base->mData.mFlags & ESM::Light::Negative) + if (ref->mBase->mData.mFlags & ESM::Light::Negative) info.colour *= -1; - info.interior = (ptr.getCell()->cell->mData.mFlags & ESM::Cell::Interior); + info.interior = !ptr.getCell()->mCell->isExterior(); - if (ref->base->mData.mFlags & ESM::Light::Flicker) + if (ref->mBase->mData.mFlags & ESM::Light::Flicker) info.type = LT_Flicker; - else if (ref->base->mData.mFlags & ESM::Light::FlickerSlow) + else if (ref->mBase->mData.mFlags & ESM::Light::FlickerSlow) info.type = LT_FlickerSlow; - else if (ref->base->mData.mFlags & ESM::Light::Pulse) + else if (ref->mBase->mData.mFlags & ESM::Light::Pulse) info.type = LT_Pulse; - else if (ref->base->mData.mFlags & ESM::Light::PulseSlow) + else if (ref->mBase->mData.mFlags & ESM::Light::PulseSlow) info.type = LT_PulseSlow; else info.type = LT_Normal; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5b5fdce68..32389c7bd 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -206,7 +206,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store) mObjects.removeCell(store); mActors.removeCell(store); mDebugging->cellRemoved(store); - if (store->cell->isExterior()) + if (store->mCell->isExterior()) mTerrainManager->cellRemoved(store); } @@ -227,7 +227,7 @@ void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) { mObjects.buildStaticGeometry (*store); mDebugging->cellAdded(store); - if (store->cell->isExterior()) + if (store->mCell->isExterior()) mTerrainManager->cellAdded(store); waterAdded(store); } @@ -366,7 +366,7 @@ void RenderingManager::update (float duration) mWater->updateUnderwater( world->isUnderwater( - *world->getPlayer().getPlayer().getCell()->cell, + *world->getPlayer().getPlayer().getCell()->mCell, Ogre::Vector3(cam.x, -cam.z, cam.y)) ); mWater->update(duration); @@ -374,14 +374,14 @@ void RenderingManager::update (float duration) } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ - if(store->cell->mData.mFlags & store->cell->HasWater - || ((!(store->cell->mData.mFlags & ESM::Cell::Interior)) - && !MWBase::Environment::get().getWorld()->getStore().lands.search(store->cell->mData.mX,store->cell->mData.mY) )) // always use water, if the cell does not have land. + if(store->mCell->mData.mFlags & store->mCell->HasWater + || ((store->mCell->isExterior()) + && !MWBase::Environment::get().getWorld()->getStore().lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. { if(mWater == 0) - mWater = new MWRender::Water(mRendering.getCamera(), this, store->cell); + mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell); else - mWater->changeCell(store->cell); + mWater->changeCell(store->mCell); mWater->setActive(true); } else @@ -467,9 +467,9 @@ bool RenderingManager::toggleRenderMode(int mode) void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell) { Ogre::ColourValue color; - color.setAsABGR (mCell.cell->mAmbi.mFog); + color.setAsABGR (mCell.mCell->mAmbi.mFog); - configureFog(mCell.cell->mAmbi.mFogDensity, color); + configureFog(mCell.mCell->mAmbi.mFogDensity, color); if (mWater) mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f)); @@ -519,7 +519,7 @@ void RenderingManager::setAmbientMode() void RenderingManager::configureAmbient(MWWorld::Ptr::CellStore &mCell) { - mAmbientColor.setAsABGR (mCell.cell->mAmbi.mAmbient); + mAmbientColor.setAsABGR (mCell.mCell->mAmbi.mAmbient); setAmbientMode(); // Create a "sun" that shines light downwards. It doesn't look @@ -529,7 +529,7 @@ void RenderingManager::configureAmbient(MWWorld::Ptr::CellStore &mCell) mSun = mRendering.getScene()->createLight(); } Ogre::ColourValue colour; - colour.setAsABGR (mCell.cell->mAmbi.mSunlight); + colour.setAsABGR (mCell.mCell->mAmbi.mSunlight); mSun->setDiffuseColour (colour); mSun->setType(Ogre::Light::LT_DIRECTIONAL); mSun->setDirection(0,-1,0); @@ -613,7 +613,7 @@ void RenderingManager::setGlare(bool glare) void RenderingManager::requestMap(MWWorld::Ptr::CellStore* cell) { - if (!(cell->cell->mData.mFlags & ESM::Cell::Interior)) + if (cell->mCell->isExterior()) mLocalMap->requestMap(cell); else mLocalMap->requestMap(cell, mObjects.getDimensions(cell)); diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 114a9bc37..eaea3d0ec 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -92,8 +92,8 @@ namespace MWRender void TerrainManager::cellAdded(MWWorld::Ptr::CellStore *store) { - const int cellX = store->cell->getGridX(); - const int cellY = store->cell->getGridY(); + const int cellX = store->mCell->getGridX(); + const int cellY = store->mCell->getGridY(); ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY); if (land == NULL) // no land data means we're not going to create any terrain. @@ -188,8 +188,8 @@ namespace MWRender { for ( int y = 0; y < 2; y++ ) { - int terrainX = store->cell->getGridX() * 2 + x; - int terrainY = store->cell->getGridY() * 2 + y; + int terrainX = store->mCell->getGridX() * 2 + x; + int terrainY = store->mCell->getGridY() * 2 + y; if (mTerrainGroup.getTerrain(terrainX, terrainY) != NULL) mTerrainGroup.unloadTerrain(terrainX, terrainY); } diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 57dd7962b..a9c31b7fe 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -87,8 +87,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { bool interior = - MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->mData.mFlags & - ESM::Cell::Interior; + !MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->isExterior(); runtime.push (interior ? 1 : 0); } @@ -103,7 +102,7 @@ namespace MWScript std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell; + const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell; std::string current = cell->mName; @@ -143,7 +142,7 @@ namespace MWScript MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); - if (!(cell->cell->mData.mFlags & ESM::Cell::Interior)) + if (cell->mCell->isExterior()) throw std::runtime_error("Can't set water level in exterior cell"); cell->mWaterLevel = level; @@ -161,7 +160,7 @@ namespace MWScript MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); - if (!(cell->cell->mData.mFlags & ESM::Cell::Interior)) + if (cell->mCell->isExterior()) throw std::runtime_error("Can't set water level in exterior cell"); cell->mWaterLevel +=level; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 0d69608e1..828d8a5e0 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -328,7 +328,7 @@ namespace MWScript assert (ref); const ESM::Class& class_ = - *MWBase::Environment::get().getWorld()->getStore().classes.find (ref->base->mClass); + *MWBase::Environment::get().getWorld()->getStore().classes.find (ref->mBase->mClass); float level = 0; float progress = std::modf (stats.getSkill (mIndex).getBase(), &level); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 5d5ef3d1d..9aabffb98 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -414,13 +414,13 @@ namespace MWSound //If the region has changed timePassed += duration; - if((current->cell->mData.mFlags & current->cell->Interior) || timePassed < 10) + if(!current->mCell->isExterior() || timePassed < 10) return; timePassed = 0; - if(regionName != current->cell->mRegion) + if(regionName != current->mCell->mRegion) { - regionName = current->cell->mRegion; + regionName = current->mCell->mRegion; total = 0; } @@ -477,7 +477,7 @@ namespace MWSound MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - const ESM::Cell *cell = player.getCell()->cell; + const ESM::Cell *cell = player.getCell()->mCell; Environment env = Env_Normal; if((cell->mData.mFlags&cell->HasWater) && mListenerPos.z < cell->mWater) diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 4ac613df7..92f232802 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -24,7 +24,7 @@ namespace MWWorld { LiveCellRef *ref = getTarget().get(); - if (ref->base->mData.mIsScroll) + if (ref->mBase->mData.mIsScroll) { MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Scroll); MWBase::Environment::get().getWindowManager()->getScrollWindow()->open(getTarget()); @@ -39,16 +39,16 @@ namespace MWWorld MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); // Skill gain from books - if (ref->base->mData.mSkillID >= 0 && ref->base->mData.mSkillID < ESM::Skill::Length - && !npcStats.hasBeenUsed (ref->base->mId)) + if (ref->mBase->mData.mSkillID >= 0 && ref->mBase->mData.mSkillID < ESM::Skill::Length + && !npcStats.hasBeenUsed (ref->mBase->mId)) { MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( - playerRef->base->mClass); + playerRef->mBase->mClass); - npcStats.increaseSkill (ref->base->mData.mSkillID, *class_, true); + npcStats.increaseSkill (ref->mBase->mData.mSkillID, *class_, true); - npcStats.flagAsUsed (ref->base->mId); + npcStats.flagAsUsed (ref->mBase->mId); } } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index e5a38d4be..0279c7480 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -24,12 +24,12 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) else { std::map, Ptr::CellStore>::iterator result = - mExteriors.find (std::make_pair (cell->mData.mX, cell->mData.mY)); + mExteriors.find (std::make_pair (cell->getGridX(), cell->getGridY())); if (result==mExteriors.end()) { result = mExteriors.insert (std::make_pair ( - std::make_pair (cell->mData.mX, cell->mData.mY), Ptr::CellStore (cell))).first; + std::make_pair (cell->getGridX(), cell->getGridY()), Ptr::CellStore (cell))).first; } @@ -40,33 +40,33 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore) { for (CellRefList::List::iterator iter ( - cellStore.containers.list.begin()); - iter!=cellStore.containers.list.end(); ++iter) + cellStore.mContainers.mList.begin()); + iter!=cellStore.mContainers.mList.end(); ++iter) { Ptr container (&*iter, &cellStore); Class::get (container).getContainerStore (container).fill ( - iter->base->mInventory, mStore); + iter->mBase->mInventory, mStore); } for (CellRefList::List::iterator iter ( - cellStore.creatures.list.begin()); - iter!=cellStore.creatures.list.end(); ++iter) + cellStore.mCreatures.mList.begin()); + iter!=cellStore.mCreatures.mList.end(); ++iter) { Ptr container (&*iter, &cellStore); Class::get (container).getContainerStore (container).fill ( - iter->base->mInventory, mStore); + iter->mBase->mInventory, mStore); } for (CellRefList::List::iterator iter ( - cellStore.npcs.list.begin()); - iter!=cellStore.npcs.list.end(); ++iter) + cellStore.mNpcs.mList.begin()); + iter!=cellStore.mNpcs.mList.end(); ++iter) { Ptr container (&*iter, &cellStore); Class::get (container).getContainerStore (container).fill ( - iter->base->mInventory, mStore); + iter->mBase->mInventory, mStore); } } @@ -169,64 +169,64 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce } MWWorld::Ptr ptr; - if (MWWorld::LiveCellRef *ref = cell.activators.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mActivators.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.potions.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mPotions.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.appas.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mAppas.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.armors.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mArmors.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.books.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mBooks.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.clothes.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mClothes.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.containers.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mContainers.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.creatures.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mCreatures.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.doors.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mDoors.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.ingreds.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mIngreds.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.creatureLists.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mCreatureLists.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.itemLists.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mItemLists.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.lights.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mLights.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.lockpicks.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mLockpicks.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.miscItems.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mMiscItems.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.npcs.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mNpcs.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.probes.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mProbes.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.repairs.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mRepairs.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.statics.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mStatics.find (name)) ptr = Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = cell.weapons.find (name)) + if (MWWorld::LiveCellRef *ref = cell.mWeapons.find (name)) ptr = Ptr (ref, &cell); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) { diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index fcdec1e7f..e0b435556 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -11,7 +11,8 @@ namespace MWWorld { - CellStore::CellStore (const ESM::Cell *cell_) : cell (cell_), mState (State_Unloaded) + CellStore::CellStore (const ESM::Cell *cell) + : mCell (cell), mState (State_Unloaded) { mWaterLevel = cell->mWater; } @@ -23,7 +24,7 @@ namespace MWWorld if (mState==State_Preloaded) mIds.clear(); - std::cout << "loading cell " << cell->getDescription() << std::endl; + std::cout << "loading cell " << mCell->getDescription() << std::endl; loadRefs (store, esm); @@ -43,18 +44,18 @@ namespace MWWorld void CellStore::listRefs(const ESMS::ESMStore &store, ESM::ESMReader &esm) { - assert (cell); + assert (mCell); - if (cell->mContext.filename.empty()) + if (mCell->mContext.filename.empty()) return; // this is a dynamically generated cell -> skipping. // Reopen the ESM reader and seek to the right position. - cell->restore (esm); + mCell->restore (esm); ESM::CellRef ref; // Get each reference in turn - while (cell->getNextRef (esm, ref)) + while (mCell->getNextRef (esm, ref)) { std::string lowerCase; @@ -69,18 +70,18 @@ namespace MWWorld void CellStore::loadRefs(const ESMS::ESMStore &store, ESM::ESMReader &esm) { - assert (cell); + assert (mCell); - if (cell->mContext.filename.empty()) + if (mCell->mContext.filename.empty()) return; // this is a dynamically generated cell -> skipping. // Reopen the ESM reader and seek to the right position. - cell->restore(esm); + mCell->restore(esm); ESM::CellRef ref; // Get each reference in turn - while(cell->getNextRef(esm, ref)) + while(mCell->getNextRef(esm, ref)) { std::string lowerCase; @@ -98,26 +99,26 @@ namespace MWWorld */ switch(rec) { - case ESM::REC_ACTI: activators.find(ref, store.activators); break; - case ESM::REC_ALCH: potions.find(ref, store.potions); break; - case ESM::REC_APPA: appas.find(ref, store.appas); break; - case ESM::REC_ARMO: armors.find(ref, store.armors); break; - case ESM::REC_BOOK: books.find(ref, store.books); break; - case ESM::REC_CLOT: clothes.find(ref, store.clothes); break; - case ESM::REC_CONT: containers.find(ref, store.containers); break; - case ESM::REC_CREA: creatures.find(ref, store.creatures); break; - case ESM::REC_DOOR: doors.find(ref, store.doors); break; - case ESM::REC_INGR: ingreds.find(ref, store.ingreds); break; - case ESM::REC_LEVC: creatureLists.find(ref, store.creatureLists); break; - case ESM::REC_LEVI: itemLists.find(ref, store.itemLists); break; - case ESM::REC_LIGH: lights.find(ref, store.lights); break; - case ESM::REC_LOCK: lockpicks.find(ref, store.lockpicks); break; - case ESM::REC_MISC: miscItems.find(ref, store.miscItems); break; - case ESM::REC_NPC_: npcs.find(ref, store.npcs); break; - case ESM::REC_PROB: probes.find(ref, store.probes); break; - case ESM::REC_REPA: repairs.find(ref, store.repairs); break; - case ESM::REC_STAT: statics.find(ref, store.statics); break; - case ESM::REC_WEAP: weapons.find(ref, store.weapons); break; + case ESM::REC_ACTI: mActivators.find(ref, store.activators); break; + case ESM::REC_ALCH: mPotions.find(ref, store.potions); break; + case ESM::REC_APPA: mAppas.find(ref, store.appas); break; + case ESM::REC_ARMO: mArmors.find(ref, store.armors); break; + case ESM::REC_BOOK: mBooks.find(ref, store.books); break; + case ESM::REC_CLOT: mClothes.find(ref, store.clothes); break; + case ESM::REC_CONT: mContainers.find(ref, store.containers); break; + case ESM::REC_CREA: mCreatures.find(ref, store.creatures); break; + case ESM::REC_DOOR: mDoors.find(ref, store.doors); break; + case ESM::REC_INGR: mIngreds.find(ref, store.ingreds); break; + case ESM::REC_LEVC: mCreatureLists.find(ref, store.creatureLists); break; + case ESM::REC_LEVI: mItemLists.find(ref, store.itemLists); break; + case ESM::REC_LIGH: mLights.find(ref, store.lights); break; + case ESM::REC_LOCK: mLockpicks.find(ref, store.lockpicks); break; + case ESM::REC_MISC: mMiscItems.find(ref, store.miscItems); break; + case ESM::REC_NPC_: mNpcs.find(ref, store.npcs); break; + case ESM::REC_PROB: mProbes.find(ref, store.probes); break; + case ESM::REC_REPA: mRepairs.find(ref, store.repairs); break; + case ESM::REC_STAT: mStatics.find(ref, store.statics); break; + case ESM::REC_WEAP: mWeapons.find(ref, store.weapons); break; case 0: std::cout << "Cell reference " + ref.mRefID + " not found!\n"; break; default: diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 32ab6e07b..c48e90d31 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -26,19 +26,21 @@ namespace MWWorld template struct LiveCellRef { - LiveCellRef(const ESM::CellRef& cref, const X* b = NULL) : base(b), ref(cref), - mData(ref) {} + LiveCellRef(const ESM::CellRef& cref, const X* b = NULL) + : mBase(b), mRef(cref), mData(mRef) + {} - - LiveCellRef(const X* b = NULL) : base(b), mData(ref) {} + LiveCellRef(const X* b = NULL) + : mBase(b), mData(mRef) + {} // The object that this instance is based on. - const X* base; + const X* mBase; /* Information about this instance, such as 3D location and rotation and individual type-dependent data. */ - ESM::CellRef ref; + ESM::CellRef mRef; /// runtime-data RefData mData; @@ -50,7 +52,7 @@ namespace MWWorld { typedef LiveCellRef LiveRef; typedef std::list List; - List list; + List mList; // Search for the given reference in the given reclist from // ESMStore. Insert the reference into the list if a match is @@ -62,14 +64,14 @@ namespace MWWorld if(obj == NULL) throw std::runtime_error("Error resolving cell reference " + ref.mRefID); - list.push_back(LiveRef(ref, obj)); + mList.push_back(LiveRef(ref, obj)); } LiveRef *find (const std::string& name) { - for (typename std::list::iterator iter (list.begin()); iter!=list.end(); ++iter) + for (typename std::list::iterator iter (mList.begin()); iter!=mList.end(); ++iter) { - if (iter->mData.getCount() > 0 && iter->ref.mRefID == name) + if (iter->mData.getCount() > 0 && iter->mRef.mRefID == name) return &*iter; } @@ -77,8 +79,8 @@ namespace MWWorld } LiveRef &insert(const LiveRef &item) { - list.push_back(item); - return list.back(); + mList.push_back(item); + return mList.back(); } }; @@ -94,33 +96,33 @@ namespace MWWorld CellStore (const ESM::Cell *cell_); - const ESM::Cell *cell; + const ESM::Cell *mCell; State mState; std::vector mIds; float mWaterLevel; // Lists for each individual object type - CellRefList activators; - CellRefList potions; - CellRefList appas; - CellRefList armors; - CellRefList books; - CellRefList clothes; - CellRefList containers; - CellRefList creatures; - CellRefList doors; - CellRefList ingreds; - CellRefList creatureLists; - CellRefList itemLists; - CellRefList lights; - CellRefList lockpicks; - CellRefList miscItems; - CellRefList npcs; - CellRefList probes; - CellRefList repairs; - CellRefList statics; - CellRefList weapons; + CellRefList mActivators; + CellRefList mPotions; + CellRefList mAppas; + CellRefList mArmors; + CellRefList mBooks; + CellRefList mClothes; + CellRefList mContainers; + CellRefList mCreatures; + CellRefList mDoors; + CellRefList mIngreds; + CellRefList mCreatureLists; + CellRefList mItemLists; + CellRefList mLights; + CellRefList mLockpicks; + CellRefList mMiscItems; + CellRefList mNpcs; + CellRefList mProbes; + CellRefList mRepairs; + CellRefList mStatics; + CellRefList mWeapons; void load (const ESMS::ESMStore &store, ESM::ESMReader &esm); @@ -133,32 +135,32 @@ namespace MWWorld bool forEach (Functor& functor) { return - forEachImp (functor, activators) && - forEachImp (functor, potions) && - forEachImp (functor, appas) && - forEachImp (functor, armors) && - forEachImp (functor, books) && - forEachImp (functor, clothes) && - forEachImp (functor, containers) && - forEachImp (functor, creatures) && - forEachImp (functor, doors) && - forEachImp (functor, ingreds) && - forEachImp (functor, creatureLists) && - forEachImp (functor, itemLists) && - forEachImp (functor, lights) && - forEachImp (functor, lockpicks) && - forEachImp (functor, miscItems) && - forEachImp (functor, npcs) && - forEachImp (functor, probes) && - forEachImp (functor, repairs) && - forEachImp (functor, statics) && - forEachImp (functor, weapons); + forEachImp (functor, mActivators) && + forEachImp (functor, mPotions) && + forEachImp (functor, mAppas) && + forEachImp (functor, mArmors) && + forEachImp (functor, mBooks) && + forEachImp (functor, mClothes) && + forEachImp (functor, mContainers) && + forEachImp (functor, mCreatures) && + forEachImp (functor, mDoors) && + forEachImp (functor, mIngreds) && + forEachImp (functor, mCreatureLists) && + forEachImp (functor, mItemLists) && + forEachImp (functor, mLights) && + forEachImp (functor, mLockpicks) && + forEachImp (functor, mMiscItems) && + forEachImp (functor, mNpcs) && + forEachImp (functor, mProbes) && + forEachImp (functor, mRepairs) && + forEachImp (functor, mStatics) && + forEachImp (functor, mWeapons); } bool operator==(const CellStore &cell) { - return this->cell->mName == cell.cell->mName && - this->cell->mData.mX == cell.cell->mData.mX && - this->cell->mData.mY == cell.cell->mData.mY; + return mCell->mName == cell.mCell->mName && + mCell->mData.mX == cell.mCell->mData.mX && + mCell->mData.mY == cell.mCell->mData.mY; } bool operator!=(const CellStore &cell) { @@ -166,7 +168,7 @@ namespace MWWorld } bool isExterior() const { - return cell->isExterior(); + return mCell->isExterior(); } private: @@ -174,9 +176,9 @@ namespace MWWorld template bool forEachImp (Functor& functor, List& list) { - for (typename List::List::iterator iter (list.list.begin()); iter!=list.list.end(); + for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end(); ++iter) - if (!functor (iter->ref, iter->mData)) + if (!functor (iter->mRef, iter->mData)) return false; return true; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 5c4dd03a4..78454be4b 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -24,12 +24,12 @@ namespace float sum = 0; for (typename MWWorld::CellRefList::List::const_iterator iter ( - cellRefList.list.begin()); - iter!=cellRefList.list.end(); + cellRefList.mList.begin()); + iter!=cellRefList.mList.end(); ++iter) { if (iter->mData.getCount()>0) - sum += iter->mData.getCount()*iter->base->mData.mWeight; + sum += iter->mData.getCount()*iter->mBase->mData.mWeight; } return sum; @@ -81,19 +81,19 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr) MWWorld::LiveCellRef *gold = ptr.get(); - if (compare_string_ci(gold->ref.mRefID, "gold_001") - || compare_string_ci(gold->ref.mRefID, "gold_005") - || compare_string_ci(gold->ref.mRefID, "gold_010") - || compare_string_ci(gold->ref.mRefID, "gold_025") - || compare_string_ci(gold->ref.mRefID, "gold_100")) + if (compare_string_ci(gold->mRef.mRefID, "gold_001") + || compare_string_ci(gold->mRef.mRefID, "gold_005") + || compare_string_ci(gold->mRef.mRefID, "gold_010") + || compare_string_ci(gold->mRef.mRefID, "gold_025") + || compare_string_ci(gold->mRef.mRefID, "gold_100")) { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001"); - int count = (ptr.getRefData().getCount() == 1) ? gold->base->mData.mValue : ptr.getRefData().getCount(); + int count = (ptr.getRefData().getCount() == 1) ? gold->mBase->mData.mValue : ptr.getRefData().getCount(); ref.getPtr().getRefData().setCount(count); for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) { - if (compare_string_ci((*iter).get()->ref.mRefID, "gold_001")) + if (compare_string_ci((*iter).get()->mRef.mRefID, "gold_001")) { (*iter).getRefData().setCount( (*iter).getRefData().getCount() + count); flagAsModified(); @@ -127,18 +127,18 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr switch (getType(ptr)) { - case Type_Potion: potions.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --potions.list.end()); break; - case Type_Apparatus: appas.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --appas.list.end()); break; - case Type_Armor: armors.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --armors.list.end()); break; - case Type_Book: books.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --books.list.end()); break; - case Type_Clothing: clothes.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --clothes.list.end()); break; - case Type_Ingredient: ingreds.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --ingreds.list.end()); break; - case Type_Light: lights.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lights.list.end()); break; - case Type_Lockpick: lockpicks.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lockpicks.list.end()); break; - case Type_Miscellaneous: miscItems.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --miscItems.list.end()); break; - case Type_Probe: probes.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --probes.list.end()); break; - case Type_Repair: repairs.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --repairs.list.end()); break; - case Type_Weapon: weapons.list.push_back (*ptr.get()); it = ContainerStoreIterator(this, --weapons.list.end()); break; + case Type_Potion: potions.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --potions.mList.end()); break; + case Type_Apparatus: appas.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --appas.mList.end()); break; + case Type_Armor: armors.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --armors.mList.end()); break; + case Type_Book: books.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --books.mList.end()); break; + case Type_Clothing: clothes.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --clothes.mList.end()); break; + case Type_Ingredient: ingreds.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --ingreds.mList.end()); break; + case Type_Light: lights.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lights.mList.end()); break; + case Type_Lockpick: lockpicks.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lockpicks.mList.end()); break; + case Type_Miscellaneous: miscItems.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --miscItems.mList.end()); break; + case Type_Probe: probes.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --probes.mList.end()); break; + case Type_Repair: repairs.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --repairs.mList.end()); break; + case Type_Weapon: weapons.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --weapons.mList.end()); break; } flagAsModified(); @@ -326,63 +326,63 @@ bool MWWorld::ContainerStoreIterator::resetIterator() { case ContainerStore::Type_Potion: - mPotion = mContainer->potions.list.begin(); - return mPotion!=mContainer->potions.list.end(); + mPotion = mContainer->potions.mList.begin(); + return mPotion!=mContainer->potions.mList.end(); case ContainerStore::Type_Apparatus: - mApparatus = mContainer->appas.list.begin(); - return mApparatus!=mContainer->appas.list.end(); + mApparatus = mContainer->appas.mList.begin(); + return mApparatus!=mContainer->appas.mList.end(); case ContainerStore::Type_Armor: - mArmor = mContainer->armors.list.begin(); - return mArmor!=mContainer->armors.list.end(); + mArmor = mContainer->armors.mList.begin(); + return mArmor!=mContainer->armors.mList.end(); case ContainerStore::Type_Book: - mBook = mContainer->books.list.begin(); - return mBook!=mContainer->books.list.end(); + mBook = mContainer->books.mList.begin(); + return mBook!=mContainer->books.mList.end(); case ContainerStore::Type_Clothing: - mClothing = mContainer->clothes.list.begin(); - return mClothing!=mContainer->clothes.list.end(); + mClothing = mContainer->clothes.mList.begin(); + return mClothing!=mContainer->clothes.mList.end(); case ContainerStore::Type_Ingredient: - mIngredient = mContainer->ingreds.list.begin(); - return mIngredient!=mContainer->ingreds.list.end(); + mIngredient = mContainer->ingreds.mList.begin(); + return mIngredient!=mContainer->ingreds.mList.end(); case ContainerStore::Type_Light: - mLight = mContainer->lights.list.begin(); - return mLight!=mContainer->lights.list.end(); + mLight = mContainer->lights.mList.begin(); + return mLight!=mContainer->lights.mList.end(); case ContainerStore::Type_Lockpick: - mLockpick = mContainer->lockpicks.list.begin(); - return mLockpick!=mContainer->lockpicks.list.end(); + mLockpick = mContainer->lockpicks.mList.begin(); + return mLockpick!=mContainer->lockpicks.mList.end(); case ContainerStore::Type_Miscellaneous: - mMiscellaneous = mContainer->miscItems.list.begin(); - return mMiscellaneous!=mContainer->miscItems.list.end(); + mMiscellaneous = mContainer->miscItems.mList.begin(); + return mMiscellaneous!=mContainer->miscItems.mList.end(); case ContainerStore::Type_Probe: - mProbe = mContainer->probes.list.begin(); - return mProbe!=mContainer->probes.list.end(); + mProbe = mContainer->probes.mList.begin(); + return mProbe!=mContainer->probes.mList.end(); case ContainerStore::Type_Repair: - mRepair = mContainer->repairs.list.begin(); - return mRepair!=mContainer->repairs.list.end(); + mRepair = mContainer->repairs.mList.begin(); + return mRepair!=mContainer->repairs.mList.end(); case ContainerStore::Type_Weapon: - mWeapon = mContainer->weapons.list.begin(); - return mWeapon!=mContainer->weapons.list.end(); + mWeapon = mContainer->weapons.mList.begin(); + return mWeapon!=mContainer->weapons.mList.end(); } return false; @@ -395,62 +395,62 @@ bool MWWorld::ContainerStoreIterator::incIterator() case ContainerStore::Type_Potion: ++mPotion; - return mPotion==mContainer->potions.list.end(); + return mPotion==mContainer->potions.mList.end(); case ContainerStore::Type_Apparatus: ++mApparatus; - return mApparatus==mContainer->appas.list.end(); + return mApparatus==mContainer->appas.mList.end(); case ContainerStore::Type_Armor: ++mArmor; - return mArmor==mContainer->armors.list.end(); + return mArmor==mContainer->armors.mList.end(); case ContainerStore::Type_Book: ++mBook; - return mBook==mContainer->books.list.end(); + return mBook==mContainer->books.mList.end(); case ContainerStore::Type_Clothing: ++mClothing; - return mClothing==mContainer->clothes.list.end(); + return mClothing==mContainer->clothes.mList.end(); case ContainerStore::Type_Ingredient: ++mIngredient; - return mIngredient==mContainer->ingreds.list.end(); + return mIngredient==mContainer->ingreds.mList.end(); case ContainerStore::Type_Light: ++mLight; - return mLight==mContainer->lights.list.end(); + return mLight==mContainer->lights.mList.end(); case ContainerStore::Type_Lockpick: ++mLockpick; - return mLockpick==mContainer->lockpicks.list.end(); + return mLockpick==mContainer->lockpicks.mList.end(); case ContainerStore::Type_Miscellaneous: ++mMiscellaneous; - return mMiscellaneous==mContainer->miscItems.list.end(); + return mMiscellaneous==mContainer->miscItems.mList.end(); case ContainerStore::Type_Probe: ++mProbe; - return mProbe==mContainer->probes.list.end(); + return mProbe==mContainer->probes.mList.end(); case ContainerStore::Type_Repair: ++mRepair; - return mRepair==mContainer->repairs.list.end(); + return mRepair==mContainer->repairs.mList.end(); case ContainerStore::Type_Weapon: ++mWeapon; - return mWeapon==mContainer->weapons.list.end(); + return mWeapon==mContainer->weapons.mList.end(); } return true; diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index d0d698feb..1f11b6233 100644 --- a/apps/openmw/mwworld/localscripts.cpp +++ b/apps/openmw/mwworld/localscripts.cpp @@ -12,12 +12,12 @@ namespace MWWorld::CellRefList& cellRefList, MWWorld::Ptr::CellStore *cell) { for (typename MWWorld::CellRefList::List::iterator iter ( - cellRefList.list.begin()); - iter!=cellRefList.list.end(); ++iter) + cellRefList.mList.begin()); + iter!=cellRefList.mList.end(); ++iter) { - if (!iter->base->mScript.empty() && iter->mData.getCount()) + if (!iter->mBase->mScript.empty() && iter->mData.getCount()) { - localScripts.add (iter->base->mScript, MWWorld::Ptr (&*iter, cell)); + localScripts.add (iter->mBase->mScript, MWWorld::Ptr (&*iter, cell)); } } } @@ -73,23 +73,23 @@ void MWWorld::LocalScripts::add (const std::string& scriptName, const Ptr& ptr) void MWWorld::LocalScripts::addCell (Ptr::CellStore *cell) { - listCellScripts (*this, cell->activators, cell); - listCellScripts (*this, cell->potions, cell); - listCellScripts (*this, cell->appas, cell); - listCellScripts (*this, cell->armors, cell); - listCellScripts (*this, cell->books, cell); - listCellScripts (*this, cell->clothes, cell); - listCellScripts (*this, cell->containers, cell); - listCellScripts (*this, cell->creatures, cell); - listCellScripts (*this, cell->doors, cell); - listCellScripts (*this, cell->ingreds, cell); - listCellScripts (*this, cell->lights, cell); - listCellScripts (*this, cell->lockpicks, cell); - listCellScripts (*this, cell->miscItems, cell); - listCellScripts (*this, cell->npcs, cell); - listCellScripts (*this, cell->probes, cell); - listCellScripts (*this, cell->repairs, cell); - listCellScripts (*this, cell->weapons, cell); + listCellScripts (*this, cell->mActivators, cell); + listCellScripts (*this, cell->mPotions, cell); + listCellScripts (*this, cell->mAppas, cell); + listCellScripts (*this, cell->mArmors, cell); + listCellScripts (*this, cell->mBooks, cell); + listCellScripts (*this, cell->mClothes, cell); + listCellScripts (*this, cell->mContainers, cell); + listCellScripts (*this, cell->mCreatures, cell); + listCellScripts (*this, cell->mDoors, cell); + listCellScripts (*this, cell->mIngreds, cell); + listCellScripts (*this, cell->mLights, cell); + listCellScripts (*this, cell->mLockpicks, cell); + listCellScripts (*this, cell->mMiscItems, cell); + listCellScripts (*this, cell->mNpcs, cell); + listCellScripts (*this, cell->mProbes, cell); + listCellScripts (*this, cell->mRepairs, cell); + listCellScripts (*this, cell->mWeapons, cell); } void MWWorld::LocalScripts::clear() diff --git a/apps/openmw/mwworld/manualref.hpp b/apps/openmw/mwworld/manualref.hpp index 6570761ab..94e9dad15 100644 --- a/apps/openmw/mwworld/manualref.hpp +++ b/apps/openmw/mwworld/manualref.hpp @@ -25,7 +25,7 @@ namespace MWWorld if (const T *instance = list.search (name)) { LiveCellRef ref; - ref.base = instance; + ref.mBase = instance; mRef = ref; mPtr = Ptr (&boost::any_cast&> (mRef), 0); @@ -42,7 +42,7 @@ namespace MWWorld if (const T *instance = list.search (name)) { LiveCellRef ref; - ref.base = instance; + ref.mBase = instance; mRef = ref; mPtr = Ptr (&boost::any_cast&> (mRef), 0); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index e1eb02c32..a436875ca 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -17,8 +17,8 @@ namespace MWWorld mCellStore (0), mClass (0), mAutoMove (false), mForwardBackward (0) { - mPlayer.base = player; - mPlayer.ref.mRefID = "player"; + mPlayer.mBase = player; + mPlayer.mRef.mRefID = "player"; mName = player->mName; mMale = !(player->mFlags & ESM::NPC::Female); mRace = player->mRace; diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index f74fdd3ef..594ddef2d 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -50,7 +50,7 @@ namespace MWWorld : mContainerStore (0) { mPtr = liveCellRef; - mCellRef = &liveCellRef->ref; + mCellRef = &liveCellRef->mRef; mRefData = &liveCellRef->mData; mCell = cell; mTypeName = typeid (T).name(); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 517025fb2..ea62c0b3c 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -20,15 +20,15 @@ namespace void insertCellRefList(MWRender::RenderingManager& rendering, T& cellRefList, MWWorld::CellStore &cell, MWWorld::PhysicsSystem& physics) { - if (!cellRefList.list.empty()) + if (!cellRefList.mList.empty()) { const MWWorld::Class& class_ = - MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell)); + MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell)); - int numRefs = cellRefList.list.size(); + int numRefs = cellRefList.mList.size(); int current = 0; - for (typename T::List::iterator it = cellRefList.list.begin(); - it != cellRefList.list.end(); it++) + for (typename T::List::iterator it = cellRefList.mList.begin(); + it != cellRefList.mList.end(); it++) { MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, current, numRefs); ++current; @@ -80,11 +80,15 @@ namespace MWWorld mPhysics->removeObject (node->getName()); } - if (!((*iter)->cell->mData.mFlags & ESM::Cell::Interior)) + if ((*iter)->mCell->isExterior()) { - ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search((*iter)->cell->mData.mX,(*iter)->cell->mData.mY); + ESM::Land* land = + MWBase::Environment::get().getWorld()->getStore().lands.search( + (*iter)->mCell->getGridX(), + (*iter)->mCell->getGridY() + ); if (land) - mPhysics->removeHeightField( (*iter)->cell->mData.mX, (*iter)->cell->mData.mY ); + mPhysics->removeHeightField( (*iter)->mCell->getGridX(), (*iter)->mCell->getGridY() ); } } @@ -111,13 +115,23 @@ namespace MWWorld float verts = ESM::Land::LAND_SIZE; float worldsize = ESM::Land::REAL_SIZE; - if (!(cell->cell->mData.mFlags & ESM::Cell::Interior)) + if (cell->mCell->isExterior()) { - ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cell->cell->mData.mX,cell->cell->mData.mY); - if (land) - mPhysics->addHeightField (land->mLandData->mHeights, - cell->cell->mData.mX, cell->cell->mData.mY, - 0, ( worldsize/(verts-1) ), verts); + ESM::Land* land = + MWBase::Environment::get().getWorld()->getStore().lands.search( + cell->mCell->getGridX(), + cell->mCell->getGridY() + ); + if (land) { + mPhysics->addHeightField ( + land->mLandData->mHeights, + cell->mCell->getGridX(), + cell->mCell->getGridY(), + 0, + worldsize / (verts-1), + verts) + ; + } } mRendering.configureAmbient(*cell); @@ -128,8 +142,8 @@ namespace MWWorld void Scene::playerCellChange(MWWorld::CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos) { - bool hasWater = cell->cell->mData.mFlags & cell->cell->HasWater; - mPhysics->setCurrentWater(hasWater, cell->cell->mWater); + bool hasWater = cell->mCell->mData.mFlags & ESM::Cell::HasWater; + mPhysics->setCurrentWater(hasWater, cell->mCell->mWater); MWBase::World *world = MWBase::Environment::get().getWorld(); world->getPlayer().setCell(cell); @@ -167,10 +181,10 @@ namespace MWWorld int numUnload = 0; while (active!=mActiveCells.end()) { - if (!((*active)->cell->mData.mFlags & ESM::Cell::Interior)) + if ((*active)->mCell->isExterior()) { - if (std::abs (X-(*active)->cell->mData.mX)<=1 && - std::abs (Y-(*active)->cell->mData.mY)<=1) + if (std::abs (X-(*active)->mCell->getGridX())<=1 && + std::abs (Y-(*active)->mCell->getGridY())<=1) { // keep cells within the new 3x3 grid ++active; @@ -185,10 +199,10 @@ namespace MWWorld active = mActiveCells.begin(); while (active!=mActiveCells.end()) { - if (!((*active)->cell->mData.mFlags & ESM::Cell::Interior)) + if ((*active)->mCell->isExterior()) { - if (std::abs (X-(*active)->cell->mData.mX)<=1 && - std::abs (Y-(*active)->cell->mData.mY)<=1) + if (std::abs (X-(*active)->mCell->getGridX())<=1 && + std::abs (Y-(*active)->mCell->getGridY())<=1) { // keep cells within the new 3x3 grid ++active; @@ -210,10 +224,10 @@ namespace MWWorld while (iter!=mActiveCells.end()) { - assert (!((*iter)->cell->mData.mFlags & ESM::Cell::Interior)); + assert ((*iter)->mCell->isExterior()); - if (x==(*iter)->cell->mData.mX && - y==(*iter)->cell->mData.mY) + if (x==(*iter)->mCell->getGridX() && + y==(*iter)->mCell->getGridY()) break; ++iter; @@ -232,10 +246,10 @@ namespace MWWorld while (iter!=mActiveCells.end()) { - assert (!((*iter)->cell->mData.mFlags & ESM::Cell::Interior)); + assert ((*iter)->mCell->isExterior()); - if (x==(*iter)->cell->mData.mX && - y==(*iter)->cell->mData.mY) + if (x==(*iter)->mCell->getGridX() && + y==(*iter)->mCell->getGridY()) break; ++iter; @@ -256,10 +270,10 @@ namespace MWWorld while (iter!=mActiveCells.end()) { - assert (!((*iter)->cell->mData.mFlags & ESM::Cell::Interior)); + assert ((*iter)->mCell->isExterior()); - if (X==(*iter)->cell->mData.mX && - Y==(*iter)->cell->mData.mY) + if (X==(*iter)->mCell->getGridX() && + Y==(*iter)->mCell->getGridY()) break; ++iter; @@ -376,26 +390,26 @@ namespace MWWorld void Scene::insertCell (Ptr::CellStore &cell) { // Loop through all references in the cell - insertCellRefList(mRendering, cell.activators, cell, *mPhysics); - insertCellRefList(mRendering, cell.potions, cell, *mPhysics); - insertCellRefList(mRendering, cell.appas, cell, *mPhysics); - insertCellRefList(mRendering, cell.armors, cell, *mPhysics); - insertCellRefList(mRendering, cell.books, cell, *mPhysics); - insertCellRefList(mRendering, cell.clothes, cell, *mPhysics); - insertCellRefList(mRendering, cell.containers, cell, *mPhysics); - insertCellRefList(mRendering, cell.creatures, cell, *mPhysics); - insertCellRefList(mRendering, cell.doors, cell, *mPhysics); - insertCellRefList(mRendering, cell.ingreds, cell, *mPhysics); - insertCellRefList(mRendering, cell.creatureLists, cell, *mPhysics); - insertCellRefList(mRendering, cell.itemLists, cell, *mPhysics); - insertCellRefList(mRendering, cell.lights, cell, *mPhysics); - insertCellRefList(mRendering, cell.lockpicks, cell, *mPhysics); - insertCellRefList(mRendering, cell.miscItems, cell, *mPhysics); - insertCellRefList(mRendering, cell.npcs, cell, *mPhysics); - insertCellRefList(mRendering, cell.probes, cell, *mPhysics); - insertCellRefList(mRendering, cell.repairs, cell, *mPhysics); - insertCellRefList(mRendering, cell.statics, cell, *mPhysics); - insertCellRefList(mRendering, cell.weapons, cell, *mPhysics); + insertCellRefList(mRendering, cell.mActivators, cell, *mPhysics); + insertCellRefList(mRendering, cell.mPotions, cell, *mPhysics); + insertCellRefList(mRendering, cell.mAppas, cell, *mPhysics); + insertCellRefList(mRendering, cell.mArmors, cell, *mPhysics); + insertCellRefList(mRendering, cell.mBooks, cell, *mPhysics); + insertCellRefList(mRendering, cell.mClothes, cell, *mPhysics); + insertCellRefList(mRendering, cell.mContainers, cell, *mPhysics); + insertCellRefList(mRendering, cell.mCreatures, cell, *mPhysics); + insertCellRefList(mRendering, cell.mDoors, cell, *mPhysics); + insertCellRefList(mRendering, cell.mIngreds, cell, *mPhysics); + insertCellRefList(mRendering, cell.mCreatureLists, cell, *mPhysics); + insertCellRefList(mRendering, cell.mItemLists, cell, *mPhysics); + insertCellRefList(mRendering, cell.mLights, cell, *mPhysics); + insertCellRefList(mRendering, cell.mLockpicks, cell, *mPhysics); + insertCellRefList(mRendering, cell.mMiscItems, cell, *mPhysics); + insertCellRefList(mRendering, cell.mNpcs, cell, *mPhysics); + insertCellRefList(mRendering, cell.mProbes, cell, *mPhysics); + insertCellRefList(mRendering, cell.mRepairs, cell, *mPhysics); + insertCellRefList(mRendering, cell.mStatics, cell, *mPhysics); + insertCellRefList(mRendering, cell.mWeapons, cell, *mPhysics); } void Scene::addObjectToScene (const Ptr& ptr) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 391b34a84..7d40e8ed4 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -497,7 +497,7 @@ void WeatherManager::update(float duration) if (exterior) { - std::string regionstr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->mRegion; + std::string regionstr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion; boost::algorithm::to_lower(regionstr); if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c7f0de245..1685798a2 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -25,10 +25,10 @@ namespace MWWorld::Ptr::CellStore *cell) { for (typename MWWorld::CellRefList::List::iterator iter ( - cellRefList.list.begin()); - iter!=cellRefList.list.end(); ++iter) + cellRefList.mList.begin()); + iter!=cellRefList.mList.end(); ++iter) { - if (!iter->base->script.empty() && iter->mData.getCount()) + if (!iter->mBase->script.empty() && iter->mData.getCount()) { if (const ESM::Script *script = store.scripts.find (iter->base->script)) { @@ -46,7 +46,7 @@ namespace { typedef typename MWWorld::CellRefList::List::iterator iterator; - for (iterator iter (refList.list.begin()); iter!=refList.list.end(); ++iter) + for (iterator iter (refList.mList.begin()); iter!=refList.mList.end(); ++iter) { if(iter->mData.getCount() > 0 && iter->mData.getBaseNode()){ if (iter->mData.getHandle()==handle) @@ -64,44 +64,44 @@ namespace MWWorld Ptr World::getPtrViaHandle (const std::string& handle, Ptr::CellStore& cell) { if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.activators)) + searchViaHandle (handle, cell.mActivators)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.potions)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mPotions)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.appas)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mAppas)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.armors)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mArmors)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.books)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mBooks)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.clothes)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mClothes)) return Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.containers)) + searchViaHandle (handle, cell.mContainers)) return Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.creatures)) + searchViaHandle (handle, cell.mCreatures)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.doors)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mDoors)) return Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.ingreds)) + searchViaHandle (handle, cell.mIngreds)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.lights)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mLights)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.lockpicks)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mLockpicks)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.miscItems)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mMiscItems)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.npcs)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mNpcs)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.probes)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mProbes)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.repairs)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mRepairs)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.statics)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mStatics)) return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.weapons)) + if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mWeapons)) return Ptr (ref, &cell); return Ptr(); } @@ -585,10 +585,10 @@ namespace MWWorld if (*currCell != newCell) { if (isPlayer) { if (!newCell.isExterior()) { - changeToInteriorCell(toLower(newCell.cell->mName), pos); + changeToInteriorCell(toLower(newCell.mCell->mName), pos); } else { - int cellX = newCell.cell->mData.mX; - int cellY = newCell.cell->mData.mY; + int cellX = newCell.mCell->getGridX(); + int cellY = newCell.mCell->getGridY(); mWorldScene->changeCell(cellX, cellY, pos, false); } } else { @@ -1033,10 +1033,7 @@ namespace MWWorld Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); if (currentCell) { - if (!(currentCell->cell->mData.mFlags & ESM::Cell::Interior)) - return true; - else - return false; + return currentCell->mCell->isExterior(); } return false; } @@ -1046,7 +1043,7 @@ namespace MWWorld Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); if (currentCell) { - if (!(currentCell->cell->mData.mFlags & ESM::Cell::QuasiEx)) + if (!(currentCell->mCell->mData.mFlags & ESM::Cell::QuasiEx)) return false; else return true; @@ -1071,7 +1068,7 @@ namespace MWWorld Ogre::Vector2 World::getNorthVector (CellStore* cell) { - MWWorld::CellRefList& statics = cell->statics; + MWWorld::CellRefList& statics = cell->mStatics; MWWorld::LiveCellRef* ref = statics.find("northmarker"); if (!ref) return Vector2(0, 1); @@ -1085,27 +1082,27 @@ namespace MWWorld { std::vector result; - MWWorld::CellRefList& doors = cell->doors; - std::list< MWWorld::LiveCellRef >& refList = doors.list; + MWWorld::CellRefList& doors = cell->mDoors; + std::list< MWWorld::LiveCellRef >& refList = doors.mList; for (std::list< MWWorld::LiveCellRef >::iterator it = refList.begin(); it != refList.end(); ++it) { MWWorld::LiveCellRef& ref = *it; - if (ref.ref.mTeleport) + if (ref.mRef.mTeleport) { World::DoorMarker newMarker; std::string dest; - if (ref.ref.mDestCell != "") + if (ref.mRef.mDestCell != "") { // door leads to an interior, use interior name - dest = ref.ref.mDestCell; + dest = ref.mRef.mDestCell; } else { // door leads to exterior, use cell name (if any), otherwise translated region name int x,y; - positionToIndex (ref.ref.mDoorDest.pos[0], ref.ref.mDoorDest.pos[1], x, y); + positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y); const ESM::Cell* cell = mStore.cells.findExt(x,y); if (cell->mName != "") dest = cell->mName; @@ -1256,7 +1253,7 @@ namespace MWWorld /// \fixme should rely on object height pos.z += 30; - return isUnderwater(*object.getCell()->cell, pos); + return isUnderwater(*object.getCell()->mCell, pos); } bool @@ -1292,10 +1289,10 @@ namespace MWWorld mPhysics->castRay(playerPos, Ogre::Vector3(0,0,-1), 50); bool isOnGround = (hit.first ? (hit.second.distance (playerPos) < 25) : false); - if (!isOnGround || isUnderwater (*currentCell->cell, playerPos)) + if (!isOnGround || isUnderwater (*currentCell->mCell, playerPos)) return 2; - if (currentCell->cell->mData.mFlags & ESM::Cell::NoSleep) + if (currentCell->mCell->mData.mFlags & ESM::Cell::NoSleep) return 1; return 0; From f0a3ee0ef90b3fbd633c2f1c3dd8e69fca526f31 Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 1 Oct 2012 17:15:16 +0400 Subject: [PATCH 110/255] gmst id should be lowercase, wipe RecIdListT --- components/esm/loadgmst.cpp | 32 ++++++++++-------- components/esm_store/reclists.hpp | 54 ------------------------------- components/esm_store/store.hpp | 2 +- 3 files changed, 19 insertions(+), 69 deletions(-) diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp index dcc500125..14e29f4ae 100644 --- a/components/esm/loadgmst.cpp +++ b/components/esm/loadgmst.cpp @@ -2,6 +2,8 @@ #include +#include + #include "esmreader.hpp" #include "esmwriter.hpp" @@ -12,9 +14,9 @@ namespace ESM /// working properly in its current state and I doubt it can be fixed without breaking other stuff. // Some handy macros -#define cI(s,x) { if(mId == (s)) return (mI == (x)); } -#define cF(s,x) { if(mId == (s)) return (mF == (x)); } -#define cS(s,x) { if(mId == (s)) return (mStr == (x)); } +#define cI(s,x) { label = (s); boost::algorithm::to_lower(label); if (mId == label) return (mI == (x)); } +#define cF(s,x) { label = (s); boost::algorithm::to_lower(label); if (mId == label) return (mF == (x)); } +#define cS(s,x) { label = (s); boost::algorithm::to_lower(label); if (mId == label) return (mStr == (x)); } bool GameSetting::isDirtyTribunal() { @@ -28,6 +30,7 @@ bool GameSetting::isDirtyTribunal() from other mods. */ + std::string label; // Strings cS("sProfitValue", "Profit Value"); // 'Profit:' cS("sEditNote", "Edit Note"); // same @@ -51,13 +54,14 @@ bool GameSetting::isDirtyTribunal() // [The difference here is "Profit Value" -> "Profit"] // Strings that matches the mId - cS("sEffectSummonFabricant", mId);// 'Summon Fabricant' + cS("sEffectSummonFabricant", "sEffectSummonFabricant");// 'Summon Fabricant' return false; } // Bloodmoon variant bool GameSetting::isDirtyBloodmoon() { + std::string label; // Strings cS("sWerewolfPopup", "Werewolf"); // same cS("sWerewolfRestMessage", @@ -69,16 +73,16 @@ bool GameSetting::isDirtyBloodmoon() // 'You have been detected as a known werewolf.' // Strings that matches the mId - cS("sMagicCreature01ID", mId); // 'BM_wolf_grey_summon' - cS("sMagicCreature02ID", mId); // 'BM_bear_black_summon' - cS("sMagicCreature03ID", mId); // 'BM_wolf_bone_summon' - cS("sMagicCreature04ID", mId); // same - cS("sMagicCreature05ID", mId); // same - cS("sEffectSummonCreature01", mId); // 'Calf Wolf' - cS("sEffectSummonCreature02", mId); // 'Calf Bear' - cS("sEffectSummonCreature03", mId); // 'Summon Bonewolf' - cS("sEffectSummonCreature04", mId); // same - cS("sEffectSummonCreature05", mId); // same + cS("sMagicCreature01ID", "sMagicCreature01ID"); // 'BM_wolf_grey_summon' + cS("sMagicCreature02ID", "sMagicCreature02ID"); // 'BM_bear_black_summon' + cS("sMagicCreature03ID", "sMagicCreature03ID"); // 'BM_wolf_bone_summon' + cS("sMagicCreature04ID", "sMagicCreature04ID"); // same + cS("sMagicCreature05ID", "sMagicCreature05ID"); // same + cS("sEffectSummonCreature01", "sEffectSummonCreature01"); // 'Calf Wolf' + cS("sEffectSummonCreature02", "sEffectSummonCreature02"); // 'Calf Bear' + cS("sEffectSummonCreature03", "sEffectSummonCreature03"); // 'Summon Bonewolf' + cS("sEffectSummonCreature04", "sEffectSummonCreature04"); // same + cS("sEffectSummonCreature05", "sEffectSummonCreature05"); // same // Integers cI("iWereWolfBounty", 10000); // 1000 diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 0b265a566..d9a764805 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -209,60 +209,6 @@ namespace ESMS } }; - // The only difference to the above is a slight change to the load() - // function. We might merge these together later, and store the id - // in all the structs. - template - struct RecIDListT : RecList - { - virtual ~RecIDListT() {} - - typedef std::map MapType; - - MapType list; - - void load(ESMReader &esm, const std::string &id) - { - std::string id2 = toLower (id); - X& ref = list[id2]; - - ref.mId = id; - ref.load(esm); - } - - // Find the given object ID, or return NULL if not found. - const X* search(const std::string &id) const - { - std::string id2 = toLower (id); - - typename MapType::const_iterator iter = list.find (id2); - - if (iter == list.end()) - return NULL; - - return &iter->second; - } - - // Find the given object ID (throws an exception if not found) - const X* find(const std::string &id) const - { - const X *object = search (id); - - if (!object) - throw std::runtime_error ("object " + id + " not found"); - - return object; - } - - int getSize() { return list.size(); } - - virtual void listIdentifier (std::vector& identifier) const - { - for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) - identifier.push_back (iter->first); - } - }; - /* Land textures are indexed by an integer number */ struct LTexList : RecList diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index 7329386d4..db36afd33 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -68,7 +68,7 @@ namespace ESMS // Lists that need special rules CellList cells; - RecIDListT gameSettings; + RecListWithIDT gameSettings; LandList lands; LTexList landTexts; ScriptListT