mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
finished spell creation
This commit is contained in:
parent
33361e6539
commit
234716daa6
4 changed files with 93 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
std::pair<std::string, const ESM::Spell*> result = MWBase::Environment::get().getWorld()->createRecord(newSpell);
|
||||
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
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…
Reference in a new issue