Merge remote-tracking branch 'scrawl/spellcreation'

actorid
Marc Zinnschlag 12 years ago
commit e05e683da3

@ -29,7 +29,8 @@ 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
enchantingdialog
)
add_openmw_dir (mwdialogue

@ -227,6 +227,9 @@ namespace MWBase
virtual bool getPlayerSleeping() = 0;
virtual void wakeUpPlayer() = 0;
virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0;
};
}

@ -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,18 @@ 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;
if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant;
win->setServices (windowServices);
// sort again, because the previous sort was case-sensitive
keywordList.sort(stringCompareNoCase);

@ -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<Widgets::MWSkillPtr>::const_iterator end = mSkills.end();
for (std::vector<Widgets::MWSkillPtr>::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();

@ -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

@ -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,16 @@ void DialogueWindow::onSelectTopic(std::string topic)
mWindowManager.pushGuiMode(GM_SpellBuying);
mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellMakingMenuTitle")->getString())
{
mWindowManager.pushGuiMode(GM_SpellCreation);
mWindowManager.startSpellMaking (mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString())
{
mWindowManager.pushGuiMode(GM_Enchanting);
mWindowManager.startEnchanting (mPtr);
}
else
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
}
@ -155,14 +167,20 @@ void DialogueWindow::setKeywords(std::list<std::string> 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.find("sBarter")->getString());
if (mShowSpells)
if (mServices & Service_BuySpells)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString());
if (mServices & Service_CreateSpells)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellmakingMenuTitle")->getString());
if (mServices & Service_Enchant)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString());
if (anyService)
mTopicsList->addSeparator();

@ -50,8 +50,15 @@ 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,
Service_Enchant = 0x08
};
protected:
void onSelectTopic(std::string topic);
@ -73,6 +80,8 @@ namespace MWGui
bool mShowTrade;
bool mShowSpells;
int mServices;
bool mEnabled;
DialogueHistory* mHistory;

@ -0,0 +1,43 @@
#include "enchantingdialog.hpp"
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);
}
void EnchantingDialog::open()
{
center();
}
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
{
mPtr = actor;
startEditing ();
}
void EnchantingDialog::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode (GM_Dialogue);
mWindowManager.removeGuiMode (GM_Enchanting);
}
void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{
mWindowManager.removeGuiMode (GM_Enchanting);
}
}

@ -0,0 +1,31 @@
#ifndef MWGUI_ENCHANTINGDIALOG_H
#define MWGUI_ENCHANTINGDIALOG_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include "spellcreationdialog.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui
{
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{
public:
EnchantingDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void startEnchanting(MWWorld::Ptr actor);
protected:
virtual void onReferenceUnavailable();
void onCancelButtonClicked(MyGUI::Widget* sender);
MyGUI::Button* mCancelButton;
};
}
#endif

@ -128,4 +128,10 @@ void MWList::onItemSelected(MyGUI::Widget* _sender)
std::string name = static_cast<MyGUI::Button*>(_sender)->getCaption();
eventItemSelected(name);
eventWidgetSelected(_sender);
}
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
{
return mScrollView->findWidget (getName() + "_item_" + name);
}

@ -18,6 +18,7 @@ namespace MWGui
MWList();
typedef MyGUI::delegates::CMultiDelegate1<std::string> EventHandle_String;
typedef MyGUI::delegates::CMultiDelegate1<MyGUI::Widget*> 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
*/
@ -38,6 +46,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();

@ -22,6 +22,8 @@ namespace MWGui
GM_Rest,
GM_RestBed,
GM_SpellBuying,
GM_SpellCreation,
GM_Enchanting,
GM_Levelup,

@ -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)
{
@ -88,7 +87,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();
@ -125,7 +124,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);
}

@ -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<MyGUI::Widget*, std::string> mSpellsWidgetMap;
void onCancelButtonClicked(MyGUI::Widget* _sender);

