finished spell creation

actorid
scrawl 12 years ago
parent 33361e6539
commit 234716daa6

@ -15,10 +15,14 @@
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellsuccess.hpp"
#include "tooltips.hpp"
#include "widgets.hpp"
#include "class.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace
{
@ -310,14 +314,25 @@ namespace MWGui
return;
}
ESM::Spell newSpell;
ESM::EffectList effectList;
effectList.mList = mEffects;
newSpell.mEffects = effectList;
newSpell.mName = mNameEdit->getCaption();
newSpell.mData.mType = ESM::Spell::ST_Spell;
if (mMagickaCost->getCaption() == "0")
{
mWindowManager.messageBox ("#{sEnchantmentMenu8}", std::vector<std::string>());
return;
}
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
return;
}
std::pair<std::string, const ESM::Spell*> result = MWBase::Environment::get().getWorld()->createRecord(newSpell);
mSpell.mName = mNameEdit->getCaption();
mWindowManager.getTradeWindow()->addOrRemoveGold(-boost::lexical_cast<int>(mPriceLabel->getCaption()));
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
std::pair<std::string, const ESM::Spell*> result = MWBase::Environment::get().getWorld()->createRecord(mSpell);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
@ -340,6 +355,47 @@ namespace MWGui
mWindowManager.removeGuiMode (GM_SpellCreation);
}
void SpellCreationDialog::notifyEffectsChanged ()
{
float y = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{
float x = 0.5 * it->mMagnMin + it->mMagnMax;
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(it->mEffectID);
x *= 0.1 * effect->mData.mBaseCost;
x *= 1 + it->mDuration;
x += 0.05 * std::max(1, it->mArea) * effect->mData.mBaseCost;
float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fEffectCostMult")->getFloat();
y += x * fEffectCostMult;
y = std::max(1.f,y);
if (effect->mData.mFlags & ESM::MagicEffect::CastTarget)
y *= 1.5;
}
mSpell.mData.mCost = int(y);
ESM::EffectList effectList;
effectList.mList = mEffects;
mSpell.mEffects = effectList;
mSpell.mData.mType = ESM::Spell::ST_Spell;
mMagickaCost->setCaption(boost::lexical_cast<std::string>(int(y)));
float fSpellMakingValueMult = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellMakingValueMult")->getFloat();
/// \todo mercantile
int price = int(y) * fSpellMakingValueMult;
mPriceLabel->setCaption(boost::lexical_cast<std::string>(int(price)));
float chance = MWMechanics::getSpellSuccessChance(&mSpell, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mSuccessChance->setCaption(boost::lexical_cast<std::string>(int(chance)));
}
// ------------------------------------------------------------------------------------------------
@ -443,6 +499,11 @@ namespace MWGui
void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender)
{
if (mEffects.size() >= 8)
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}", std::vector<std::string>());
return;
}
short effectId = *sender->getUserData<short>();
@ -534,6 +595,8 @@ namespace MWGui
}
mUsedEffectsView->setCanvasSize(size);
notifyEffectsChanged();
}
void EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect)

@ -116,6 +116,7 @@ namespace MWGui
void startEditing();
void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView);
virtual void notifyEffectsChanged () {}
};
class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
@ -133,6 +134,7 @@ namespace MWGui
void onCancelButtonClicked (MyGUI::Widget* sender);
void onBuyButtonClicked (MyGUI::Widget* sender);
virtual void notifyEffectsChanged ();
MyGUI::EditBox* mNameEdit;
MyGUI::TextBox* mMagickaCost;
@ -143,6 +145,8 @@ namespace MWGui
Widgets::MWEffectList* mUsedEffectsList;
ESM::Spell mSpell;
};
}

@ -27,9 +27,8 @@ namespace MWMechanics
return schoolSkillMap[school];
}
inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor)
inline int getSpellSchool(const ESM::Spell* spell, const MWWorld::Ptr& actor)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
// determine the spell's school
@ -60,27 +59,34 @@ namespace MWMechanics
return school;
}
inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
return getSpellSchool(spell, actor);
}
// UESP wiki / Morrowind/Spells:
// Chance of success is (Spell's skill * 2 + Willpower / 5 + Luck / 10 - Spell cost - Sound magnitude) * (Current fatigue + Maximum Fatigue * 1.5) / Maximum fatigue * 2
/**
* @param spellId ID of spell
* @param spell spell to cast
* @param actor calculate spell success chance for this actor (depends on actor's skills)
* @attention actor has to be an NPC and not a creature!
* @return success chance from 0 to 100 (in percent)
*/
inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor)
inline float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
if (spell->mData.mFlags & ESM::Spell::F_Always // spells with this flag always succeed (usually birthsign spells)
|| spell->mData.mType == ESM::Spell::ST_Power) // powers always succeed, but can be cast only once per day
return 100.0;
if (spell->mEffects.mList.size() == 0)
return 0.0;
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
int skillLevel = stats.getSkill (getSpellSchool(spellId, actor)).getModified();
int skillLevel = stats.getSkill (getSpellSchool(spell, actor)).getModified();
// Sound magic effect (reduces spell casting chance)
int soundMagnitude = creatureStats.getMagicEffects().get (MWMechanics::EffectKey (48)).mMagnitude;
@ -98,6 +104,12 @@ namespace MWMechanics
return chance;
}
inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
return getSpellSuccessChance(spell, actor);
}
}
#endif

@ -22,7 +22,6 @@
<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>
@ -31,7 +30,6 @@
<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>
@ -64,7 +62,6 @@
<Property key="Caption" value="#{sBarterDialog7}"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="PriceLabel">
<Property key="Caption" value="30"/>
</Widget>

Loading…
Cancel
Save