コード例 #1
0
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld::Ptr& item)
{
    MWWorld::ContainerStoreIterator retval = end();
    for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
    {
        if (item == *iter)
        {
            retval = iter;
            break;
        }
    }

    if (retval == end())
        throw std::runtime_error("item is not from this container");

    for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
    {
        if (stacks(*iter, item))
        {
            iter->getRefData().setCount(iter->getRefData().getCount() + item.getRefData().getCount());
            item.getRefData().setCount(0);
            retval = iter;
            break;
        }
    }
    return retval;
}
コード例 #2
0
ファイル: armor.cpp プロジェクト: dteviot/openmw
    std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
    {
        MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);

        if (ptr.getCellRef().getCharge() == 0)
            return std::make_pair(0, "#{sInventoryMessage1}");

        // slots that this item can be equipped in
        std::pair<std::vector<int>, bool> slots_ = ptr.getClass().getEquipmentSlots(ptr);

        if (slots_.first.empty())
            return std::make_pair(0, "");

        if (npc.getClass().isNpc())
        {
            std::string npcRace = npc.get<ESM::NPC>()->mBase->mRace;

            // Beast races cannot equip shoes / boots, or full helms (head part vs hair part)
            const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npcRace);
            if(race->mData.mFlags & ESM::Race::Beast)
            {
                std::vector<ESM::PartReference> parts = ptr.get<ESM::Armor>()->mBase->mParts.mParts;

                for(std::vector<ESM::PartReference>::iterator itr = parts.begin(); itr != parts.end(); ++itr)
                {
                    if((*itr).mPart == ESM::PRT_Head)
                        return std::make_pair(0, "#{sNotifyMessage13}");
                    if((*itr).mPart == ESM::PRT_LFoot || (*itr).mPart == ESM::PRT_RFoot)
                        return std::make_pair(0, "#{sNotifyMessage14}");
                }
            }
        }

        for (std::vector<int>::const_iterator slot=slots_.first.begin();
            slot!=slots_.first.end(); ++slot)
        {
            // If equipping a shield, check if there's a twohanded weapon conflicting with it
            if(*slot == MWWorld::InventoryStore::Slot_CarriedLeft)
            {
                MWWorld::ContainerStoreIterator weapon = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);

                if(weapon == invStore.end())
                    return std::make_pair(1,"");

                if(weapon->getTypeName() == typeid(ESM::Weapon).name() &&
                        (weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoClose ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoWide ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::SpearTwoWide ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::AxeTwoHand ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanBow ||
                weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow))
                {
                    return std::make_pair(3,"");
                }
                return std::make_pair(1,"");
            }
        }
        return std::make_pair(1,"");
    }
コード例 #3
0
ファイル: weaponanimation.cpp プロジェクト: scrawl/openmw
void WeaponAnimation::attachArrow(MWWorld::Ptr actor)
{
    MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor);
    MWWorld::ContainerStoreIterator weaponSlot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
    if (weaponSlot == inv.end())
        return;
    if (weaponSlot->getTypeName() != typeid(ESM::Weapon).name())
        return;
    int weaponType = weaponSlot->get<ESM::Weapon>()->mBase->mData.mType;
    if (weaponType == ESM::Weapon::MarksmanThrown)
    {
        std::string soundid = weaponSlot->getClass().getUpSoundId(*weaponSlot);
        if(!soundid.empty())
        {
            MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
            sndMgr->playSound3D(actor, soundid, 1.0f, 1.0f);
        }
        showWeapon(true);
    }
    else if (weaponType == ESM::Weapon::MarksmanBow || weaponType == ESM::Weapon::MarksmanCrossbow)
    {
        osg::Group* parent = getArrowBone();
        if (!parent)
            return;

        MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
        if (ammo == inv.end())
            return;
        std::string model = ammo->getClass().getModel(*ammo);

        osg::ref_ptr<osg::Node> arrow = getResourceSystem()->getSceneManager()->getInstance(model, parent);

        mAmmunition = PartHolderPtr(new PartHolder(arrow));
    }
}
コード例 #4
0
ファイル: light.cpp プロジェクト: ChairGraveyard/TES3MP
    std::pair<int, std::string> Light::canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const
    {
        const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
        if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
            return std::make_pair(0,"");

        MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);
        MWWorld::ContainerStoreIterator weapon = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);

        if(weapon == invStore.end())
            return std::make_pair(1,"");

        /// \todo the 2h check is repeated many times; put it in a function
        if(weapon->getTypeName() == typeid(ESM::Weapon).name() &&
                (weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoClose ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoWide ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::SpearTwoWide ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::AxeTwoHand ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanBow ||
        weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow))
        {
            return std::make_pair(3,"");
        }
        return std::make_pair(1,"");
    }