@ -0,0 +1,513 @@
#include "spellcreationdialog.hpp"
#include <boost/lexical_cast.hpp>
#include <components/esm_store/store.hpp>
#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"
#include "class.hpp"
namespace
{
bool sortMagicEffects (short id1, short id2)
{
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();
}
}
namespace MWGui
{
EditEffectDialog::EditEffectDialog(MWBase::WindowManager &parWindowManager)
: WindowModal("openmw_edit_effect.layout", parWindowManager)
, mEditing(false)
{
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");
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();
}
void EditEffectDialog::newEffect (const ESM::MagicEffect *effect)
{
setMagicEffect(effect);
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)
{
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effect.mEffectID);
setMagicEffect(magicEffect);
mEffect = effect;
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)
{
std::string icon = effect->mIcon;
icon[icon.size()-3] = 'd';
icon[icon.size()-2] = 'd';
icon[icon.size()-1] = 's';
icon = "icons\\" + icon;
mEffectImage->setImageTexture (icon);
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)
{
mEffect.mRange = (mEffect.mRange+1)%3;
if (mEffect.mRange == ESM::RT_Self)
mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}");
else if (mEffect.mRange == ESM::RT_Target)
mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}");
else if (mEffect.mRange == ESM::RT_Touch)
mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}");
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)
{
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)
{
setVisible(false);
}
void EditEffectDialog::setSkill (int skill)
{
mEffect.mSkill = skill;
}
void EditEffectDialog::setAttribute (int attribute)
{
mEffect.mAttribute = attribute;
}
void EditEffectDialog::onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mMagnitudeMinValue->setCaption(boost::lexical_cast<std::string>(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<std::string>(pos+1));
}
void EditEffectDialog::onDurationChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mDurationValue->setCaption(boost::lexical_cast<std::string>(pos+1));
mEffect.mDuration = pos+1;
}
void EditEffectDialog::onAreaChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mAreaValue->setCaption(boost::lexical_cast<std::string>(pos));
mEffect.mArea = pos;
}
// ------------------------------------------------------------------------------------------------
SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_spellcreation_dialog.layout", parWindowManager)
, EffectEditorBase(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);
setWidgets(mAvailableEffectsList, mUsedEffectsView);
}
void SpellCreationDialog::startSpellMaking (MWWorld::Ptr actor)
{
mPtr = actor;
startEditing();
}
void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender)
{
mWindowManager.removeGuiMode (MWGui::GM_SpellCreation);
}
void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender)
{
}
void SpellCreationDialog::open()
{
center();
}
void SpellCreationDialog::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode (GM_Dialogue);
mWindowManager.removeGuiMode (GM_SpellCreation);
}
// ------------------------------------------------------------------------------------------------
EffectEditorBase::EffectEditorBase(MWBase::WindowManager& parWindowManager)
: mAddEffectDialog(parWindowManager)
, mSelectAttributeDialog(NULL)
, mSelectSkillDialog(NULL)
{
mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded);
mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified);
mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &EffectEditorBase::onEffectRemoved);
mAddEffectDialog.setVisible (false);
}
void EffectEditorBase::startEditing ()
{
// get the list of magic effects that are known to the player
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::Spells& spells = stats.getSpells();
std::vector<short> 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->mData.mType != ESM::Spell::ST_Spell)
continue;
const std::vector<ESM::ENAMstruct>& list = spell->mEffects.mList;
for (std::vector<ESM::ENAMstruct>::const_iterator it2 = list.begin(); it2 != list.end(); ++it2)
{
if (std::find(knownEffects.begin(), knownEffects.end(), it2->mEffectID) == knownEffects.end())
knownEffects.push_back(it2->mEffectID);
}
}
std::sort(knownEffects.begin(), knownEffects.end(), sortMagicEffects);
mAvailableEffectsList->clear ();
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(
ESM::MagicEffect::effectIdToString (*it))->getString());
}
mAvailableEffectsList->adjustSize ();
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{
std::string name = MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(
ESM::MagicEffect::effectIdToString (*it))->getString();
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
w->setUserData(*it);
ToolTips::createMagicEffectToolTip (w, *it);
}
}
void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView)
{
mAvailableEffectsList = availableEffectsList;
mUsedEffectsView = usedEffectsView;
mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked);
}
void EffectEditorBase::onSelectAttribute ()
{
mAddEffectDialog.setVisible(true);
mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId());
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog);
mSelectAttributeDialog = 0;
}
void EffectEditorBase::onSelectSkill ()
{
mAddEffectDialog.setVisible(true);
mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId ());
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog);
mSelectSkillDialog = 0;
}
void EffectEditorBase::onAttributeOrSkillCancel ()
{
if (mSelectSkillDialog)
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog);
if (mSelectAttributeDialog)
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog);
mSelectSkillDialog = 0;
mSelectAttributeDialog = 0;
}
void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender)
{
short effectId = *sender->getUserData<short>();
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId);
mAddEffectDialog.newEffect (effect);
if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill)
{
delete mSelectSkillDialog;
mSelectSkillDialog = new SelectSkillDialog(*MWBase::Environment::get().getWindowManager ());
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(*MWBase::Environment::get().getWindowManager ());
mSelectAttributeDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel);
mSelectAttributeDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute);
mSelectAttributeDialog->setVisible (true);
}
else
{
mAddEffectDialog.setVisible(true);
}
}
void EffectEditorBase::onEffectModified (ESM::ENAMstruct effect)
{
mEffects[mSelectedEffect] = effect;
updateEffectsView();
}
void EffectEditorBase::onEffectRemoved (ESM::ENAMstruct effect)
{
mEffects.erase(mEffects.begin() + mSelectedEffect);
updateEffectsView();
}
void EffectEditorBase::updateEffectsView ()
{
MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator ();
MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets);
MyGUI::IntSize size(0,0);
int i = 0;
for (std::vector<ESM::ENAMstruct>::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;
params.mArea = it->mArea;
MyGUI::Button* button = mUsedEffectsView->createWidget<MyGUI::Button>("", 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<Widgets::MWSpellEffect>("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default);
effect->setNeedMouseFocus (false);
effect->setWindowManager (MWBase::Environment::get().getWindowManager ());
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 EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect)
{
mEffects.push_back(effect);
updateEffectsView();
}
void EffectEditorBase::onEditEffect (MyGUI::Widget *sender)
{
int id = *sender->getUserData<int>();
mSelectedEffect = id;
mAddEffectDialog.editEffect (mEffects[id]);
mAddEffectDialog.setVisible (true);
}
}

@ -0,0 +1,150 @@
#ifndef MWGUI_SPELLCREATION_H
#define MWGUI_SPELLCREATION_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include "list.hpp"
#include "widgets.hpp"
namespace MWGui
{
class SelectSkillDialog;
class SelectAttributeDialog;
class EditEffectDialog : public WindowModal
{
public:
EditEffectDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void setSkill(int skill);
void setAttribute(int attribute);
void newEffect (const ESM::MagicEffect* effect);
void editEffect (ESM::ENAMstruct effect);
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
EventHandle_Effect eventEffectAdded;
EventHandle_Effect eventEffectModified;
EventHandle_Effect eventEffectRemoved;
protected:
MyGUI::Button* mCancelButton;
MyGUI::Button* mOkButton;
MyGUI::Button* mDeleteButton;
MyGUI::Button* mRangeButton;
MyGUI::Widget* mDurationBox;
MyGUI::Widget* mMagnitudeBox;
MyGUI::Widget* mAreaBox;
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::TextBox* mAreaText;
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 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;
};
class EffectEditorBase
{
public:
EffectEditorBase(MWBase::WindowManager& parWindowManager);
protected:
Widgets::MWList* mAvailableEffectsList;
MyGUI::ScrollView* mUsedEffectsView;
EditEffectDialog mAddEffectDialog;
SelectAttributeDialog* mSelectAttributeDialog;
SelectSkillDialog* mSelectSkillDialog;
int mSelectedEffect;
std::vector<ESM::ENAMstruct> mEffects;
void onEffectAdded(ESM::ENAMstruct effect);
void onEffectModified(ESM::ENAMstruct effect);
void onEffectRemoved(ESM::ENAMstruct effect);
void onAvailableEffectClicked (MyGUI::Widget* sender);
void onAttributeOrSkillCancel();
void onSelectAttribute();
void onSelectSkill();
void onEditEffect(MyGUI::Widget* sender);
void updateEffectsView();
void startEditing();
void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView);
};
class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{
public:
SpellCreationDialog(MWBase::WindowManager& parWindowManager);
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;
MyGUI::Button* mBuyButton;
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPriceLabel;
Widgets::MWEffectList* mUsedEffectsList;
};
}
#endif

