Merged pull request #1753

0.6.3
Marc Zinnschlag 7 years ago
commit aea481eacb

@ -81,6 +81,47 @@ namespace MWGui
delete mMagicSelectionDialog; delete mMagicSelectionDialog;
} }
void QuickKeysMenu::onOpen()
{
WindowBase::onOpen();
MWWorld::Ptr player = MWMechanics::getPlayer();
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
// Check if quick keys are still valid
for (int i=0; i<10; ++i)
{
ItemWidget* button = mQuickKeyButtons[i];
int type = mAssigned[i];
switch (type)
{
case Type_Unassigned:
case Type_HandToHand:
case Type_Magic:
break;
case Type_Item:
case Type_MagicItem:
{
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// Make sure the item is available and is not broken
if (item.getRefData().getCount() < 1 ||
(item.getClass().hasItemHealth(item) &&
item.getClass().getItemHealth(item) <= 0))
{
// Try searching for a compatible replacement
std::string id = item.getCellRef().getRefId();
item = store.findReplacement(id);
button->setUserData(MWWorld::Ptr(item));
break;
}
}
}
}
}
void QuickKeysMenu::unassign(ItemWidget* key, int index) void QuickKeysMenu::unassign(ItemWidget* key, int index)
{ {
key->clearUserStrings(); key->clearUserStrings();
@ -122,12 +163,10 @@ namespace MWGui
assert(index != -1); assert(index != -1);
mSelectedIndex = index; mSelectedIndex = index;
{ // open assign dialog
// open assign dialog if (!mAssignDialog)
if (!mAssignDialog) mAssignDialog = new QuickKeysMenuAssign(this);
mAssignDialog = new QuickKeysMenuAssign(this); mAssignDialog->setVisible (true);
mAssignDialog->setVisible (true);
}
} }
void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender) void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender)
@ -296,21 +335,16 @@ namespace MWGui
if (type == Type_Item || type == Type_MagicItem) if (type == Type_Item || type == Type_MagicItem)
{ {
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// make sure the item is available // Make sure the item is available and is not broken
if (item.getRefData ().getCount() < 1) if (item.getRefData().getCount() < 1 ||
(item.getClass().hasItemHealth(item) &&
item.getClass().getItemHealth(item) <= 0))
{ {
// Try searching for a compatible replacement // Try searching for a compatible replacement
std::string id = item.getCellRef().getRefId(); std::string id = item.getCellRef().getRefId();
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) item = store.findReplacement(id);
{ button->setUserData(MWWorld::Ptr(item));
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{
item = *it;
button->setUserData(MWWorld::Ptr(item));
break;
}
}
if (item.getRefData().getCount() < 1) if (item.getRefData().getCount() < 1)
{ {
@ -498,6 +532,9 @@ namespace MWGui
ESM::QuickKeys keys; ESM::QuickKeys keys;
keys.load(reader); keys.load(reader);
MWWorld::Ptr player = MWMechanics::getPlayer();
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
int i=0; int i=0;
for (std::vector<ESM::QuickKeys::QuickKey>::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it) for (std::vector<ESM::QuickKeys::QuickKey>::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it)
{ {
@ -519,22 +556,7 @@ namespace MWGui
case Type_MagicItem: case Type_MagicItem:
{ {
// Find the item by id // Find the item by id
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::Ptr item = store.findReplacement(id);
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
MWWorld::Ptr item;
for (MWWorld::ContainerStoreIterator iter = store.begin(); iter != store.end(); ++iter)
{
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id))
{
if (item.isEmpty() ||
// Prefer the stack with the lowest remaining uses
!item.getClass().hasItemHealth(*iter) ||
iter->getClass().getItemHealth(*iter) < item.getClass().getItemHealth(item))
{
item = *iter;
}
}
}
if (item.isEmpty()) if (item.isEmpty())
unassign(button, i); unassign(button, i);

@ -34,6 +34,7 @@ namespace MWGui
void onAssignMagicItem (MWWorld::Ptr item); void onAssignMagicItem (MWWorld::Ptr item);
void onAssignMagic (const std::string& spellId); void onAssignMagic (const std::string& spellId);
void onAssignMagicCancel (); void onAssignMagicCancel ();
void onOpen();
void activateQuickKey(int index); void activateQuickKey(int index);
void updateActivatedQuickKey(); void updateActivatedQuickKey();

@ -288,23 +288,9 @@ namespace MWMechanics
if (prevItemId.empty()) if (prevItemId.empty())
return; return;
// Find the item by id // Find previous item (or its replacement) by id.
MWWorld::Ptr item;
for (MWWorld::ContainerStoreIterator iter = store.begin(); iter != store.end(); ++iter)
{
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), prevItemId))
{
if (item.isEmpty() ||
// Prefer the stack with the lowest remaining uses
!item.getClass().hasItemHealth(*iter) ||
iter->getClass().getItemHealth(*iter) < item.getClass().getItemHealth(item))
{
item = *iter;
}
}
}
// we should equip previous item only if expired bound item was equipped. // we should equip previous item only if expired bound item was equipped.
MWWorld::Ptr item = store.findReplacement(prevItemId);
if (item.isEmpty() || !wasEquipped) if (item.isEmpty() || !wasEquipped)
return; return;

@ -675,6 +675,30 @@ int MWWorld::ContainerStore::getType (const ConstPtr& ptr)
"Object '" + ptr.getCellRef().getRefId() + "' of type " + ptr.getTypeName() + " can not be placed into a container"); "Object '" + ptr.getCellRef().getRefId() + "' of type " + ptr.getTypeName() + " can not be placed into a container");
} }
MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const std::string& id)
{
MWWorld::Ptr item;
int itemHealth = 1;
for (MWWorld::ContainerStoreIterator iter = begin(); iter != end(); ++iter)
{
int iterHealth = iter->getClass().hasItemHealth(*iter) ? iter->getClass().getItemHealth(*iter) : 1;
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id))
{
// Prefer the stack with the lowest remaining uses
// Try to get item with zero durability only if there are no other items found
if (item.isEmpty() ||
(iterHealth > 0 && iterHealth < itemHealth) ||
(itemHealth <= 0 && iterHealth > 0))
{
item = *iter;
itemHealth = iterHealth;
}
}
}
return item;
}
MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id) MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id)
{ {
{ {

@ -198,6 +198,9 @@ namespace MWWorld
///< This function throws an exception, if ptr does not point to an object, that can be ///< This function throws an exception, if ptr does not point to an object, that can be
/// put into a container. /// put into a container.
Ptr findReplacement(const std::string& id);
///< Returns replacement for object with given id. Prefer used items (with low durability left).
Ptr search (const std::string& id); Ptr search (const std::string& id);
virtual void writeState (ESM::InventoryState& state) const; virtual void writeState (ESM::InventoryState& state) const;

Loading…
Cancel
Save