forked from teamnwah/openmw-tes3coop
equipping items works, but only if you have more than one of the item that you're equipping
This commit is contained in:
parent
765881a61d
commit
71de10cb7e
8 changed files with 145 additions and 11 deletions
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue