|
|
|
@ -44,8 +44,36 @@ namespace MWMechanics
|
|
|
|
|
return schoolSkillMap[school];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap)
|
|
|
|
|
float calcEffectCost(const ESM::ENAMstruct& effect)
|
|
|
|
|
{
|
|
|
|
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
|
|
|
|
|
|
|
|
|
int minMagn = 1;
|
|
|
|
|
int maxMagn = 1;
|
|
|
|
|
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
|
|
|
|
{
|
|
|
|
|
minMagn = effect.mMagnMin;
|
|
|
|
|
maxMagn = effect.mMagnMax;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int duration = 0;
|
|
|
|
|
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
|
|
|
|
|
duration = effect.mDuration;
|
|
|
|
|
|
|
|
|
|
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore()
|
|
|
|
|
.get<ESM::GameSetting>().find("fEffectCostMult")->getFloat();
|
|
|
|
|
|
|
|
|
|
float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));
|
|
|
|
|
x *= 0.1 * magicEffect->mData.mBaseCost;
|
|
|
|
|
x *= 1 + duration;
|
|
|
|
|
x += 0.05 * std::max(1, effect.mArea) * magicEffect->mData.mBaseCost;
|
|
|
|
|
|
|
|
|
|
return x * fEffectCostMult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float calcSpellBaseSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool)
|
|
|
|
|
{
|
|
|
|
|
// Morrowind for some reason uses a formula slightly different from magicka cost calculation
|
|
|
|
|
float y = std::numeric_limits<float>::max();
|
|
|
|
|
float lowestSkill = 0;
|
|
|
|
|
|
|
|
|
@ -54,8 +82,10 @@ namespace MWMechanics
|
|
|
|
|
float x = static_cast<float>(it->mDuration);
|
|
|
|
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(
|
|
|
|
|
it->mEffectID);
|
|
|
|
|
|
|
|
|
|
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage))
|
|
|
|
|
x = std::max(1.f, x);
|
|
|
|
|
|
|
|
|
|
x *= 0.1f * magicEffect->mData.mBaseCost;
|
|
|
|
|
x *= 0.5f * (it->mMagnMin + it->mMagnMax);
|
|
|
|
|
x *= it->mArea * 0.05f * magicEffect->mData.mBaseCost;
|
|
|
|
@ -75,6 +105,18 @@ namespace MWMechanics
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
|
|
|
|
|
|
|
|
|
int actorWillpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
|
|
|
|
int actorLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
|
|
|
|
|
|
|
|
|
float castChance = (lowestSkill - spell->mData.mCost + 0.2f * actorWillpower + 0.1f * actorLuck);
|
|
|
|
|
|
|
|
|
|
return castChance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap)
|
|
|
|
|
{
|
|
|
|
|
bool godmode = actor == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
|
|
|
|
|
|
|
|
|
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
|
|
|
@ -98,10 +140,8 @@ namespace MWMechanics
|
|
|
|
|
|
|
|
|
|
float castBonus = -stats.getMagicEffects().get(ESM::MagicEffect::Sound).getMagnitude();
|
|
|
|
|
|
|
|
|
|
int actorWillpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
|
|
|
|
int actorLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
|
|
|
|
|
|
|
|
|
float castChance = (lowestSkill - spell->mData.mCost + castBonus + 0.2f * actorWillpower + 0.1f * actorLuck) * stats.getFatigueTerm();
|
|
|
|
|
float castChance = calcSpellBaseSuccessChance(spell, actor, effectiveSchool) + castBonus;
|
|
|
|
|
castChance *= stats.getFatigueTerm();
|
|
|
|
|
|
|
|
|
|
if (!cap)
|
|
|
|
|
return std::max(0.f, castChance);
|
|
|
|
|