equipping items works, but only if you have more than one of the item that you're equipping

This commit is contained in:
scrawl 2012-05-15 20:33:34 +02:00
parent 765881a61d
commit 71de10cb7e
8 changed files with 145 additions and 11 deletions

View file

@ -81,6 +81,8 @@ void ContainerBase::onSelectedItemImpl(MyGUI::Widget* _sender, int count)
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
_unequipItem(object);
int originalCount = object.getRefData().getCount();
object.getRefData().setCount(count);
mDragAndDrop->mStore.add(object);
@ -90,6 +92,7 @@ void ContainerBase::onSelectedItemImpl(MyGUI::Widget* _sender, int count)
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
mDragAndDrop->mDraggedWidget = mSelectedItem;
static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
getCountString((*mDragAndDrop->mStore.begin()).getRefData().getCount()));
@ -181,9 +184,46 @@ void ContainerBase::drawItems()
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
// filter out the equipped items of categories we don't want
std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
{
std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
if (found != unwantedItems.end())
{
unwantedItems.erase(found);
}
}
// now erase everything that's still in unwantedItems.
for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
it != unwantedItems.end(); ++it)
{
equippedItems.erase(std::find(unwantedItems.begin(), unwantedItems.end(), *it));
}
// and add the items that are left (= have the correct category)
for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
it != equippedItems.end(); ++it)
{
items.push_back( std::make_pair(*it, ItemState_Equipped) );
}
// now add the regular items
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
{
/// \todo sorting
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end())
items.push_back( std::make_pair(*iter, ItemState_Normal) );
}
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
it != items.end(); ++it)
{
index++;
const MWWorld::Ptr* iter = &((*it).first);
if(iter->getRefData().getCount() > 0 && !(onlyMagic && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
{
std::string path = std::string("icons\\");
@ -194,7 +234,22 @@ void ContainerBase::drawItems()
MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
backgroundWidget->setUserString("ToolTipType", "ItemPtr");
backgroundWidget->setUserData(*iter);
backgroundWidget->setImageTexture( isMagic ? "textures\\menu_icon_magic.dds" : "");
std::string backgroundTex = "textures\\menu_icon";
if (isMagic)
backgroundTex += "_magic";
if (it->second == ItemState_Normal)
{
if (!isMagic)
backgroundTex = "";
}
else if (it->second == ItemState_Equipped)
{
backgroundTex += "_equip";
}
backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex);
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel);

View file

@ -63,6 +63,15 @@ namespace MWGui
Filter_Misc = 0x05
};
enum ItemState
{
ItemState_Normal = 0x01,
ItemState_Equipped = 0x02,
// unimplemented
ItemState_Barter = 0x03
};
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
void openContainer(MWWorld::Ptr container);
@ -87,7 +96,10 @@ namespace MWGui
std::string getCountString(const int count);
// to be reimplemented by InventoryWindow
virtual bool isInventory() { return false; }
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
virtual void _unequipItem(MWWorld::Ptr item) { ; }
void drawItems();
};

View file

@ -151,6 +151,8 @@ namespace MWGui
// can't be equipped, try to use instead
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
std::cout << "Item can't be equipped" << std::endl;
// execute action and script
MWBase::Environment::get().getWorld()->executeActionScript(ptr, action);
@ -172,19 +174,31 @@ namespace MWGui
{
// put back in inventory
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
invStore.add(ptr);
// get a ContainerStoreIterator to the item we just re-added into the inventory
MWWorld::ContainerStoreIterator it = invStore.begin();
MWWorld::ContainerStoreIterator nextIt = ++it;
while (nextIt != invStore.end())
MWWorld::ContainerStoreIterator it = invStore.add(ptr);
// retrieve iterator to the item we just re-added (if stacking didn't happen).
// if stacking happened, the iterator was already returned by the add() call
/// \todo this does not work!
if (it == invStore.end())
{
++it;
++nextIt;
std::cout << "stacking didn't happen" << std::endl;
for (MWWorld::ContainerStoreIterator it2 = invStore.begin();
it2 != invStore.end(); ++it2)
{
if (*it2 == ptr)
{
std::cout << "found iterator" << std::endl;
it = it2;
return;
}
}
}
// equip the item in the first available slot
invStore.equip(slots.first.front(), it);
std::cout << "Equipped item in slot " << slots.first.front() << std::endl;
}
drawItems();
@ -197,4 +211,42 @@ namespace MWGui
}
}
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
{
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
std::vector<MWWorld::Ptr> items;
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
if (it != invStore.end())
{
std::cout << "slot " << slot << " is equipped" << std::endl;
items.push_back(*it);
}
else
{
std::cout << "slot " << slot << " is empty " << std::endl;
}
}
return items;
}
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
{
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
if (it != invStore.end() && *it == item)
{
invStore._freeSlot(slot);
return;
}
}
}
}

View file

@ -51,6 +51,8 @@ namespace MWGui
void onPinToggled();
virtual bool isInventory() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual void _unequipItem(MWWorld::Ptr item);
};
}
#endif // Inventory_H

View file

@ -58,7 +58,7 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
return false;
}
void MWWorld::ContainerStore::add (const Ptr& ptr)
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
{
int type = getType(ptr);
@ -71,12 +71,13 @@ void MWWorld::ContainerStore::add (const Ptr& ptr)
iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() );
flagAsModified();
return;
return iter;
}
}
// if we got here, this means no stacking
addImpl(ptr);
return end();
}
void MWWorld::ContainerStore::addImpl (const Ptr& ptr)

View file

@ -66,13 +66,15 @@ namespace MWWorld
ContainerStoreIterator end();
void add (const Ptr& ptr);
ContainerStoreIterator add (const Ptr& ptr);
///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
///
/// \note The item pointed to is not required to exist beyond this function call.
///
/// \attention Do not add items to an existing stack by increasing the count instead of
/// calling this function!
///
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise end() iterator
protected:
void addImpl (const Ptr& ptr);

View file

@ -97,6 +97,13 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
flagAsModified();
}
void MWWorld::InventoryStore::_freeSlot(int slot)
{
mSlots[slot] = end();
flagAsModified();
}
MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
{
if (slot<0 || slot>=static_cast<int> (mSlots.size()))

View file

@ -60,6 +60,9 @@ namespace MWWorld
void equip (int slot, const ContainerStoreIterator& iterator);
///< \note \a iteartor can be an end-iterator
void _freeSlot(int slot);
///< this method is dangerous, as it doesn't do re-stacking items - you probably want to use equip()
ContainerStoreIterator getSlot (int slot);
void autoEquip (const MWMechanics::NpcStats& stats);