void MWMechanics::Alchemy::addPotion (const std::string& name)
{
    ESM::Potion newRecord;

    newRecord.mData.mWeight = 0;

    for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter)
        if (!iter->isEmpty())
            newRecord.mData.mWeight += iter->get<ESM::Ingredient>()->mBase->mData.mWeight;

    if (countIngredients() > 0)
        newRecord.mData.mWeight /= countIngredients();

    newRecord.mData.mValue = mValue;
    newRecord.mData.mAutoCalc = 0;

    newRecord.mName = name;

    int index = Misc::Rng::rollDice(6);
    assert (index>=0 && index<6);

    static const char *meshes[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" };

    newRecord.mModel = "m\\misc_potion_" + std::string (meshes[index]) + "_01.nif";
    newRecord.mIcon = "m\\tx_potion_" + std::string (meshes[index]) + "_01.dds";

    newRecord.mEffects.mList = mEffects;

    const ESM::Potion* record = getRecord(newRecord);
    if (!record)
        record = MWBase::Environment::get().getWorld()->createRecord (newRecord);

    mAlchemist.getClass().getContainerStore (mAlchemist).add (record->mId, 1, mAlchemist);
}
Exemple #2
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;
}
Exemple #3
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() && getPotionName().empty())
        return Result_NoName;

    if (beginEffects()==endEffects())
        return Result_NoEffects;

    if (getChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
    {
        removeIngredients();
        return Result_RandomFailure;
    }

    addPotion (name);

    removeIngredients();

    increaseSkill();

    return Result_Success;
}
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);
        }
    }
}