@ -588,8 +588,6 @@ void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
widget->setUserString("Caption_SkillNoProgressDescription", skill->mDescription);
widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}");
widget->setUserString("ImageTexture_SkillNoProgressImage", icon);
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
}
void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
@ -715,6 +713,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 = ESM::MagicEffect::effectIdToString (id);
std::string icon = effect->mIcon;
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<std::string> 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("ImageTexture_MagicEffectImage", icon);
}
void ToolTips::setDelay(float delay)
{
mDelay = delay;

@ -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;

@ -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;
@ -385,343 +386,82 @@ 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)
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
{
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 = effectIDToString(mEffectParams.mEffectID);
std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, "");
if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length)
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
else
{
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], "");
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
}
if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8)
}
// constant effects have no duration and no target
if (!mEffectParams.mIsConstant)
{
if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs);
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr))
if (mEffectParams.mArea > 0)
{
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
else
{
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
}
spellLine += " #{sin} " + boost::lexical_cast<std::string>(mEffectParams.mArea) + " #{sfootarea}";
}
// constant effects have no duration and no target
if (!mEffectParams.mIsConstant)
// potions have no target
if (!mEffectParams.mNoTarget)
{
if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr))
{
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(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<MyGUI::TextBox*>(mTextWidget)->setCaption(spellLine);
mRequestedWidth = mTextWidget->getTextSize().width + 24;
}
if (mImageWidget)
{
std::string path = std::string("icons\\") + magicEffect->mIcon;
fixTexturePath(path);
mImageWidget->setImageTexture(path);
}
}
std::string MWSpellEffect::effectIDToString(const short effectID)
{
// Map effect ID to GMST name
// http://www.uesp.net/morrow/hints/mweffects.shtml
std::map<short, std::string> 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<std::string> 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<std::string> 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");
}
static_cast<MyGUI::TextBox*>(mTextWidget)->setCaptionWithReplacing(spellLine);
mRequestedWidth = mTextWidget->getTextSize().width + 24;
bool MWSpellEffect::effectInvolvesSkill (const std::string& effect)
{
return (effect == "sEffectRestoreSkill"
|| effect == "sEffectAbsorbSkill"
|| effect == "sEffectDrainSkill"
|| effect == "sEffectFortifySkill"
|| effect == "sEffectDamageSkill");
std::string path = std::string("icons\\") + magicEffect->mIcon;
fixTexturePath(path);
mImageWidget->setImageTexture(path);
}
MWSpellEffect::~MWSpellEffect()

