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; }
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); }
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); } } } }
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; } }
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; } } }
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; }
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); }
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); } } }
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; }
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; } } }
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); }
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; }
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; }
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; }
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; } } }
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"); }
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); }
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 RemoveItem must be non-negative"); // no-op if (count == 0) return; MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr); std::string itemName = ""; // originalCount holds the total number of items to remove, count holds the remaining number of items to remove Interpreter::Type_Integer originalCount = count; for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end() && count; ++iter) { if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) { itemName = MWWorld::Class::get(*iter).getName(*iter); if (iter->getRefData().getCount()<=count) { count -= iter->getRefData().getCount(); iter->getRefData().setCount (0); } else { iter->getRefData().setCount (iter->getRefData().getCount()-count); count = 0; } } } // 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 removed from their inventory std::string msgBox; int numRemoved = (originalCount - count); if(numRemoved > 1) { msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage63}"); msgBox = boost::str (boost::format(msgBox) % numRemoved % itemName); } else { msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage62}"); msgBox = boost::str (boost::format(msgBox) % itemName); } if (numRemoved > 0) MWBase::Environment::get().getWindowManager()->messageBox(msgBox); } }
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); switch (select.getFunction()) { case SelectWrapper::Function_Journal: return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); case SelectWrapper::Function_Item: { MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); int sum = 0; std::string name = select.getName(); for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) if (Misc::StringUtils::lowerCase(iter->getCellRef().mRefID) == name) sum += iter->getRefData().getCount(); return sum; } case SelectWrapper::Function_Dead: return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); case SelectWrapper::Function_Choice: return mChoice; case SelectWrapper::Function_AiSetting: return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument()); case SelectWrapper::Function_PcAttribute: return MWWorld::Class::get (player).getCreatureStats (player). getAttribute (select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: return static_cast<int> (MWWorld::Class::get (player). getNpcStats (player).getSkill (select.getArgument()).getModified()); case SelectWrapper::Function_FriendlyHit: { int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits(); return hits>4 ? 4 : hits; } case SelectWrapper::Function_PcLevel: return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); case SelectWrapper::Function_PcGender: return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1; case SelectWrapper::Function_PcClothingModifier: { MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player); int value = 0; for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition { MWWorld::ContainerStoreIterator slot = store.getSlot (i); if (slot!=store.end()) value += MWWorld::Class::get (*slot).getValue (*slot); } return value; } case SelectWrapper::Function_PcCrimeLevel: return MWWorld::Class::get (player).getNpcStats (player).getBounty(); case SelectWrapper::Function_RankRequirement: { if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) return 0; std::string faction = MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; int rank = getFactionRank (player, faction); if (rank>=9) return 0; // max rank int result = 0; if (hasFactionRankSkillRequirements (player, faction, rank+1)) result += 1; if (hasFactionRankReputationRequirements (player, faction, rank+1)) result += 2; return result; } case SelectWrapper::Function_Level: return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); case SelectWrapper::Function_PCReputation: return MWWorld::Class::get (player).getNpcStats (player).getReputation(); case SelectWrapper::Function_Weather: return MWBase::Environment::get().getWorld()->getCurrentWeather(); case SelectWrapper::Function_Reputation: return MWWorld::Class::get (mActor).getNpcStats (mActor).getReputation(); case SelectWrapper::Function_FactionRankDiff: { if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) return 0; std::pair<std::string, int> faction = *MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin(); int rank = getFactionRank (player, faction.first); return rank-faction.second; } case SelectWrapper::Function_WerewolfKills: return MWWorld::Class::get (player).getNpcStats (player).getWerewolfKills(); case SelectWrapper::Function_RankLow: case SelectWrapper::Function_RankHigh: { bool low = select.getFunction()==SelectWrapper::Function_RankLow; if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) return 0; std::string factionId = MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; int value = 0; const ESM::Faction& faction = *MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId); MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player); for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin()); iter!=faction.mReactions.end(); ++iter) if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end()) if (low ? iter->mReaction<value : iter->mReaction>value) value = iter->mReaction; return value; } default: throw std::runtime_error ("unknown integer select function"); } }