コード例 #5
0
ファイル: tradewindow.cpp プロジェクト: tdunn19/openmw
    void TradeWindow::addOrRemoveGold(int amount)
    {
        bool goldFound = false;
        MWWorld::Ptr gold;
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
        MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);

        for (MWWorld::ContainerStoreIterator it = playerStore.begin();
                it != playerStore.end(); ++it)
        {
            if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
            {
                goldFound = true;
                gold = *it;
            }
        }
        if (goldFound)
        {
            gold.getRefData().setCount(gold.getRefData().getCount() + amount);
        }
        else
        {
            assert(amount > 0);
            MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001");
            ref.getPtr().getRefData().setCount(amount);
            playerStore.add(ref.getPtr());
        }
    }
コード例 #6
0
ファイル: inventorystore.cpp プロジェクト: DartLizard/openmw
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipItemQuantity(const Ptr& item, const Ptr& actor, int count)
{
    if (!isEquipped(item))
        throw std::runtime_error ("attempt to unequip an item that is not currently equipped");
    if (count <= 0)
        throw std::runtime_error ("attempt to unequip nothing (count <= 0)");
    if (count > item.getRefData().getCount())
        throw std::runtime_error ("attempt to unequip more items than equipped");

    if (count == item.getRefData().getCount())
        return unequipItem(item, actor);

    // Move items to an existing stack if possible, otherwise split count items out into a new stack.
    // Moving counts manually here, since ContainerStore's restack can't target unequipped stacks.
    for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
    {
        if (stacks(*iter, item) && !isEquipped(*iter))
        {
            iter->getRefData().setCount(iter->getRefData().getCount() + count);
            item.getRefData().setCount(item.getRefData().getCount() - count);
            return iter;
        }
    }

    return unstack(item, actor, item.getRefData().getCount() - count);
}
コード例 #7
0
ファイル: inventorystore.cpp プロジェクト: DartLizard/openmw
void MWWorld::InventoryStore::readEquipmentState(const MWWorld::ContainerStoreIterator &iter, int index, const ESM::InventoryState &inventory)
{
    if (index == inventory.mSelectedEnchantItem)
        mSelectedEnchantItem = iter;

    std::map<int, int>::const_iterator found = inventory.mEquipmentSlots.find(index);
    if (found != inventory.mEquipmentSlots.end())
    {
        if (found->second < 0 || found->second >= MWWorld::InventoryStore::Slots)
            throw std::runtime_error("Invalid slot index in inventory state");

        // make sure the item can actually be equipped in this slot
        int slot = found->second;
        std::pair<std::vector<int>, bool> allowedSlots = iter->getClass().getEquipmentSlots(*iter);
        if (!allowedSlots.first.size())
            return;
        if (std::find(allowedSlots.first.begin(), allowedSlots.first.end(), slot) == allowedSlots.first.end())
            slot = allowedSlots.first.front();

        // unstack if required
        if (!allowedSlots.second && iter->getRefData().getCount() > 1)
        {
            MWWorld::ContainerStoreIterator newIter = addNewStack(*iter, 1);
            iter->getRefData().setCount(iter->getRefData().getCount()-1);
            mSlots[slot] = newIter;
        }
        else
            mSlots[slot] = iter;
    }
}
コード例 #8
0
void ContainerItemModel::update()
{
    mItems.clear();
    for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
    {
        MWWorld::ContainerStore& store = MWWorld::Class::get(*source).getContainerStore(*source);

        for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
        {
            std::vector<ItemStack>::iterator itemStack = mItems.begin();
            for (; itemStack != mItems.end(); ++itemStack)
            {
                // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
                if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it))
                {
                    // we already have an item stack of this kind, add to it
                    itemStack->mCount += it->getRefData().getCount();
                    break;
                }
            }

            if (itemStack == mItems.end())
            {
                // no stack yet, create one
                ItemStack newItem (*it, this, it->getRefData().getCount());
                mItems.push_back(newItem);
            }
        }
    }
}
コード例 #9
0
int MWWorld::ContainerStore::count(const std::string &id)
{
    int total=0;
    for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
        if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id))
            total += iter->getRefData().getCount();
    return total;
}
コード例 #10
0
ファイル: projectilemanager.cpp プロジェクト: gr4bb/openmw
    void ProjectileManager::moveProjectiles(float duration)
    {
        for (std::vector<ProjectileState>::iterator it = mProjectiles.begin(); it != mProjectiles.end();)
        {
            // gravity constant - must be way lower than the gravity affecting actors, since we're not
            // simulating aerodynamics at all
            it->mVelocity -= osg::Vec3f(0, 0, 627.2f * 0.1f) * duration;

            osg::Vec3f pos(it->mNode->getPosition());
            osg::Vec3f newPos = pos + it->mVelocity * duration;

            osg::Quat orient;
            orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity);
            it->mNode->setAttitude(orient);
            it->mNode->setPosition(newPos);

            update(*it, duration);

            MWWorld::Ptr caster = it->getCaster();

            // Check for impact
            // TODO: use a proper btRigidBody / btGhostObject?
            MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, 0xff, MWPhysics::CollisionType_Projectile);

            bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), newPos);
            if (result.mHit || underwater)
            {
                if (result.mHit)
                {
                    MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), it->mId);

                    // Try to get a Ptr to the bow that was used. It might no longer exist.
                    MWWorld::Ptr bow = projectileRef.getPtr();
                    if (!caster.isEmpty())
                    {
                        MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster);
                        MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
                        if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), it->mBowId))
                            bow = *invIt;
                    }

                    if (caster.isEmpty())
                        caster = result.mHitObject;

                    MWMechanics::projectileHit(caster, result.mHitObject, bow, projectileRef.getPtr(), result.mHitPos, it->mAttackStrength);
                }

                if (underwater)
                    mRendering->emitWaterRipple(newPos);

                mParent->removeChild(it->mNode);
                it = mProjectiles.erase(it);
                continue;
            }

            ++it;
        }
    }