@ -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);
}
};
@ -249,12 +253,6 @@ namespace MWGui
void setWindowManager(MWBase::WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
void setSpellEffect(const SpellEffectParams& params);
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);
int getRequestedWidth() const { return mRequestedWidth; }
protected:

@ -46,6 +46,8 @@
#include "loadingscreen.hpp"
#include "levelupdialog.hpp"
#include "waitdialog.hpp"
#include "spellcreationdialog.hpp"
#include "enchantingdialog.hpp"
using namespace MWGui;
@ -75,6 +77,8 @@ WindowManager::WindowManager(
, mCharGen(NULL)
, mLevelupDialog(NULL)
, mWaitDialog(NULL)
, mSpellCreationDialog(NULL)
, mEnchantingDialog(NULL)
, mPlayerClass()
, mPlayerName()
, mPlayerRaceId()
@ -155,6 +159,8 @@ WindowManager::WindowManager(
mQuickKeysMenu = new QuickKeysMenu(*this);
mLevelupDialog = new LevelupDialog(*this);
mWaitDialog = new WaitDialog(*this);
mSpellCreationDialog = new SpellCreationDialog(*this);
mEnchantingDialog = new EnchantingDialog(*this);
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this);
mLoadingScreen->onResChange (w,h);
@ -210,6 +216,8 @@ WindowManager::~WindowManager()
delete mLoadingScreen;
delete mLevelupDialog;
delete mWaitDialog;
delete mSpellCreationDialog;
delete mEnchantingDialog;
cleanupGarbage();
@ -259,6 +267,8 @@ void WindowManager::updateVisible()
mQuickKeysMenu->setVisible(false);
mLevelupDialog->setVisible(false);
mWaitDialog->setVisible(false);
mSpellCreationDialog->setVisible(false);
mEnchantingDialog->setVisible(false);
mHud->setVisible(true);
@ -359,6 +369,12 @@ void WindowManager::updateVisible()
case GM_SpellBuying:
mSpellBuyingWindow->setVisible(true);
break;
case GM_SpellCreation:
mSpellCreationDialog->setVisible(true);
break;
case GM_Enchanting:
mEnchantingDialog->setVisible(true);
break;
case GM_InterMessageBox:
break;
case GM_Journal:
@ -561,6 +577,8 @@ void WindowManager::onFrame (float frameDuration)
mDialogueWindow->checkReferenceAvailable();
mTradeWindow->checkReferenceAvailable();
mSpellBuyingWindow->checkReferenceAvailable();
mSpellCreationDialog->checkReferenceAvailable();
mEnchantingDialog->checkReferenceAvailable();
mContainerWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable();
}
@ -965,3 +983,13 @@ 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);
}
void WindowManager::startEnchanting (MWWorld::Ptr actor)
{
mEnchantingDialog->startEnchanting (actor);
}

