2012-09-23 00:36:20 +02:00
|
|
|
#include "spellcreationdialog.hpp"
|
|
|
|
|
2022-06-04 15:26:36 +02:00
|
|
|
#include <MyGUI_Button.h>
|
2015-01-10 02:50:43 +01:00
|
|
|
#include <MyGUI_Gui.h>
|
|
|
|
#include <MyGUI_ImageBox.h>
|
2022-06-04 15:26:36 +02:00
|
|
|
#include <MyGUI_ScrollBar.h>
|
2015-01-10 02:50:43 +01:00
|
|
|
|
2022-06-29 00:32:11 +02:00
|
|
|
#include <components/misc/resourcehelpers.hpp>
|
|
|
|
#include <components/resource/resourcesystem.hpp>
|
2015-01-10 03:56:06 +01:00
|
|
|
#include <components/widgets/list.hpp>
|
2014-08-12 12:18:38 +02:00
|
|
|
|
2022-09-05 19:35:15 +02:00
|
|
|
#include <components/esm3/loadgmst.hpp>
|
|
|
|
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "../mwbase/environment.hpp"
|
2012-11-05 19:53:55 +01:00
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
2012-09-23 00:36:20 +02:00
|
|
|
#include "../mwbase/windowmanager.hpp"
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "../mwbase/world.hpp"
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2014-01-18 10:52:16 +01:00
|
|
|
#include "../mwworld/class.hpp"
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "../mwworld/containerstore.hpp"
|
|
|
|
#include "../mwworld/esmstore.hpp"
|
|
|
|
#include "../mwworld/store.hpp"
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
2022-07-16 16:37:31 +02:00
|
|
|
#include "../mwmechanics/creaturestats.hpp"
|
2020-04-26 20:46:51 +03:00
|
|
|
#include "../mwmechanics/spellutil.hpp"
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
#include "class.hpp"
|
2012-09-23 00:36:20 +02:00
|
|
|
#include "tooltips.hpp"
|
2015-01-10 03:56:06 +01:00
|
|
|
#include "widgets.hpp"
|
2012-09-23 00:36:20 +02:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
bool sortMagicEffects(short id1, short id2)
|
|
|
|
{
|
2012-11-05 23:41:26 +04:00
|
|
|
const MWWorld::Store<ESM::GameSetting>& gmst
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
|
|
|
2018-08-29 18:38:12 +03:00
|
|
|
return gmst.find(ESM::MagicEffect::effectIdToString(id1))->mValue.getString()
|
|
|
|
< gmst.find(ESM::MagicEffect::effectIdToString(id2))->mValue.getString();
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
2015-01-12 20:25:25 +01:00
|
|
|
|
|
|
|
void init(ESM::ENAMstruct& effect)
|
|
|
|
{
|
|
|
|
effect.mArea = 0;
|
|
|
|
effect.mDuration = 0;
|
|
|
|
effect.mEffectID = -1;
|
|
|
|
effect.mMagnMax = 0;
|
|
|
|
effect.mMagnMin = 0;
|
|
|
|
effect.mRange = 0;
|
|
|
|
effect.mSkill = -1;
|
|
|
|
effect.mAttribute = -1;
|
|
|
|
}
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace MWGui
|
|
|
|
{
|
|
|
|
|
2013-04-10 14:46:21 -04:00
|
|
|
EditEffectDialog::EditEffectDialog()
|
|
|
|
: WindowModal("openmw_edit_effect.layout")
|
2012-10-03 15:06:54 +02:00
|
|
|
, mEditing(false)
|
2018-10-09 10:21:12 +04:00
|
|
|
, mMagicEffect(nullptr)
|
2015-01-05 05:33:51 +01:00
|
|
|
, mConstantEffect(false)
|
2012-09-24 08:09:16 +02:00
|
|
|
{
|
2015-01-12 20:25:25 +01:00
|
|
|
init(mEffect);
|
|
|
|
init(mOldEffect);
|
|
|
|
|
2012-09-24 08:09:16 +02:00
|
|
|
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");
|
2012-10-11 18:26:29 +02:00
|
|
|
getWidget(mDurationBox, "DurationBox");
|
|
|
|
getWidget(mAreaBox, "AreaBox");
|
|
|
|
getWidget(mMagnitudeBox, "MagnitudeBox");
|
2012-09-24 08:09:16 +02:00
|
|
|
|
|
|
|
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);
|
2012-10-11 18:26:29 +02:00
|
|
|
|
|
|
|
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);
|
2015-01-05 05:33:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::setConstantEffect(bool constant)
|
|
|
|
{
|
|
|
|
mConstantEffect = constant;
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
2017-09-22 17:10:53 +02:00
|
|
|
void EditEffectDialog::onOpen()
|
2012-09-24 08:09:16 +02:00
|
|
|
{
|
2017-09-22 17:10:53 +02:00
|
|
|
WindowModal::onOpen();
|
2012-09-24 08:09:16 +02:00
|
|
|
center();
|
|
|
|
}
|
|
|
|
|
2017-09-23 12:18:39 +02:00
|
|
|
bool EditEffectDialog::exit()
|
2014-05-27 03:00:31 -04:00
|
|
|
{
|
|
|
|
if (mEditing)
|
|
|
|
eventEffectModified(mOldEffect);
|
|
|
|
else
|
|
|
|
eventEffectRemoved(mEffect);
|
2017-09-23 12:18:39 +02:00
|
|
|
return true;
|
2014-05-27 03:00:31 -04:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
void EditEffectDialog::newEffect(const ESM::MagicEffect* effect)
|
|
|
|
{
|
2015-03-06 23:19:57 +13:00
|
|
|
bool allowSelf = (effect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0;
|
2015-01-05 05:33:51 +01:00
|
|
|
bool allowTouch = (effect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect;
|
2014-12-10 17:48:49 +01:00
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
setMagicEffect(effect);
|
|
|
|
mEditing = false;
|
|
|
|
|
|
|
|
mDeleteButton->setVisible(false);
|
2012-10-11 18:26:29 +02:00
|
|
|
|
|
|
|
mEffect.mRange = ESM::RT_Self;
|
2014-12-10 17:48:49 +01:00
|
|
|
if (!allowSelf)
|
2013-07-31 13:33:30 +02:00
|
|
|
mEffect.mRange = ESM::RT_Touch;
|
2014-12-10 17:48:49 +01:00
|
|
|
if (!allowTouch)
|
2013-07-31 13:33:30 +02:00
|
|
|
mEffect.mRange = ESM::RT_Target;
|
|
|
|
mEffect.mMagnMin = 1;
|
|
|
|
mEffect.mMagnMax = 1;
|
|
|
|
mEffect.mDuration = 1;
|
|
|
|
mEffect.mArea = 0;
|
2013-11-16 01:19:39 +01:00
|
|
|
mEffect.mSkill = -1;
|
|
|
|
mEffect.mAttribute = -1;
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectAdded(mEffect);
|
2012-10-11 18:26:29 +02:00
|
|
|
|
|
|
|
onRangeButtonClicked(mRangeButton);
|
|
|
|
|
|
|
|
mMagnitudeMinSlider->setScrollPosition(0);
|
|
|
|
mMagnitudeMaxSlider->setScrollPosition(0);
|
|
|
|
mAreaSlider->setScrollPosition(0);
|
|
|
|
mDurationSlider->setScrollPosition(0);
|
|
|
|
|
|
|
|
mDurationValue->setCaption("1");
|
|
|
|
mMagnitudeMinValue->setCaption("1");
|
2022-08-24 22:16:03 +02:00
|
|
|
const std::string to{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-") };
|
2018-09-09 13:56:58 +03:00
|
|
|
|
|
|
|
mMagnitudeMaxValue->setCaption(to + " 1");
|
2012-10-11 18:26:29 +02:00
|
|
|
mAreaValue->setCaption("0");
|
2014-12-10 17:48:49 +01:00
|
|
|
|
|
|
|
setVisible(true);
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::editEffect(ESM::ENAMstruct effect)
|
|
|
|
{
|
2012-11-05 23:41:26 +04:00
|
|
|
const ESM::MagicEffect* magicEffect
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
2012-10-03 15:06:54 +02:00
|
|
|
|
|
|
|
setMagicEffect(magicEffect);
|
2013-07-31 13:33:30 +02:00
|
|
|
mOldEffect = effect;
|
2012-10-03 15:06:54 +02:00
|
|
|
mEffect = effect;
|
|
|
|
mEditing = true;
|
|
|
|
|
|
|
|
mDeleteButton->setVisible(true);
|
2012-10-11 18:26:29 +02:00
|
|
|
|
|
|
|
mMagnitudeMinSlider->setScrollPosition(effect.mMagnMin - 1);
|
|
|
|
mMagnitudeMaxSlider->setScrollPosition(effect.mMagnMax - 1);
|
|
|
|
mAreaSlider->setScrollPosition(effect.mArea);
|
|
|
|
mDurationSlider->setScrollPosition(effect.mDuration - 1);
|
|
|
|
|
2017-07-15 14:03:36 +04:00
|
|
|
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}");
|
|
|
|
|
2012-10-11 18:26:29 +02:00
|
|
|
onMagnitudeMinChanged(mMagnitudeMinSlider, effect.mMagnMin - 1);
|
|
|
|
onMagnitudeMaxChanged(mMagnitudeMinSlider, effect.mMagnMax - 1);
|
|
|
|
onAreaChanged(mAreaSlider, effect.mArea);
|
|
|
|
onDurationChanged(mDurationSlider, effect.mDuration - 1);
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2017-07-15 14:03:36 +04:00
|
|
|
|
|
|
|
updateBoxes();
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::setMagicEffect(const ESM::MagicEffect* effect)
|
2012-09-24 08:09:16 +02:00
|
|
|
{
|
2022-06-29 00:32:11 +02:00
|
|
|
mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath(
|
|
|
|
effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS()));
|
2012-09-24 08:09:16 +02:00
|
|
|
|
2012-10-01 23:33:07 +02:00
|
|
|
mEffectName->setCaptionWithReplacing("#{" + ESM::MagicEffect::effectIdToString(effect->mIndex) + "}");
|
2012-10-03 15:06:54 +02:00
|
|
|
|
|
|
|
mEffect.mEffectID = effect->mIndex;
|
2012-10-11 18:26:29 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-01-05 05:33:51 +01:00
|
|
|
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) && mConstantEffect == false)
|
2012-10-11 18:26:29 +02:00
|
|
|
{
|
|
|
|
mDurationBox->setPosition(mDurationBox->getPosition().left, curY);
|
|
|
|
mDurationBox->setVisible(true);
|
|
|
|
curY += mDurationBox->getSize().height;
|
|
|
|
}
|
2013-07-31 12:26:34 +02:00
|
|
|
if (mEffect.mRange != ESM::RT_Self)
|
2012-10-11 18:26:29 +02:00
|
|
|
{
|
|
|
|
mAreaBox->setPosition(mAreaBox->getPosition().left, curY);
|
|
|
|
mAreaBox->setVisible(true);
|
2014-09-26 17:12:48 +02:00
|
|
|
// curY += mAreaBox->getSize().height;
|
2012-10-11 18:26:29 +02:00
|
|
|
}
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onRangeButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
2012-10-01 17:54:45 +02:00
|
|
|
mEffect.mRange = (mEffect.mRange + 1) % 3;
|
2012-09-24 08:09:16 +02:00
|
|
|
|
2012-10-11 18:26:29 +02:00
|
|
|
// cycle through range types until we find something that's allowed
|
2014-12-10 17:48:49 +01:00
|
|
|
// does not handle the case where nothing is allowed (this should be prevented before opening the Add Effect
|
|
|
|
// dialog)
|
2015-03-06 23:19:57 +13:00
|
|
|
bool allowSelf = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0;
|
2015-01-05 05:33:51 +01:00
|
|
|
bool allowTouch = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect;
|
|
|
|
bool allowTarget = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTarget) && !mConstantEffect;
|
2014-12-10 17:48:49 +01:00
|
|
|
if (mEffect.mRange == ESM::RT_Self && !allowSelf)
|
|
|
|
mEffect.mRange = (mEffect.mRange + 1) % 3;
|
|
|
|
if (mEffect.mRange == ESM::RT_Touch && !allowTouch)
|
|
|
|
mEffect.mRange = (mEffect.mRange + 1) % 3;
|
|
|
|
if (mEffect.mRange == ESM::RT_Target && !allowTarget)
|
|
|
|
mEffect.mRange = (mEffect.mRange + 1) % 3;
|
2012-10-11 18:26:29 +02:00
|
|
|
|
2013-07-31 12:26:34 +02:00
|
|
|
if (mEffect.mRange == ESM::RT_Self)
|
|
|
|
{
|
|
|
|
mAreaSlider->setScrollPosition(0);
|
|
|
|
onAreaChanged(mAreaSlider, 0);
|
|
|
|
}
|
2014-12-10 17:48:49 +01:00
|
|
|
|
|
|
|
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}");
|
|
|
|
|
2012-10-11 18:26:29 +02:00
|
|
|
updateBoxes();
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onDeleteButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
2012-10-03 15:06:54 +02:00
|
|
|
setVisible(false);
|
2012-09-24 08:09:16 +02:00
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
eventEffectRemoved(mEffect);
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onOkButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
|
|
|
setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onCancelButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
2017-09-23 12:18:39 +02:00
|
|
|
setVisible(false);
|
2014-05-27 03:00:31 -04:00
|
|
|
exit();
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
void EditEffectDialog::setSkill(int skill)
|
|
|
|
{
|
|
|
|
mEffect.mSkill = skill;
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::setAttribute(int attribute)
|
|
|
|
{
|
|
|
|
mEffect.mAttribute = attribute;
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 18:26:29 +02:00
|
|
|
void EditEffectDialog::onMagnitudeMinChanged(MyGUI::ScrollBar* sender, size_t pos)
|
|
|
|
{
|
2015-01-10 03:01:01 +01:00
|
|
|
mMagnitudeMinValue->setCaption(MyGUI::utility::toString(pos + 1));
|
2012-10-11 18:26:29 +02:00
|
|
|
mEffect.mMagnMin = pos + 1;
|
|
|
|
|
|
|
|
// trigger the check again (see below)
|
|
|
|
onMagnitudeMaxChanged(mMagnitudeMaxSlider, mMagnitudeMaxSlider->getScrollPosition());
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-10-11 18:26:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2022-08-24 22:16:03 +02:00
|
|
|
const std::string to{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-") };
|
2012-10-11 18:26:29 +02:00
|
|
|
|
2018-09-09 13:56:58 +03:00
|
|
|
mMagnitudeMaxValue->setCaption(to + " " + MyGUI::utility::toString(pos + 1));
|
2013-07-31 13:33:30 +02:00
|
|
|
|
|
|
|
eventEffectModified(mEffect);
|
2012-10-11 18:26:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onDurationChanged(MyGUI::ScrollBar* sender, size_t pos)
|
|
|
|
{
|
2015-01-10 03:01:01 +01:00
|
|
|
mDurationValue->setCaption(MyGUI::utility::toString(pos + 1));
|
2012-10-11 18:26:29 +02:00
|
|
|
mEffect.mDuration = pos + 1;
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-10-11 18:26:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditEffectDialog::onAreaChanged(MyGUI::ScrollBar* sender, size_t pos)
|
|
|
|
{
|
2015-01-10 03:01:01 +01:00
|
|
|
mAreaValue->setCaption(MyGUI::utility::toString(pos));
|
2012-10-11 18:26:29 +02:00
|
|
|
mEffect.mArea = pos;
|
2013-07-31 13:33:30 +02:00
|
|
|
eventEffectModified(mEffect);
|
2012-10-11 18:26:29 +02:00
|
|
|
}
|
|
|
|
|
2012-09-24 08:09:16 +02:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
|
2013-04-10 14:46:21 -04:00
|
|
|
SpellCreationDialog::SpellCreationDialog()
|
|
|
|
: WindowBase("openmw_spellcreation_dialog.layout")
|
2014-08-24 21:59:52 +02:00
|
|
|
, EffectEditorBase(EffectEditorBase::Spellmaking)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
|
|
|
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);
|
2017-09-24 13:05:52 +02:00
|
|
|
mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &SpellCreationDialog::onAccept);
|
2012-09-24 08:09:16 +02:00
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
setWidgets(mAvailableEffectsList, mUsedEffectsView);
|
|
|
|
}
|
2012-10-03 15:06:54 +02:00
|
|
|
|
2017-09-22 21:26:41 +02:00
|
|
|
void SpellCreationDialog::setPtr(const MWWorld::Ptr& actor)
|
2012-10-03 15:36:10 +02:00
|
|
|
{
|
|
|
|
mPtr = actor;
|
2012-11-05 20:47:28 +01:00
|
|
|
mNameEdit->setCaption("");
|
2012-10-03 15:36:10 +02:00
|
|
|
|
|
|
|
startEditing();
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void SpellCreationDialog::onCancelButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
2017-09-23 12:18:39 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_SpellCreation);
|
2012-10-03 15:36:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpellCreationDialog::onBuyButtonClicked(MyGUI::Widget* sender)
|
|
|
|
{
|
2012-10-15 21:54:19 +02:00
|
|
|
if (mEffects.size() <= 0)
|
|
|
|
{
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage30}");
|
2012-10-15 21:54:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-19 14:31:25 +04:00
|
|
|
if (mNameEdit->getCaption() == "")
|
2012-10-15 21:54:19 +02:00
|
|
|
{
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage10}");
|
2012-10-15 21:54:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-23 11:42:38 +02:00
|
|
|
if (mMagickaCost->getCaption() == "0")
|
|
|
|
{
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sEnchantmentMenu8}");
|
2012-10-23 11:42:38 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-21 21:12:39 +12:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2014-01-08 23:37:46 +01:00
|
|
|
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
|
|
|
|
|
2021-04-10 11:26:54 +04:00
|
|
|
int price = MyGUI::utility::parseInt(mPriceLabel->getCaption());
|
|
|
|
if (price > playerGold)
|
2012-10-23 11:42:38 +02:00
|
|
|
{
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage18}");
|
2012-10-23 11:42:38 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-10-15 21:54:19 +02:00
|
|
|
|
2017-08-19 14:31:25 +04:00
|
|
|
mSpell.mName = mNameEdit->getCaption();
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2014-07-28 00:55:57 +02:00
|
|
|
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
|
|
|
|
|
|
|
|
// add gold to NPC trading gold pool
|
|
|
|
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
|
|
|
|
npcStats.setGoldPool(npcStats.getGoldPool() + price);
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2017-07-10 15:48:00 +04:00
|
|
|
MWBase::Environment::get().getWindowManager()->playSound("Mysticism Hit");
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2012-11-08 01:52:34 +04:00
|
|
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->createRecord(mSpell);
|
2012-10-15 21:54:19 +02:00
|
|
|
|
2014-05-22 20:37:22 +02:00
|
|
|
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
2012-10-15 21:54:19 +02:00
|
|
|
MWMechanics::Spells& spells = stats.getSpells();
|
2012-11-08 01:52:34 +04:00
|
|
|
spells.add(spell->mId);
|
2012-10-15 21:54:19 +02:00
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellCreation);
|
2012-10-03 15:36:10 +02:00
|
|
|
}
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2017-09-24 13:05:52 +02:00
|
|
|
void SpellCreationDialog::onAccept(MyGUI::EditBox* sender)
|
|
|
|
{
|
|
|
|
onBuyButtonClicked(sender);
|
2018-09-10 12:55:00 +04:00
|
|
|
|
|
|
|
// To do not spam onAccept() again and again
|
|
|
|
MWBase::Environment::get().getWindowManager()->injectKeyRelease(MyGUI::KeyCode::None);
|
2017-09-24 13:05:52 +02:00
|
|
|
}
|
|
|
|
|
2017-09-22 17:10:53 +02:00
|
|
|
void SpellCreationDialog::onOpen()
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
|
|
|
center();
|
2019-06-09 02:08:09 +03:00
|
|
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpellCreationDialog::onReferenceUnavailable()
|
|
|
|
{
|
2013-04-10 00:32:05 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellCreation);
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
2012-10-23 11:42:38 +02:00
|
|
|
void SpellCreationDialog::notifyEffectsChanged()
|
|
|
|
{
|
2014-08-12 18:53:03 +02:00
|
|
|
if (mEffects.empty())
|
|
|
|
{
|
|
|
|
mMagickaCost->setCaption("0");
|
|
|
|
mPriceLabel->setCaption("0");
|
|
|
|
mSuccessChance->setCaption("0");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-23 11:42:38 +02:00
|
|
|
float y = 0;
|
|
|
|
|
2012-11-05 23:41:26 +04:00
|
|
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const ESM::ENAMstruct& effect : mEffects)
|
2012-10-23 11:42:38 +02:00
|
|
|
{
|
2021-04-02 19:47:21 +02:00
|
|
|
y += std::max(
|
|
|
|
1.f, MWMechanics::calcEffectCost(effect, nullptr, MWMechanics::EffectCostMethod::PlayerSpell));
|
2012-11-05 23:41:26 +04:00
|
|
|
|
2017-06-30 16:27:18 +04:00
|
|
|
if (effect.mRange == ESM::RT_Target)
|
2012-10-23 11:42:38 +02:00
|
|
|
y *= 1.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
ESM::EffectList effectList;
|
|
|
|
effectList.mList = mEffects;
|
|
|
|
mSpell.mEffects = effectList;
|
2014-10-02 00:32:22 +02:00
|
|
|
mSpell.mData.mCost = int(y);
|
2012-10-23 11:42:38 +02:00
|
|
|
mSpell.mData.mType = ESM::Spell::ST_Spell;
|
2014-10-02 00:32:22 +02:00
|
|
|
mSpell.mData.mFlags = 0;
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2015-01-10 03:01:01 +01:00
|
|
|
mMagickaCost->setCaption(MyGUI::utility::toString(int(y)));
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2018-08-29 18:38:12 +03:00
|
|
|
float fSpellMakingValueMult = store.get<ESM::GameSetting>().find("fSpellMakingValueMult")->mValue.getFloat();
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2020-09-08 16:55:12 +04:00
|
|
|
int price = std::max(1, static_cast<int>(y * fSpellMakingValueMult));
|
|
|
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2015-01-10 03:01:01 +01:00
|
|
|
mPriceLabel->setCaption(MyGUI::utility::toString(int(price)));
|
2012-10-23 11:42:38 +02:00
|
|
|
|
2018-10-09 10:21:12 +04:00
|
|
|
float chance = MWMechanics::calcSpellBaseSuccessChance(&mSpell, MWMechanics::getPlayer(), nullptr);
|
2017-06-30 16:27:18 +04:00
|
|
|
|
|
|
|
int intChance = std::min(100, int(chance));
|
|
|
|
mSuccessChance->setCaption(MyGUI::utility::toString(intChance));
|
2012-10-23 11:42:38 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
|
2014-08-24 21:59:52 +02:00
|
|
|
EffectEditorBase::EffectEditorBase(Type type)
|
2018-10-09 10:21:12 +04:00
|
|
|
: mAvailableEffectsList(nullptr)
|
|
|
|
, mUsedEffectsView(nullptr)
|
2015-04-30 19:24:27 -05:00
|
|
|
, mAddEffectDialog()
|
2014-10-11 01:20:33 +02:00
|
|
|
, mSelectedEffect(0)
|
|
|
|
, mSelectedKnownEffectId(0)
|
2015-01-05 05:33:51 +01:00
|
|
|
, mConstantEffect(false)
|
2015-04-30 19:24:27 -05:00
|
|
|
, mType(type)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
2012-10-03 15:36:10 +02:00
|
|
|
mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded);
|
|
|
|
mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified);
|
|
|
|
mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &EffectEditorBase::onEffectRemoved);
|
|
|
|
|
|
|
|
mAddEffectDialog.setVisible(false);
|
|
|
|
}
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2013-06-09 23:08:57 +02:00
|
|
|
EffectEditorBase::~EffectEditorBase() {}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::startEditing()
|
|
|
|
{
|
2012-09-23 00:36:20 +02:00
|
|
|
// get the list of magic effects that are known to the player
|
|
|
|
|
2015-08-21 21:12:39 +12:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2014-05-22 20:37:22 +02:00
|
|
|
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
2012-09-23 00:36:20 +02:00
|
|
|
MWMechanics::Spells& spells = stats.getSpells();
|
|
|
|
|
|
|
|
std::vector<short> knownEffects;
|
|
|
|
|
2021-08-27 20:07:50 +02:00
|
|
|
for (const ESM::Spell* spell : spells)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
|
|
|
// only normal spells count
|
2012-10-01 17:54:45 +02:00
|
|
|
if (spell->mData.mType != ESM::Spell::ST_Spell)
|
2012-09-23 00:36:20 +02:00
|
|
|
continue;
|
|
|
|
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const ESM::ENAMstruct& effectInfo : spell->mEffects.mList)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
2019-03-02 13:27:59 +04:00
|
|
|
const ESM::MagicEffect* effect
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(
|
|
|
|
effectInfo.mEffectID);
|
2014-08-24 21:59:52 +02:00
|
|
|
|
|
|
|
// skip effects that do not allow spellmaking/enchanting
|
|
|
|
int requiredFlags
|
|
|
|
= (mType == Spellmaking) ? ESM::MagicEffect::AllowSpellmaking : ESM::MagicEffect::AllowEnchanting;
|
|
|
|
if (!(effect->mData.mFlags & requiredFlags))
|
|
|
|
continue;
|
|
|
|
|
2019-03-02 13:27:59 +04:00
|
|
|
if (std::find(knownEffects.begin(), knownEffects.end(), effectInfo.mEffectID) == knownEffects.end())
|
|
|
|
knownEffects.push_back(effectInfo.mEffectID);
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(knownEffects.begin(), knownEffects.end(), sortMagicEffects);
|
|
|
|
|
|
|
|
mAvailableEffectsList->clear();
|
|
|
|
|
2013-03-28 17:41:00 +01:00
|
|
|
int i = 0;
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const short effectId : knownEffects)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
2012-11-05 23:41:26 +04:00
|
|
|
mAvailableEffectsList->addItem(MWBase::Environment::get()
|
|
|
|
.getWorld()
|
|
|
|
->getStore()
|
|
|
|
.get<ESM::GameSetting>()
|
2019-03-02 13:27:59 +04:00
|
|
|
.find(ESM::MagicEffect::effectIdToString(effectId))
|
|
|
|
->mValue.getString());
|
|
|
|
mButtonMapping[i] = effectId;
|
2013-03-28 17:41:00 +01:00
|
|
|
++i;
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
mAvailableEffectsList->adjustSize();
|
2015-06-04 23:09:40 +03:00
|
|
|
mAvailableEffectsList->scrollToTop();
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const short effectId : knownEffects)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
2022-08-28 15:06:31 +02:00
|
|
|
const std::string& name = MWBase::Environment::get()
|
|
|
|
.getWorld()
|
|
|
|
->getStore()
|
|
|
|
.get<ESM::GameSetting>()
|
2019-03-02 13:27:59 +04:00
|
|
|
.find(ESM::MagicEffect::effectIdToString(effectId))
|
|
|
|
->mValue.getString();
|
2012-09-23 00:36:20 +02:00
|
|
|
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
|
|
|
|
|
2019-03-02 13:27:59 +04:00
|
|
|
ToolTips::createMagicEffectToolTip(w, effectId);
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
2012-10-15 21:54:19 +02:00
|
|
|
|
|
|
|
mEffects.clear();
|
|
|
|
updateEffectsView();
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
2014-09-25 16:25:08 +02:00
|
|
|
void EffectEditorBase::setWidgets(Gui::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView)
|
2012-09-23 00:36:20 +02:00
|
|
|
{
|
2012-10-03 15:36:10 +02:00
|
|
|
mAvailableEffectsList = availableEffectsList;
|
|
|
|
mUsedEffectsView = usedEffectsView;
|
2012-09-23 00:36:20 +02:00
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
mAvailableEffectsList->eventWidgetSelected
|
|
|
|
+= MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked);
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onSelectAttribute()
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
2014-08-15 00:30:24 +02:00
|
|
|
const ESM::MagicEffect* effect
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(mSelectedKnownEffectId);
|
|
|
|
|
|
|
|
mAddEffectDialog.newEffect(effect);
|
2012-10-03 15:06:54 +02:00
|
|
|
mAddEffectDialog.setAttribute(mSelectAttributeDialog->getAttributeId());
|
2022-07-20 22:13:33 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectAttributeDialog));
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onSelectSkill()
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
2014-08-15 00:30:24 +02:00
|
|
|
const ESM::MagicEffect* effect
|
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(mSelectedKnownEffectId);
|
|
|
|
|
|
|
|
mAddEffectDialog.newEffect(effect);
|
|
|
|
mAddEffectDialog.setSkill(mSelectSkillDialog->getSkillId());
|
2022-07-20 22:13:33 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectSkillDialog));
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onAttributeOrSkillCancel()
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
2022-07-20 22:13:33 +02:00
|
|
|
if (mSelectSkillDialog != nullptr)
|
|
|
|
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectSkillDialog));
|
|
|
|
if (mSelectAttributeDialog != nullptr)
|
|
|
|
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectAttributeDialog));
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onAvailableEffectClicked(MyGUI::Widget* sender)
|
2012-09-24 08:09:16 +02:00
|
|
|
{
|
2012-10-23 11:42:38 +02:00
|
|
|
if (mEffects.size() >= 8)
|
|
|
|
{
|
2013-03-30 12:56:37 +01:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}");
|
2012-10-23 11:42:38 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-09-24 08:09:16 +02:00
|
|
|
|
2013-03-28 17:41:00 +01:00
|
|
|
int buttonId = *sender->getUserData<int>();
|
2014-08-15 00:30:24 +02:00
|
|
|
mSelectedKnownEffectId = mButtonMapping[buttonId];
|
2012-10-15 21:54:19 +02:00
|
|
|
|
2012-11-05 23:41:26 +04:00
|
|
|
const ESM::MagicEffect* effect
|
2014-08-15 00:30:24 +02:00
|
|
|
= MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(mSelectedKnownEffectId);
|
2012-09-24 22:09:38 +02:00
|
|
|
|
2022-02-28 16:42:22 +01:00
|
|
|
bool allowSelf = (effect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0;
|
|
|
|
bool allowTouch = (effect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect;
|
|
|
|
bool allowTarget = (effect->mData.mFlags & ESM::MagicEffect::CastTarget) && !mConstantEffect;
|
|
|
|
|
|
|
|
if (!allowSelf && !allowTouch && !allowTarget)
|
|
|
|
return; // TODO: Show an error message popup?
|
|
|
|
|
2012-10-03 15:06:54 +02:00
|
|
|
if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill)
|
|
|
|
{
|
2022-07-20 22:13:33 +02:00
|
|
|
mSelectSkillDialog = std::make_unique<SelectSkillDialog>();
|
2012-10-03 15:06:54 +02:00
|
|
|
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)
|
|
|
|
{
|
2022-07-20 22:13:33 +02:00
|
|
|
mSelectAttributeDialog = std::make_unique<SelectAttributeDialog>();
|
2012-10-03 15:06:54 +02:00
|
|
|
mSelectAttributeDialog->eventCancel
|
|
|
|
+= MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel);
|
|
|
|
mSelectAttributeDialog->eventItemSelected
|
|
|
|
+= MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute);
|
|
|
|
mSelectAttributeDialog->setVisible(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const ESM::ENAMstruct& effectInfo : mEffects)
|
2014-12-22 01:54:24 +01:00
|
|
|
{
|
2019-03-02 13:27:59 +04:00
|
|
|
if (effectInfo.mEffectID == mSelectedKnownEffectId)
|
2014-12-22 01:54:24 +01:00
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sOnetypeEffectMessage}");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-15 00:30:24 +02:00
|
|
|
mAddEffectDialog.newEffect(effect);
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
2012-09-24 08:09:16 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onEffectModified(ESM::ENAMstruct effect)
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
mEffects[mSelectedEffect] = effect;
|
|
|
|
|
|
|
|
updateEffectsView();
|
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onEffectRemoved(ESM::ENAMstruct effect)
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
mEffects.erase(mEffects.begin() + mSelectedEffect);
|
|
|
|
updateEffectsView();
|
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::updateEffectsView()
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator();
|
|
|
|
MyGUI::Gui::getInstance().destroyWidgets(oldWidgets);
|
|
|
|
|
|
|
|
MyGUI::IntSize size(0, 0);
|
|
|
|
|
|
|
|
int i = 0;
|
2019-03-02 13:27:59 +04:00
|
|
|
for (const ESM::ENAMstruct& effectInfo : mEffects)
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
Widgets::SpellEffectParams params;
|
2019-03-02 13:27:59 +04:00
|
|
|
params.mEffectID = effectInfo.mEffectID;
|
|
|
|
params.mSkill = effectInfo.mSkill;
|
|
|
|
params.mAttribute = effectInfo.mAttribute;
|
|
|
|
params.mDuration = effectInfo.mDuration;
|
|
|
|
params.mMagnMin = effectInfo.mMagnMin;
|
|
|
|
params.mMagnMax = effectInfo.mMagnMax;
|
|
|
|
params.mRange = effectInfo.mRange;
|
|
|
|
params.mArea = effectInfo.mArea;
|
2015-01-05 05:33:51 +01:00
|
|
|
params.mIsConstant = mConstantEffect;
|
2012-10-03 15:06:54 +02:00
|
|
|
|
|
|
|
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->setSpellEffect(params);
|
|
|
|
|
|
|
|
effect->setSize(effect->getRequestedWidth(), 24);
|
|
|
|
button->setSize(effect->getRequestedWidth(), 24);
|
|
|
|
|
|
|
|
size.width = std::max(size.width, effect->getRequestedWidth());
|
|
|
|
size.height += 24;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
2014-07-26 02:23:42 +02:00
|
|
|
// Canvas size must be expressed with HScroll disabled, otherwise MyGUI would expand the scroll area when the
|
|
|
|
// scrollbar is hidden
|
|
|
|
mUsedEffectsView->setVisibleHScroll(false);
|
2012-10-03 15:06:54 +02:00
|
|
|
mUsedEffectsView->setCanvasSize(size);
|
2014-07-26 02:23:42 +02:00
|
|
|
mUsedEffectsView->setVisibleHScroll(true);
|
2012-10-23 11:42:38 +02:00
|
|
|
|
|
|
|
notifyEffectsChanged();
|
2012-10-03 15:06:54 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onEffectAdded(ESM::ENAMstruct effect)
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
mEffects.push_back(effect);
|
2013-07-31 13:33:30 +02:00
|
|
|
mSelectedEffect = mEffects.size() - 1;
|
2012-10-03 15:06:54 +02:00
|
|
|
|
|
|
|
updateEffectsView();
|
|
|
|
}
|
|
|
|
|
2012-10-03 15:36:10 +02:00
|
|
|
void EffectEditorBase::onEditEffect(MyGUI::Widget* sender)
|
2012-10-03 15:06:54 +02:00
|
|
|
{
|
|
|
|
int id = *sender->getUserData<int>();
|
|
|
|
|
|
|
|
mSelectedEffect = id;
|
|
|
|
|
|
|
|
mAddEffectDialog.editEffect(mEffects[id]);
|
|
|
|
mAddEffectDialog.setVisible(true);
|
|
|
|
}
|
2015-01-05 05:33:51 +01:00
|
|
|
|
|
|
|
void EffectEditorBase::setConstantEffect(bool constant)
|
|
|
|
{
|
|
|
|
mAddEffectDialog.setConstantEffect(constant);
|
|
|
|
mConstantEffect = constant;
|
2020-09-25 02:12:36 +03:00
|
|
|
|
|
|
|
if (!constant)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (auto it = mEffects.begin(); it != mEffects.end();)
|
|
|
|
{
|
|
|
|
if (it->mRange != ESM::RT_Self)
|
|
|
|
{
|
|
|
|
auto& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
auto magicEffect = store.get<ESM::MagicEffect>().find(it->mEffectID);
|
|
|
|
if ((magicEffect->mData.mFlags & ESM::MagicEffect::CastSelf) == 0)
|
|
|
|
{
|
|
|
|
it = mEffects.erase(it);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
it->mRange = ESM::RT_Self;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
2015-01-05 05:33:51 +01:00
|
|
|
}
|
2012-09-23 00:36:20 +02:00
|
|
|
}
|