コード例 #11
0
ファイル: container.cpp プロジェクト: Manbeardo/openmw
    boost::shared_ptr<MWWorld::Action> Container::activate (const MWWorld::Ptr& ptr,
        const MWWorld::Ptr& actor) const
    {
        const std::string lockedSound = "LockedChest";
        const std::string trapActivationSound = "Disarm Trap Fail";

        MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);

        bool needKey = ptr.getCellRef().lockLevel>0;
        bool hasKey = false;
        std::string keyName;
        for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
        {
            if (it->getCellRef ().refID == ptr.getCellRef().key)
            {
                hasKey = true;
                keyName = MWWorld::Class::get(*it).getName(*it);
            }
        }

        if (needKey && hasKey)
        {
            MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}", std::vector<std::string>());
            ptr.getCellRef().lockLevel = 0;
            // using a key disarms the trap
            ptr.getCellRef().trap = "";
        }


        if (!needKey || hasKey)
        {
            if(ptr.getCellRef().trap.empty())
            {
                boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr));
                return action;
            }
            else
            {
                // Trap activation goes here
                std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl;
                boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
                action->setSound(trapActivationSound);
                ptr.getCellRef().trap = "";
                return action;
            }
        }
        else
        {
            boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
            action->setSound(lockedSound);
            return action;
        }
    }
コード例 #12
0
 int TradeWindow::getMerchantGold()
 {
     int merchantGold = 0;
     MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
     for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
     {
         if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, MWWorld::ContainerStore::sGoldId))
             merchantGold += it->getRefData().getCount();
     }
     return merchantGold;
 }