@ -64,6 +64,8 @@ namespace MWGui
class LoadingScreen;
class LevelupDialog;
class WaitDialog;
class SpellCreationDialog;
class EnchantingDialog;
class WindowManager : public MWBase::WindowManager
{
@ -211,6 +213,9 @@ namespace MWGui
virtual bool getPlayerSleeping();
virtual void wakeUpPlayer();
virtual void startSpellMaking(MWWorld::Ptr actor);
virtual void startEnchanting(MWWorld::Ptr actor);
private:
OEngine::GUI::MyGUIManager *mGuiManager;
HUD *mHud;
@ -238,6 +243,8 @@ namespace MWGui
LoadingScreen* mLoadingScreen;
LevelupDialog* mLevelupDialog;
WaitDialog* mWaitDialog;
SpellCreationDialog* mSpellCreationDialog;
EnchantingDialog* mEnchantingDialog;
CharacterCreation* mCharGen;

@ -180,6 +180,8 @@ RenderingManager::~RenderingManager ()
delete mOcclusionQuery;
delete mCompositors;
delete mWater;
delete mFactory;
}
MWRender::SkyManager* RenderingManager::getSkyManager()

@ -1,5 +1,7 @@
#include "loadmgef.hpp"
#include <boost/lexical_cast.hpp>
#include "esmreader.hpp"
#include "esmwriter.hpp"
@ -79,4 +81,162 @@ 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<short, std::string> 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";
if (names.find(effectID) == names.end())
throw std::runtime_error( std::string("Unimplemented effect ID ") + boost::lexical_cast<std::string>(effectID));
return names[effectID];
}
}

