예제 #1
0
    bool Enchanting::create()
    {
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
        ESM::Enchantment enchantment;
        enchantment.mData.mCharge = getGemCharge();

        mSoulGemPtr.getRefData().setCount (mSoulGemPtr.getRefData().getCount()-1);

        //Exception for Azura Star, new one will be added after enchanting
        if(boost::iequals(mSoulGemPtr.get<ESM::Miscellaneous>()->mBase->mId, "Misc_SoulGem_Azura"))
        {
            MWWorld::ManualRef azura (MWBase::Environment::get().getWorld()->getStore(), "Misc_SoulGem_Azura");
            MWWorld::Class::get (player).getContainerStore (player).add (azura.getPtr());
        }

        if(mSelfEnchanting)
        {
            if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
                return false;

            MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1);
        }

        if(mCastStyle==ESM::Enchantment::ConstantEffect)
        {
            enchantment.mData.mCharge=0;
        }
        enchantment.mData.mType = mCastStyle;
        enchantment.mData.mCost = getEnchantPoints();
        enchantment.mEffects = mEffectList;

        const ESM::Enchantment *enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord (enchantment);

        MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName);

        mOldItemPtr.getRefData().setCount(1);

        MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), mOldItemId);
        ref.getPtr().getRefData().setCount (mOldItemCount-1);

        MWWorld::Class::get (player).getContainerStore (player).add (ref.getPtr());
        if(!mSelfEnchanting)
            payForEnchantment();

        return true;
    }
예제 #2
0
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

                    std::string creature = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    std::string gem = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
                    store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature

                    MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), gem);

                    ref.getPtr().getRefData().setCount (1);

                    ref.getPtr().getCellRef().mSoul = creature;

                    MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());

                }
예제 #3
0
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

                    std::string item = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    Interpreter::Type_Integer count = runtime[0].mInteger;
                    runtime.pop();

                    if (count<0)
                        throw std::runtime_error ("second argument for AddItem must be non-negative");

                    // no-op
                    if (count == 0)
                        return;

                    MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item);

                    ref.getPtr().getRefData().setCount (count);
                    
                    // Configure item's script variables
                    std::string script = MWWorld::Class::get(ref.getPtr()).getScript(ref.getPtr());
                    if (script != "")
                    {
                        const ESM::Script *esmscript = MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (script);
                        ref.getPtr().getRefData().setLocals(*esmscript);
                    }

                    MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());

                    // Spawn a messagebox (only for items added to player's inventory)
                    if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer())
                    {
                        // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory
                        std::string msgBox;
                        std::string itemName = MWWorld::Class::get(ref.getPtr()).getName(ref.getPtr());
                        if (count == 1)
                        {
                            msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}");
                            msgBox = boost::str(boost::format(msgBox) % itemName);
                        }
                        else
                        {
                            msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}");
                            msgBox = boost::str(boost::format(msgBox) % count % itemName);
                        }

                        MWBase::Environment::get().getWindowManager()->messageBox(msgBox);
                    }
                }
예제 #4
0
    /// @return ID of resulting item, or empty if none
    inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0)
    {
        const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;

        const MWWorld::Ptr& player = getPlayer();
        int playerLevel = player.getClass().getCreatureStats(player).getLevel();

        failChance += levItem->mChanceNone;

        if (Misc::Rng::roll0to99() < failChance)
            return std::string();

        std::vector<std::string> candidates;
        int highestLevel = 0;
        for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
                highestLevel = it->mLevel;
        }

        // For levelled creatures, the flags are swapped. This file format just makes so much sense.
        bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0;
        if (creature)
            allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;

        std::pair<int, std::string> highest = std::make_pair(-1, "");
        for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            if (playerLevel >= it->mLevel
                    && (allLevels || it->mLevel == highestLevel))
            {
                candidates.push_back(it->mId);
                if (it->mLevel >= highest.first)
                    highest = std::make_pair(it->mLevel, it->mId);
            }
        }
        if (candidates.empty())
            return std::string();
        std::string item = candidates[Misc::Rng::rollDice(candidates.size())];

        // Vanilla doesn't fail on nonexistent items in levelled lists
        if (!MWBase::Environment::get().getWorld()->getStore().find(Misc::StringUtils::lowerCase(item)))
        {
            std::cerr << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" << levItem->mId << "'" << std::endl;
            return std::string();
        }

        // Is this another levelled item or a real item?
        MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1);
        if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name()
                && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name())
        {
            return item;
        }
        else
        {
            if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name())
                return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, failChance);
            else
                return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, failChance);
        }
    }
예제 #5
0
    /// @return ID of resulting item, or empty if none
    inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0)
    {
        const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;

        const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        int playerLevel = player.getClass().getCreatureStats(player).getLevel();

        failChance += levItem->mChanceNone;

        int random = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
        if (random < failChance)
            return std::string();

        std::vector<std::string> candidates;
        int highestLevel = 0;
        for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
                highestLevel = it->mLevel;
        }

        // For levelled creatures, the flags are swapped. This file format just makes so much sense.
        bool allLevels = levItem->mFlags & ESM::ItemLevList::AllLevels;
        if (creature)
            allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;

        std::pair<int, std::string> highest = std::make_pair(-1, "");
        for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
        {
            if (playerLevel >= it->mLevel
                    && (allLevels || it->mLevel == highestLevel))
            {
                candidates.push_back(it->mId);
                if (it->mLevel >= highest.first)
                    highest = std::make_pair(it->mLevel, it->mId);
            }
        }
        if (candidates.empty())
            return std::string();
        std::string item = candidates[std::rand()%candidates.size()];

        // Is this another levelled item or a real item?
        try
        {
            MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1);
            if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name()
                    && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name())
            {
                return item;
            }
            else
            {
                if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name())
                    return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, failChance);
                else
                    return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, failChance);
            }
        }
        catch (std::logic_error& e)
        {
            // Vanilla doesn't fail on nonexistent items in levelled lists
            std::cerr << "Warning: ignoring nonexistent item '" << item << "'" << std::endl;
            return std::string();
        }
    }