コード例 #13
0
ファイル: inventorystore.cpp プロジェクト: Chiur/openmw
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, const MWWorld::Ptr& actor)
{
    ContainerStoreIterator it = mSlots[slot];

    if (it != end())
    {
        ContainerStoreIterator retval = it;

        // empty this slot
        mSlots[slot] = end();

        // restack the previously equipped item with other (non-equipped) items
        for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
        {
            if (stacks(*iter, *it))
            {
                iter->getRefData().setCount(iter->getRefData().getCount() + it->getRefData().getCount());
                it->getRefData().setCount(0);
                retval = iter;
                break;
            }
        }

        if (actor.getRefData().getHandle() == "player")
        {
            // Unset OnPCEquip Variable on item's script, if it has a script with that variable declared
            const std::string& script = Class::get(*it).getScript(*it);
            if (script != "")
                (*it).getRefData().getLocals().setVarByInt(script, "onpcequip", 0);

            // Update HUD icon when removing player weapon or selected enchanted item.
            // We have to check for both as the weapon could also be the enchanted item.
            if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
            {
                // weapon
                MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
            }
            if ((mSelectedEnchantItem != end()) && (mSelectedEnchantItem == it))
            {
                // enchanted item
                mSelectedEnchantItem = end();
                MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
            }
        }

        fireEquipmentChangedEvent();
        updateMagicEffects(actor);

        return retval;
    }

    return it;
}
コード例 #14
0
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
{
    int type = getType(ptr);

    const MWWorld::ESMStore &esmStore =
        MWBase::Environment::get().getWorld()->getStore();

    // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
    // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
    if (MWWorld::Class::get(ptr).getName(ptr) == esmStore.get<ESM::GameSetting>().find("sGold")->getString())
    {
        MWWorld::LiveCellRef<ESM::Miscellaneous> *gold =
            ptr.get<ESM::Miscellaneous>();

        if (compare_string_ci(gold->mRef.mRefID, "gold_001")
            || compare_string_ci(gold->mRef.mRefID, "gold_005")
            || compare_string_ci(gold->mRef.mRefID, "gold_010")
            || compare_string_ci(gold->mRef.mRefID, "gold_025")
            || compare_string_ci(gold->mRef.mRefID, "gold_100"))
        {
            MWWorld::ManualRef ref(esmStore, "Gold_001");

            int count = (ptr.getRefData().getCount() == 1) ? gold->mBase->mData.mValue : ptr.getRefData().getCount();
            ref.getPtr().getRefData().setCount(count);
            for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
            {
                if (compare_string_ci((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001"))
                {
                    (*iter).getRefData().setCount( (*iter).getRefData().getCount() + count);
                    flagAsModified();
                    return iter;
                }
            }

            return addImpl(ref.getPtr());
        }
    }

    // determine whether to stack or not
    for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
    {
        if (stacks(*iter, ptr))
        {
            // stack
            iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() );

            flagAsModified();
            return iter;
        }
    }
    // if we got here, this means no stacking
    return addImpl(ptr);
}
コード例 #15
0
ファイル: inventorywindow.cpp プロジェクト: 4DA/openmw
    int InventoryWindow::getPlayerGold()
    {
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);

        for (MWWorld::ContainerStoreIterator it = invStore.begin();
                it != invStore.end(); ++it)
        {
            if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
                return it->getRefData().getCount();
        }
        return 0;
    }
コード例 #16
0
ファイル: inventorywindow.cpp プロジェクト: angeld29/openmw
    int InventoryWindow::getPlayerGold()
    {
        MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);

        for (MWWorld::ContainerStoreIterator it = invStore.begin();
                it != invStore.end(); ++it)
        {
            if (toLower(it->getCellRef().refID) == "gold_001")
                return it->getRefData().getCount();
        }
        return 0;
    }
