From e2f15181f95890d6caa4555cd462408f77180a5a Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 24 Aug 2014 16:36:19 +0200 Subject: [PATCH 1/7] Make the "Choose an Attribute" text centered --- files/mygui/openmw_chargen_select_attribute.layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/mygui/openmw_chargen_select_attribute.layout b/files/mygui/openmw_chargen_select_attribute.layout index f0f72bb0fa..a93b5c4530 100644 --- a/files/mygui/openmw_chargen_select_attribute.layout +++ b/files/mygui/openmw_chargen_select_attribute.layout @@ -6,7 +6,7 @@ - + From e8a245bea3a331ffe7edc06a0959bf74e5248a43 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 24 Aug 2014 16:41:17 +0200 Subject: [PATCH 2/7] Enchanting dialog: follow vanilla behavior more closely --- apps/openmw/mwgui/enchantingdialog.cpp | 4 ++++ files/mygui/openmw_enchanting_dialog.layout | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 8612617c14..d5098adbf1 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -87,6 +87,7 @@ namespace MWGui } else { + mName->setCaption(item.getClass().getName(item)); mItemBox->setItem(item); mItemBox->setUserString ("ToolTipType", "ItemPtr"); mItemBox->setUserData(item); @@ -208,6 +209,7 @@ namespace MWGui else { setItem(MWWorld::Ptr()); + updateLabels(); } } @@ -216,6 +218,7 @@ namespace MWGui mItemSelectionDialog->setVisible(false); setItem(item); + MWBase::Environment::get().getSoundManager()->playSound(item.getClass().getDownSoundId(item), 1, 1); mEnchanting.nextCastStyle(); updateLabels(); } @@ -237,6 +240,7 @@ namespace MWGui } setSoulGem(item); + MWBase::Environment::get().getSoundManager()->playSound(item.getClass().getDownSoundId(item), 1, 1); updateLabels(); } diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/mygui/openmw_enchanting_dialog.layout index 2a3cb7c1db..def065b7a0 100644 --- a/files/mygui/openmw_enchanting_dialog.layout +++ b/files/mygui/openmw_enchanting_dialog.layout @@ -7,6 +7,9 @@ + + + @@ -25,6 +28,9 @@ + + + @@ -33,6 +39,9 @@ + + + @@ -70,6 +79,9 @@ + + + @@ -77,6 +89,9 @@ + + + @@ -89,6 +104,9 @@ + + + @@ -100,6 +118,9 @@ + + + From fc789265e2b6468406a4f005a700f4ec08360f4f Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 24 Aug 2014 20:36:31 +0200 Subject: [PATCH 3/7] Spells that always succeed should not increase your skill when you cast them --- apps/openmw/mwmechanics/spellcasting.cpp | 17 +++++++++++++++-- apps/openmw/mwmechanics/spellcasting.hpp | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 377455cac2..6563d0e629 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -151,6 +151,20 @@ namespace MWMechanics return school; } + bool spellIncreasesSkill(const ESM::Spell *spell) + { + if (spell->mData.mType == ESM::Spell::ST_Spell && !(spell->mData.mFlags & ESM::Spell::F_Always)) + return true; + return false; + } + + bool spellIncreasesSkill(const std::string &spellId) + { + const ESM::Spell* spell = + MWBase::Environment::get().getWorld()->getStore().get().find(spellId); + return spellIncreasesSkill(spell); + } + float getEffectResistanceAttribute (short effectId, const MagicEffects* actorEffects) { short resistanceEffect = ESM::MagicEffect::getResistanceEffect(effectId); @@ -775,7 +789,7 @@ namespace MWMechanics } } - if (mCaster.getRefData().getHandle() == "player" && spell->mData.mType == ESM::Spell::ST_Spell) + if (mCaster.getRefData().getHandle() == "player" && spellIncreasesSkill(spell)) mCaster.getClass().skillUsageSucceeded(mCaster, spellSchoolToSkill(school), 0); @@ -874,5 +888,4 @@ namespace MWMechanics return true; } - } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 9381b605ee..66e91d055d 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -36,6 +36,10 @@ namespace MWMechanics int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor); int getSpellSchool(const ESM::Spell* spell, const MWWorld::Ptr& actor); + /// Get whether or not the given spell contributes to skill progress. + bool spellIncreasesSkill(const ESM::Spell* spell); + bool spellIncreasesSkill(const std::string& spellId); + /// Get the resistance attribute against an effect for a given actor. This will add together /// ResistX and Weakness to X effects relevant against the given effect. float getEffectResistanceAttribute (short effectId, const MagicEffects* actorEffects); From df262e53aed4f01479957dcaeea5790f443ec90a Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 24 Aug 2014 20:51:41 +0200 Subject: [PATCH 4/7] Display school in the spell tooltip --- apps/openmw/mwgui/tooltips.cpp | 18 +++++++++--------- apps/openmw/mwgui/tooltips.hpp | 2 ++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 154d33d528..aaf4f10b57 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -11,6 +11,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" +#include "../mwmechanics/spellcasting.hpp" #include "mapwindow.hpp" #include "inventorywindow.hpp" @@ -19,6 +20,7 @@ namespace MWGui { + std::string ToolTips::sSchoolNames[] = {"#{sSchoolAlteration}", "#{sSchoolConjuration}", "#{sSchoolDestruction}", "#{sSchoolIllusion}", "#{sSchoolMysticism}", "#{sSchoolRestoration}"}; ToolTips::ToolTips() : Layout("openmw_tooltips.layout") @@ -220,6 +222,12 @@ namespace MWGui params.mNoTarget = false; effects.push_back(params); } + if (MWMechanics::spellIncreasesSkill(spell)) // display school of spells that contribute to skill progress + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int school = MWMechanics::getSpellSchool(spell, player); + info.text = "#{sSchool}: " + sSchoolNames[school]; + } info.effects = effects; tooltipSize = createToolTip(info); } @@ -739,19 +747,11 @@ namespace MWGui icon.insert(slashPos+1, "b_"); icon = Misc::ResourceHelpers::correctIconPath(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->mDescription); - widget->setUserString("Caption_MagicEffectSchool", "#{sSchool}: " + schools[effect->mData.mSchool]); + widget->setUserString("Caption_MagicEffectSchool", "#{sSchool}: " + sSchoolNames[effect->mData.mSchool]); widget->setUserString("ImageTexture_MagicEffectImage", icon); } diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 62ac693433..ffbb35e047 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -96,6 +96,8 @@ namespace MWGui /// Adjust position for a tooltip so that it doesn't leave the screen and does not obscure the mouse cursor void position(MyGUI::IntPoint& position, MyGUI::IntSize size, MyGUI::IntSize viewportSize); + static std::string sSchoolNames[6]; + int mHorizontalScrollIndex; From d16e0c063c38ac194fdf169eb9e020b0ff047be1 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 24 Aug 2014 21:59:52 +0200 Subject: [PATCH 5/7] Enchanting, spellmaking dialog: check for flags when listing known effects --- apps/openmw/mwgui/enchantingdialog.cpp | 2 +- apps/openmw/mwgui/spellcreationdialog.cpp | 12 ++++++++++-- apps/openmw/mwgui/spellcreationdialog.hpp | 11 ++++++++++- components/esm/loadmgef.hpp | 8 +++++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index d5098adbf1..30d67f5540 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -24,7 +24,7 @@ namespace MWGui EnchantingDialog::EnchantingDialog() : WindowBase("openmw_enchanting_dialog.layout") - , EffectEditorBase() + , EffectEditorBase(EffectEditorBase::Enchanting) , mItemSelectionDialog(NULL) { getWidget(mName, "NameEdit"); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index b72962125e..e6da3d692a 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -287,7 +287,7 @@ namespace MWGui SpellCreationDialog::SpellCreationDialog() : WindowBase("openmw_spellcreation_dialog.layout") - , EffectEditorBase() + , EffectEditorBase(EffectEditorBase::Spellmaking) { getWidget(mNameEdit, "NameEdit"); getWidget(mMagickaCost, "MagickaCost"); @@ -444,10 +444,11 @@ namespace MWGui // ------------------------------------------------------------------------------------------------ - EffectEditorBase::EffectEditorBase() + EffectEditorBase::EffectEditorBase(Type type) : mAddEffectDialog() , mSelectAttributeDialog(NULL) , mSelectSkillDialog(NULL) + , mType(type) { mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded); mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified); @@ -482,6 +483,13 @@ namespace MWGui const std::vector& list = spell->mEffects.mList; for (std::vector::const_iterator it2 = list.begin(); it2 != list.end(); ++it2) { + const ESM::MagicEffect * effect = MWBase::Environment::get().getWorld()->getStore().get().find(it2->mEffectID); + + // skip effects that do not allow spellmaking/enchanting + int requiredFlags = (mType == Spellmaking) ? ESM::MagicEffect::AllowSpellmaking : ESM::MagicEffect::AllowEnchanting; + if (!(effect->mData.mFlags & requiredFlags)) + continue; + if (std::find(knownEffects.begin(), knownEffects.end(), it2->mEffectID) == knownEffects.end()) knownEffects.push_back(it2->mEffectID); } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index f5d6f06161..be984c8d4d 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -85,7 +85,13 @@ namespace MWGui class EffectEditorBase { public: - EffectEditorBase(); + enum Type + { + Spellmaking, + Enchanting + }; + + EffectEditorBase(Type type); virtual ~EffectEditorBase(); protected: @@ -121,6 +127,9 @@ namespace MWGui void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); virtual void notifyEffectsChanged () {} + + private: + Type mType; }; class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 8281f4969d..64835530c1 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -16,6 +16,7 @@ struct MagicEffect enum Flags { + // Hardcoded flags 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. @@ -28,7 +29,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. + + // Moddable flags + AllowSpellmaking = 0x200, + AllowEnchanting = 0x400, + Negative = 0x800 // TODO: needs research }; enum MagnitudeDisplayType { From fc21d898f228e7ea596f4d6d7bd5a6b447132717 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Mon, 25 Aug 2014 03:15:28 +0200 Subject: [PATCH 6/7] Add hand-to-hand tooltip --- apps/openmw/mwgui/hud.cpp | 11 +++++++---- files/mygui/openmw_tooltips.layout | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 77b8c6ccbd..a541901ea6 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -471,6 +471,7 @@ namespace MWGui mWeaponSpellBox->setVisible(true); } + mWeapBox->clearUserStrings(); mWeapBox->setUserString("ToolTipType", "ItemPtr"); mWeapBox->setUserData(item); @@ -515,12 +516,14 @@ namespace MWGui MWWorld::Ptr player = world->getPlayerPtr(); mWeapImage->setItem(MWWorld::Ptr()); - if (player.getClass().getNpcStats(player).isWerewolf()) - mWeapImage->setIcon("icons\\k\\tx_werewolf_hand.dds"); - else - mWeapImage->setIcon("icons\\k\\stealth_handtohand.dds"); + std::string icon = (player.getClass().getNpcStats(player).isWerewolf()) ? "icons\\k\\tx_werewolf_hand.dds" : "icons\\k\\stealth_handtohand.dds"; + mWeapImage->setIcon(icon); mWeapBox->clearUserStrings(); + mWeapBox->setUserString("ToolTipType", "Layout"); + mWeapBox->setUserString("ToolTipLayout", "HandToHandToolTip"); + mWeapBox->setUserString("Caption_HandToHandText", itemName); + mWeapBox->setUserString("ImageTexture_HandToHandImage", icon); } void HUD::setCrosshairVisible(bool visible) diff --git a/files/mygui/openmw_tooltips.layout b/files/mygui/openmw_tooltips.layout index d761d90b7e..dca5ebc664 100644 --- a/files/mygui/openmw_tooltips.layout +++ b/files/mygui/openmw_tooltips.layout @@ -65,6 +65,24 @@ + + + + + + + + + + + + + + + + + + From 46e9ee408fe570c5c5d650c30e4edc048dbe7b49 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Mon, 25 Aug 2014 18:59:50 +0200 Subject: [PATCH 7/7] Do not allow mods to change fixed effect properties in the legacy format, but allow it entirely in the new format. --- components/esm/loadmgef.cpp | 9 +++++++-- components/esm/loadmgef.hpp | 11 ++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index f601915395..04d55c828a 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -42,8 +42,13 @@ void MagicEffect::load(ESMReader &esm) esm.getHNT(mIndex, "INDX"); esm.getHNT(mData, "MEDT", 36); - if (mIndex>=0 && mIndex=0 && mIndex