#include "inventorystore.hpp" #include #include #include "../mwmechanics/npcstats.hpp" #include "class.hpp" void MWWorld::InventoryStore::copySlots (const InventoryStore& store) { // some const-trickery, required because of a flaw in the handling of MW-references and the // resulting workarounds for (std::vector::const_iterator iter ( const_cast (store).mSlots.begin()); iter!=const_cast (store).mSlots.end(); ++iter) { std::size_t distance = std::distance (const_cast (store).begin(), *iter); ContainerStoreIterator slot = begin(); std::advance (slot, distance); mSlots.push_back (slot); } } void MWWorld::InventoryStore::initSlots (TSlots& slots) { for (int i=0; i=static_cast (mSlots.size())) throw std::runtime_error ("slot number out of range"); if (iterator.getContainerStore()!=this) throw std::runtime_error ("attempt to equip an item that is not in the inventory"); if (iterator!=end()) { std::pair, bool> slots = Class::get (*iterator).getEquipmentSlots (*iterator); if (std::find (slots.first.begin(), slots.first.end(), slot)==slots.first.end()) throw std::runtime_error ("invalid slot"); } /// \todo restack item previously in this slot (if required) /// \todo unstack item pointed to by iterator if required) mSlots[slot] = iterator; flagAsModified(); } MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) { if (slot<0 || slot>=static_cast (mSlots.size())) throw std::runtime_error ("slot number out of range"); if (mSlots[slot]==end()) return end(); if (mSlots[slot]->getRefData().getCount()<1) { // object has been deleted mSlots[slot] = end(); return end(); } return mSlots[slot]; } void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats, const Environment& environment) { TSlots slots; initSlots (slots); for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter) { Ptr test = *iter; int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test, environment); std::pair, bool> itemsSlots = MWWorld::Class::get (*iter).getEquipmentSlots (*iter); for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); iter2!=itemsSlots.first.end(); ++iter2) { bool use = false; if (slots.at (*iter2)==end()) use = true; // slot was empty before -> skill all further checks else { Ptr old = *slots.at (*iter2); if (!use) { // check skill int oldSkill = MWWorld::Class::get (old).getEquipmentSkill (old, environment); if (testSkill!=-1 || oldSkill!=-1 || testSkill!=oldSkill) { if (stats.mSkill[oldSkill].getModified()>stats.mSkill[testSkill].getModified()) continue; // rejected, because old item better matched the NPC's skills. if (stats.mSkill[oldSkill].getModified()= MWWorld::Class::get (test).getValue (test)) { continue; } use = true; } } /// \todo unstack, if reqquired (itemsSlots.second) slots[*iter2] = iter; break; } } bool changed = false; for (std::size_t i=0; i