コード例 #17
0
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container, int count)
{
    if (ptr.getRefData().getCount() <= count)
        return end();
    MWWorld::ContainerStoreIterator it = addNewStack(ptr, ptr.getRefData().getCount()-count);
    const std::string script = it->getClass().getScript(*it);
    if (!script.empty())
        MWBase::Environment::get().getWorld()->getLocalScripts().add(script, *it);

    remove(ptr, ptr.getRefData().getCount()-count, container);

    return it;
}
コード例 #18
0
ファイル: containerextensions.cpp プロジェクト: 4DA/openmw
                virtual void execute(Interpreter::Runtime &runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

                    MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
                    MWWorld::ContainerStoreIterator it = invStore.getSlot (MWWorld::InventoryStore::Slot_CarriedRight);
                    if (it == invStore.end() || it->getTypeName () != typeid(ESM::Weapon).name())
                    {
                        runtime.push(-1);
                        return;
                    }

                    runtime.push(it->get<ESM::Weapon>()->mBase->mData.mType);
                }
コード例 #19
0
ファイル: containeritemmodel.cpp プロジェクト: Aozi/openmw
void ContainerItemModel::update()
{
    mItems.clear();
    for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
    {
        MWWorld::ContainerStore& store = MWWorld::Class::get(*source).getContainerStore(*source);

        for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
        {
            std::vector<ItemStack>::iterator itemStack = mItems.begin();
            for (; itemStack != mItems.end(); ++itemStack)
            {
                if (stacks(*it, itemStack->mBase))
                {
                    // we already have an item stack of this kind, add to it
                    itemStack->mCount += it->getRefData().getCount();
                    break;
                }
            }

            if (itemStack == mItems.end())
            {
                // no stack yet, create one
                ItemStack newItem (*it, this, it->getRefData().getCount());
                mItems.push_back(newItem);
            }
        }
    }
    for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
    {
        std::vector<ItemStack>::iterator itemStack = mItems.begin();
        for (; itemStack != mItems.end(); ++itemStack)
        {
            if (stacks(*source, itemStack->mBase))
            {
                // we already have an item stack of this kind, add to it
                itemStack->mCount += source->getRefData().getCount();
                break;
            }
        }

        if (itemStack == mItems.end())
        {
            // no stack yet, create one
            ItemStack newItem (*source, this, source->getRefData().getCount());
            mItems.push_back(newItem);
        }
    }
}
コード例 #20
0
ファイル: containerextensions.cpp プロジェクト: 4DA/openmw
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);

                    Interpreter::Type_Integer sum = 0;

                    for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
                        if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item))
                            sum += iter->getRefData().getCount();

                    runtime.push (sum);
                }
コード例 #21
0
ファイル: miscextensions.cpp プロジェクト: UIKit0/openmw
                virtual void execute (Interpreter::Runtime& runtime)
                {

                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);


                    for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
                    {
                        if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul))
                        {

                            if(iter->getRefData().getCount() <= 1)
                            {
                                MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
                                iter->getRefData().setCount(0);
                            }
                            else
                            {
                                int original = iter->getRefData().getCount();
                                iter->getRefData().setCount(1);
                                MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
                                iter->getRefData().setCount(original - 1);
                            }

                            break;
                        }
                    }
                }
コード例 #22
0
ファイル: enchanting.cpp プロジェクト: IanPAOConnor/openmw
    void Enchanting::payForEnchantment() const
    {
        MWWorld::Ptr gold;

        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
        MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);

        for (MWWorld::ContainerStoreIterator it = store.begin();
                it != store.end(); ++it)
        {
            if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
            {
                gold = *it;
            }
        }

        gold.getRefData().setCount(gold.getRefData().getCount() - getEnchantPrice());
    }
コード例 #23
0
ファイル: containerextensions.cpp プロジェクト: 4DA/openmw
                virtual void execute(Interpreter::Runtime &runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
                    for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
                    {
                        MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
                        if (it != invStore.end() && Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item))
                        {
                            runtime.push(1);
                            return;
                        }
                    }
                    runtime.push(0);
                }
コード例 #24
0
ファイル: containerextensions.cpp プロジェクト: 4DA/openmw
                virtual void execute(Interpreter::Runtime &runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
                    MWWorld::ContainerStoreIterator it = invStore.begin();
                    for (; it != invStore.end(); ++it)
                    {
                        if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item))
                            break;
                    }
                    if (it == invStore.end())
                        throw std::runtime_error("Item to equip not found");

                    MWWorld::ActionEquip action (*it);
                    action.execute(ptr);
                }