@ -13,11 +13,24 @@ struct MagicEffect
{
enum Flags
{
NoDuration = 0x4,
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.
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.
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.
SpellMaking = 0x0200,
Enchanting = 0x0400,
Negative = 0x0800 // A harmful effect. Will determine whether
// eg. NPCs regard this spell as an attack.
// eg. NPCs regard this spell as an attack. (same as 0x10?)
};
struct MEDTstruct
@ -30,6 +43,9 @@ struct MagicEffect
float mSpeed, mSize, mSizeCap;
}; // 36 bytes
static std::string effectIdToString(short effectID);
MEDTstruct mData;
std::string mIcon, mParticle; // Textures

@ -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

@ -1,6 +1,5 @@
configuration water_reflection
{
fog false
shadows false
shadows_pssm false
mrt_output false

@ -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

@ -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);
}

@ -75,6 +75,9 @@ set(MYGUI_FILES
openmw_levelup_dialog.layout
openmw_wait_dialog.layout
openmw_wait_dialog_progressbar.layout
openmw_spellcreation_dialog.layout
openmw_edit_effect.layout
openmw_enchanting_dialog.layout
smallbars.png
VeraMono.ttf
markers.png

@ -3,7 +3,7 @@
<MyGUI type="List">
<List file="core.skin" />
<List file="openmw_resources.xml" />
<List file="openmw.font.xml" />
<List file="openmw_font.xml"/>
<List file="openmw_text.skin.xml" />
<List file="openmw_windows.skin.xml" />
<List file="openmw_button.skin.xml" />

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 362 310" name="_Main">
<Widget type="ImageBox" skin="ImageBox" position="8 12 16 16" name="EffectImage">
</Widget>
<Widget type="TextBox" skin="NormalText" position="36 8 400 24" name="EffectName">
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<!-- Range -->
<Widget type="TextBox" skin="NormalText" position="8 36 400 24">
<Property key="Caption" value="#{sRange}"/>
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="130 36 0 24" name="RangeButton">
<Property key="Caption" value="#{sRangeTouch}"/>
</Widget>
<!-- Magnitude -->
<Widget type="Widget" position="8 80 400 70" name="MagnitudeBox">
<Widget type="TextBox" skin="NormalText" position="0 0 400 24">
<Property key="Caption" value="#{sMagnitude}"/>
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="MagnitudeMinValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="MagnitudeMinSlider">
<Property key="Range" value="100"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 32 210 20" name="MagnitudeMaxValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 52 210 13" name="MagnitudeMaxSlider">
<Property key="Range" value="100"/>
</Widget>
</Widget>
<!-- Duration -->
<Widget type="Widget" position="8 153 400 40" name="DurationBox">
<Widget type="TextBox" skin="NormalText" position="0 20 400 24">
<Property key="Caption" value="#{sDuration}"/>
<Property key="TextAlign" value="Left Top"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="DurationValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="DurationSlider">
<Property key="Range" value="1440"/>
</Widget>
</Widget>
<!-- Area -->
<Widget type="Widget" position="8 197 400 40" name="AreaBox">
<Widget type="TextBox" skin="NormalText" position="0 20 400 24" name="AreaText">
<Property key="Caption" value="#{sArea}"/>
<Property key="TextAlign" value="Left Top"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="AreaValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="AreaSlider">
<Property key="Range" value="51"/>
</Widget>
</Widget>
<Widget type="HBox" position="8 266 336 24">
<Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="DeleteButton">
<Property key="Caption" value="#{sDelete}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="OkButton">
<Property key="Caption" value="#{sOk}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 560 400" name="_Main">
<Widget type="HBox" position="12 12 250 30">
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sName}"/>
</Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="0 0 30 30" name="NameEdit">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="Widget">
</Widget>
</Widget>
<!-- Item -->
<Widget type="HBox" position="12 48 400 59">
<Property key="Spacing" value="8"/>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sItem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="ItemBox"/>
<Widget type="Widget" position="0 0 8 0"/>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sSoulGem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="SoulBox"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 0 300 24">
<Property key="Caption" value="#{sEnchantmentMenu3}:"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 0 258 24" name="Enchantment">
<Property key="Caption" value="1"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 24 300 24">
<Property key="Caption" value="#{sCastCost}:"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 24 258 24" name="CastCost">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 48 300 24">
<Property key="Caption" value="#{sCharges}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 48 258 24" name="Charge">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<!-- Available effects -->
<Widget type="TextBox" skin="NormalText" position="12 148 300 24">
<Property key="Caption" value="#{sMagicEffects}"/>
</Widget>
<Widget type="MWList" skin="MW_SimpleList" position="12 176 202 169" name="AvailableEffects">
</Widget>
<!-- Used effects -->
<Widget type="TextBox" skin="NormalText" position="226 148 300 24">
<Property key="Caption" value="#{sEffects}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="226 176 316 169">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 161" name="UsedEffects">
<Property key="CanvasAlign" value="Left Top"/>
</Widget>
</Widget>
<Widget type="HBox" position="0 340 560 60">
<Property key="Padding" value="16"/>
<Widget type="Widget" position="0 0 0 0">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sBarterDialog7}"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="PriceLabel">
<Property key="Caption" value="30"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BuyButton">
<Property key="Caption" value="#{sBuy}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 560 400" name="_Main">
<Widget type="HBox" position="12 12 250 30">
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sName}"/>
</Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="0 0 30 30" name="NameEdit">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="Widget">
</Widget>
</Widget>
<Widget type="TextBox" skin="NormalText" position="280 0 300 24">
<Property key="Caption" value="#{sEnchantmentMenu4}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 0 258 24" name="MagickaCost">
<Property key="Caption" value="1"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="280 24 300 24">
<Property key="Caption" value="#{sSpellmakingMenu1}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 24 258 24" name="SuccessChance">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<!-- Available effects -->
<Widget type="TextBox" skin="NormalText" position="12 48 300 24">
<Property key="Caption" value="#{sMagicEffects}"/>
</Widget>
<Widget type="MWList" skin="MW_SimpleList" position="12 76 202 269" name="AvailableEffects">
</Widget>
<!-- Used effects -->
<Widget type="TextBox" skin="NormalText" position="226 48 300 24">
<Property key="Caption" value="#{sEffects}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="226 76 316 269">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 261" name="UsedEffects">
<Property key="CanvasAlign" value="Left Top"/>
</Widget>
</Widget>
<Widget type="HBox" position="0 340 560 60">
<Property key="Padding" value="16"/>
<Widget type="Widget" position="0 0 0 0">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sBarterDialog7}"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="PriceLabel">
<Property key="Caption" value="30"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BuyButton">
<Property key="Caption" value="#{sBuy}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -196,6 +196,31 @@
</Widget>
</Widget>
<!-- Magic effect tooltip -->
<Widget type="Widget" skin="HUD_Box_NoTransp" position="0 0 300 52" align="Stretch" name="MagicEffectToolTip">
<Property key="Visible" value="false"/>
<Widget type="ImageBox" skin="ImageBox" position="8 8 32 32" align="Left Top" name="MagicEffectImage"/>
<Widget type="TextBox" skin="NormalText" position="44 8 252 16" align="Left Top HStretch" name="MagicEffectName">
<Property key="TextAlign" value="Left"/>
<UserString key="AutoResizeHorizontal" value="true"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="44 24 252 16" align="Left Top HStretch" name="MagicEffectSchool">
<Property key="TextAlign" value="Left"/>
<UserString key="AutoResizeHorizontal" value="true"/>
</Widget>
<Widget type="EditBox" skin="SandText" position="8 44 284 0" align="Left Top Stretch" name="MagicEffectDescription">
<Property key="MultiLine" value="true"/>
<Property key="WordWrap" value="true"/>
<Property key="TextAlign" value="Left Top"/>
<UserString key="AutoResizeHorizontal" value="true"/>
<UserString key="AutoResizeVertical" value="true"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

Loading…
Cancel
Save