From 9d7c35ae4872f15682b0c0f34345ae05e1ecce90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 23 Sep 2012 00:36:20 +0200 Subject: [PATCH 01/34] 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 02/34] 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 03/34] 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 04/34] 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 1971ba66f18cccd06b60b63b7b29c06e46ebf7de Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 27 Sep 2012 13:08:38 +0200 Subject: [PATCH 05/34] 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 06/34] 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 07/34] 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 21493c2dbd9979e51673c589e88e95c6962be8b8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 1 Oct 2012 23:33:07 +0200 Subject: [PATCH 08/34] 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 7ee038fdd7fcb51f901893ae0e6554a2f0cc3dc1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 3 Oct 2012 12:03:07 +0200 Subject: [PATCH 09/34] 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 10/34] 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 | 121 ++++++------- apps/openmw/mwgui/windowmanagerimp.cpp | 1 + files/mygui/openmw_enchanting_dialog.layout | 25 ++- .../mygui/openmw_spellcreation_dialog.layout | 3 +- 8 files changed, 287 insertions(+), 74 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) + { + spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); + } + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { - 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", ""); + static const char *attributes[8] = { + "sAttributeStrength", + "sAttributeIntelligence", + "sAttributeWillpower", + "sAttributeAgility", + "sAttributeSpeed", + "sAttributeEndurance", + "sAttributePersonality", + "sAttributeLuck" + }; + spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); + } - std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); - std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); - if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + 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 += " " + 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], ""); + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " " + pts; } + } - if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + // constant effects have no duration and no target + if (!mEffectParams.mIsConstant) + { + if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) { - 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; - } + spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); } - // constant effects have no duration and no target - if (!mEffectParams.mIsConstant) + // potions have no target + if (!mEffectParams.mNoTarget) { - 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", ""); - } + 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; - } - if (mImageWidget) - { - std::string path = std::string("icons\\") + magicEffect->mIcon; - fixTexturePath(path); - mImageWidget->setImageTexture(path); } + + 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 11/34] 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 | 86 +++++++++++++-------- apps/openmw/mwgui/spellcreationdialog.hpp | 61 +++++++++------ files/mygui/openmw_enchanting_dialog.layout | 3 +- 5 files changed, 101 insertions(+), 59 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); + setWidgets(mAvailableEffectsList, mUsedEffectsView); + } - mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectAdded); - mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectModified); - mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &SpellCreationDialog::onEffectRemoved); + 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) + // ------------------------------------------------------------------------------------------------ + + + EffectEditorBase::EffectEditorBase(MWBase::WindowManager& parWindowManager) + : mAddEffectDialog(parWindowManager) + , mSelectAttributeDialog(NULL) + , mSelectSkillDialog(NULL) { - mPtr = actor; + 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) - { - mWindowManager.removeGuiMode (MWGui::GM_SpellCreation); } - void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) + void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView) { + mAvailableEffectsList = availableEffectsList; + mUsedEffectsView = usedEffectsView; + mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked); } - 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,54 +67,69 @@ namespace MWGui ESM::ENAMstruct mEffect; }; - class SpellCreationDialog : public WindowBase, public ReferenceInterface + + class EffectEditorBase { public: - SpellCreationDialog(MWBase::WindowManager& parWindowManager); + EffectEditorBase(MWBase::WindowManager& parWindowManager); - virtual void open(); - - void startSpellMaking(MWWorld::Ptr actor); protected: - virtual void onReferenceUnavailable (); + 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 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 onEditEffect(MyGUI::Widget* sender); void updateEffectsView(); - void onEditEffect(MyGUI::Widget* sender); + void startEditing(); + void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); + + }; + + class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase + { + 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; - 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 12/34] 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 13/34] 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 14/34] 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 15/34] 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 16/34] 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 17/34] 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 18/34] 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 19/34] 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 20/34] 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 21/34] 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 | 499 +++++++++++++++++++++++---------------- apps/esmtool/record.hpp | 4 +- 3 files changed, 319 insertions(+), 213 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 << " 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 << " 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::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 68a856ff6fe8f86a7de123e69eaf4061e1764828 Mon Sep 17 00:00:00 2001 From: cfcohen Date: Wed, 10 Oct 2012 22:00:44 -0400 Subject: [PATCH 22/34] 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 | 319 ++++++++----- 4 files changed, 1165 insertions(+), 104 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 << " 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; + 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::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; + + 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)); + + 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 23/34] 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 24/34] 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 25/34] 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 | 77 ++++++++------ 6 files changed, 189 insertions(+), 40 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 8ccb0907e647dc02f770aaf5357927605dac811f Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Oct 2012 14:26:10 +0200 Subject: [PATCH 26/34] 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 c9afe222bec803da4035e9e106b73acc55c5af77 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 16 Oct 2012 19:34:29 +0200 Subject: [PATCH 27/34] 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 28/34] 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 29/34] 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 30/34] 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 1a2034b4dddfacafd52a2fbd2eeec72e008d4b57 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 17 Oct 2012 18:03:02 +0200 Subject: [PATCH 31/34] 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 32/34] 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 33/34] 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 34/34] 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 @@ - + -