コード例 #25
0
ファイル: containerextensions.cpp プロジェクト: 4DA/openmw
                virtual void execute(Interpreter::Runtime &runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);
      
		    const std::string &name = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
                    for (MWWorld::ContainerStoreIterator it = invStore.begin(MWWorld::ContainerStore::Type_Miscellaneous);
                         it != invStore.end(); ++it)
                    {

                        if (Misc::StringUtils::ciEqual(it->getCellRef().mSoul, name))
                        {
                            runtime.push(1);
                            return;
                        }
                    }
                    runtime.push(0);
                }
コード例 #26
0
ファイル: containerextensions.cpp プロジェクト: 0xmono/openmw
                virtual void execute(Interpreter::Runtime &runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr);
                    MWWorld::ContainerStoreIterator it = invStore.begin();
                    for (; it != invStore.end(); ++it)
                    {
                        if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
                            break;
                    }
                    if (it == invStore.end())
                        throw std::runtime_error("Item to equip not found");

                    MWWorld::ActionEquip action (*it);
                    action.execute(ptr);

                    if (ptr.getRefData().getHandle() == "player" && !ptr.getClass().getScript(ptr).empty())
                        ptr.getRefData().getLocals().setVarByInt(ptr.getClass().getScript(ptr), "onpcequip", 1);
                }
コード例 #27
0
void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
{
    int toRemove = count;

    for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
    {
        MWWorld::ContainerStore& store = MWWorld::Class::get(*source).getContainerStore(*source);

        for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
        {
            // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
            if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase)))
            {
                int refCount = it->getRefData().getCount();
                it->getRefData().setCount(std::max(0, refCount - toRemove));
                toRemove -= refCount;
                if (toRemove <= 0)
                    return;
            }
        }
    }
    throw std::runtime_error("Not enough items to remove could be found");
}
コード例 #28
0
ファイル: miscextensions.cpp プロジェクト: UIKit0/openmw
                virtual void execute (Interpreter::Runtime& runtime)
                {

                    MWWorld::Ptr ptr = R()(runtime);

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

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

                    if (amount<0)
                        throw std::runtime_error ("amount must be non-negative");

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

                    MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);


                    for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
                    {
                        if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item))
                        {
                            if(iter->getRefData().getCount() <= amount)
                            {
                                MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
                                iter->getRefData().setCount(0);
                            }
                            else
                            {
                                int original = iter->getRefData().getCount();
                                iter->getRefData().setCount(amount);
                                MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
                                iter->getRefData().setCount(original - amount);
                            }

                            break;
                        }
                    }
                }
コード例 #29
0
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, int count)
{
    int type = getType(ptr);

    const MWWorld::ESMStore &esmStore =
        MWBase::Environment::get().getWorld()->getStore();

    // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
    // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
    if(ptr.getClass().isGold(ptr))
    {
        int realCount = count * ptr.getClass().getValue(ptr);

        for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
        {
            if (Misc::StringUtils::ciEqual((*iter).getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId))
            {
                iter->getRefData().setCount(iter->getRefData().getCount() + realCount);
                flagAsModified();
                return iter;
            }
        }

        MWWorld::ManualRef ref(esmStore, MWWorld::ContainerStore::sGoldId, realCount);
        return addNewStack(ref.getPtr(), realCount);
    }

    // determine whether to stack or not
    for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
    {
        if (stacks(*iter, ptr))
        {
            // stack
            iter->getRefData().setCount( iter->getRefData().getCount() + count );

            flagAsModified();
            return iter;
        }
    }
    // if we got here, this means no stacking
    return addNewStack(ptr, count);
}
コード例 #30
0
ファイル: miscextensions.cpp プロジェクト: UIKit0/openmw
                virtual void execute (Interpreter::Runtime& runtime)
                {

                    MWWorld::Ptr ptr = R()(runtime);

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

                    MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);


                    for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
                    {
                        if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul))
                        {
                            if (iter->getRefData().getCount() <= 1)
                                iter->getRefData().setCount (0);
                            else
                                iter->getRefData().setCount (iter->getRefData().getCount() - 1);
                            break;
                        }
                    }
                }