From 9d7c35ae4872f15682b0c0f34345ae05e1ecce90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 23 Sep 2012 00:36:20 +0200 Subject: [PATCH 01/10] 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/10] 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/10] 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 636f297f10fd41e5c083a0b02f2edda7ff3de22e Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 28 Sep 2012 16:52:42 +0200 Subject: [PATCH 04/10] 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 21493c2dbd9979e51673c589e88e95c6962be8b8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 1 Oct 2012 23:33:07 +0200 Subject: [PATCH 05/10] 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 06/10] 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 07/10] 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 08/10] 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 f154031e54d21271d8ee0f01818613d13eb94355 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 11 Oct 2012 18:26:29 +0200 Subject: [PATCH 09/10] 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 10/10] 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