예제 #1
0
MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& name)
{
    if (mTools[ESM::Apparatus::MortarPestle].isEmpty())
        return Result_NoMortarAndPestle;

    if (countIngredients()<2)
        return Result_LessThanTwoIngredients;

    if (name.empty())
        return Result_NoName;

    if (listEffects().empty())
        return Result_NoEffects;

    if (beginEffects() == endEffects())
    {
        // all effects were nullified due to insufficient skill
        removeIngredients();
        return Result_RandomFailure;
    }

    if (getAlchemyFactor() < OEngine::Misc::Rng::roll0to99())
    {
        removeIngredients();
        return Result_RandomFailure;
    }

    addPotion (name);

    removeIngredients();

    increaseSkill();

    return Result_Success;
}
예제 #2
0
std::string MWMechanics::Alchemy::suggestPotionName()
{
    std::set<MWMechanics::EffectKey> effects = listEffects();
    if (effects.empty())
        return "";

    int effectId = effects.begin()->mId;
    return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
                ESM::MagicEffect::effectIdToString(effectId))->getString();
}
예제 #3
0
void MWMechanics::Alchemy::updateEffects()
{
    mEffects.clear();
    mValue = 0;

    if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty())
        return;

    // find effects
    std::set<EffectKey> effects (listEffects());

    // general alchemy factor
    float x = getAlchemyFactor();

    x *= mTools[ESM::Apparatus::MortarPestle].get<ESM::Apparatus>()->mBase->mData.mQuality;
    x *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionStrengthMult")->getFloat();

    // value
    mValue = static_cast<int> (
        x * MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iAlchemyMod")->getFloat());

    // build quantified effect list
    for (std::set<EffectKey>::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter)
    {
        const ESM::MagicEffect *magicEffect =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (iter->mId);

        if (magicEffect->mData.mBaseCost<=0)
        {
            std::ostringstream os;
            os << "invalid base cost for magic effect " << iter->mId;
            throw std::runtime_error (os.str());
        }

        float fPotionT1MagMul =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1MagMult")->getFloat();

        if (fPotionT1MagMul<=0)
            throw std::runtime_error ("invalid gmst: fPotionT1MagMul");

        float fPotionT1DurMult =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1DurMult")->getFloat();

        if (fPotionT1DurMult<=0)
            throw std::runtime_error ("invalid gmst: fPotionT1DurMult");

        float magnitude = magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude ?
            1 : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost;
        float duration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ?
            1 : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost;

        if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
            applyTools (magicEffect->mData.mFlags, magnitude);

        if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
            applyTools (magicEffect->mData.mFlags, duration);

        duration = roundf(duration);
        magnitude = roundf(magnitude);

        if (magnitude>0 && duration>0)
        {
            ESM::ENAMstruct effect;
            effect.mEffectID = iter->mId;

            effect.mAttribute = -1;
            effect.mSkill = -1;

            if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
                effect.mSkill = iter->mArg;
            else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
                effect.mAttribute = iter->mArg;

            effect.mRange = 0;
            effect.mArea = 0;

            effect.mDuration = static_cast<int>(duration);
            effect.mMagnMin = effect.mMagnMax = static_cast<int>(magnitude);

            mEffects.push_back (effect);
        }
    }
}