forked from teamnwah/openmw-tes3coop
prevent segfalt in QuickKeysMenu when item has been removed from player inventory
added a MWWorld::ContainerStore to hold item copies which are then used to find real items with findReplacement(). (storing the RefId could be a better solution but would probably leave tooltips broken...)
This commit is contained in:
parent
64cc3b3a6a
commit
da4c55d5ad
2 changed files with 80 additions and 74 deletions
|
@ -124,6 +124,13 @@ namespace MWGui
|
||||||
|
|
||||||
void QuickKeysMenu::unassign(ItemWidget* key, int index)
|
void QuickKeysMenu::unassign(ItemWidget* key, int index)
|
||||||
{
|
{
|
||||||
|
// cleanup refrance ItemContainer
|
||||||
|
if( mAssigned[index] == Type_Item || mAssigned[index] == Type_MagicItem)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr refItem = *key->getUserData<MWWorld::Ptr>();
|
||||||
|
mRefItemContainer.remove(refItem.getCellRef().getRefId(), 1, MWMechanics::getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
key->clearUserStrings();
|
key->clearUserStrings();
|
||||||
key->setItem(MWWorld::Ptr());
|
key->setItem(MWWorld::Ptr());
|
||||||
while (key->getChildCount()) // Destroy number label
|
while (key->getChildCount()) // Destroy number label
|
||||||
|
@ -221,9 +228,11 @@ namespace MWGui
|
||||||
|
|
||||||
mAssigned[mSelectedIndex] = Type_Item;
|
mAssigned[mSelectedIndex] = Type_Item;
|
||||||
|
|
||||||
button->setItem(item, ItemWidget::Barter);
|
MWWorld::Ptr itemCopy = *mRefItemContainer.add(item, 1, MWMechanics::getPlayer());
|
||||||
|
|
||||||
|
button->setItem(itemCopy, ItemWidget::Barter);
|
||||||
button->setUserString ("ToolTipType", "ItemPtr");
|
button->setUserString ("ToolTipType", "ItemPtr");
|
||||||
button->setUserData(MWWorld::Ptr(item));
|
button->setUserData(itemCopy);
|
||||||
|
|
||||||
if (mItemSelectionDialog)
|
if (mItemSelectionDialog)
|
||||||
mItemSelectionDialog->setVisible(false);
|
mItemSelectionDialog->setVisible(false);
|
||||||
|
@ -334,51 +343,28 @@ 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 refItem = *button->getUserData<MWWorld::Ptr>();
|
||||||
// Make sure the item is available and is not broken
|
MWWorld::Ptr item = store.findReplacement(refItem.getCellRef().getRefId());
|
||||||
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);
|
// check the item is available and not broken
|
||||||
button->setUserData(MWWorld::Ptr(item));
|
if (!item || item.getRefData().getCount() < 1 ||
|
||||||
|
(item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0))
|
||||||
if (item.getRefData().getCount() < 1)
|
|
||||||
{
|
{
|
||||||
// No replacement was found
|
if (!item || item.getRefData().getCount() < 1)
|
||||||
MWBase::Environment::get().getWindowManager ()->messageBox (
|
{
|
||||||
"#{sQuickMenu5} " + item.getClass().getName(item));
|
// item not in plater inventory found
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox(
|
||||||
|
"#{sQuickMenu5} " + refItem.getClass().getName(refItem));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type_Magic)
|
if (type == Type_Item)
|
||||||
{
|
{
|
||||||
std::string spellId = button->getUserString("Spell");
|
|
||||||
|
|
||||||
// Make sure the player still has this spell
|
|
||||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
|
||||||
MWMechanics::Spells& spells = stats.getSpells();
|
|
||||||
if (!spells.hasSpell(spellId))
|
|
||||||
{
|
|
||||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox (
|
|
||||||
"#{sQuickMenu5} " + spell->mName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
store.setSelectedEnchantItem(store.end());
|
|
||||||
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
|
||||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
|
||||||
}
|
|
||||||
else if (type == Type_Item)
|
|
||||||
{
|
|
||||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
|
||||||
bool isWeapon = item.getTypeName() == typeid(ESM::Weapon).name();
|
bool isWeapon = item.getTypeName() == typeid(ESM::Weapon).name();
|
||||||
bool isTool = item.getTypeName() == typeid(ESM::Probe).name() || item.getTypeName() == typeid(ESM::Lockpick).name();
|
bool isTool = item.getTypeName() == typeid(ESM::Probe).name() ||
|
||||||
|
item.getTypeName() == typeid(ESM::Lockpick).name();
|
||||||
|
|
||||||
// delay weapon switching if player is busy
|
// delay weapon switching if player is busy
|
||||||
if (isDelayNeeded && (isWeapon || isTool))
|
if (isDelayNeeded && (isWeapon || isTool))
|
||||||
|
@ -403,8 +389,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
else if (type == Type_MagicItem)
|
else if (type == Type_MagicItem)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
|
||||||
|
|
||||||
// retrieve ContainerStoreIterator to the item
|
// retrieve ContainerStoreIterator to the item
|
||||||
MWWorld::ContainerStoreIterator it = store.begin();
|
MWWorld::ContainerStoreIterator it = store.begin();
|
||||||
for (; it != store.end(); ++it)
|
for (; it != store.end(); ++it)
|
||||||
|
@ -429,6 +413,25 @@ namespace MWGui
|
||||||
store.setSelectedEnchantItem(it);
|
store.setSelectedEnchantItem(it);
|
||||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (type == Type_Magic)
|
||||||
|
{
|
||||||
|
std::string spellId = button->getUserString("Spell");
|
||||||
|
|
||||||
|
// Make sure the player still has this spell
|
||||||
|
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||||
|
MWMechanics::Spells& spells = stats.getSpells();
|
||||||
|
if (!spells.hasSpell(spellId))
|
||||||
|
{
|
||||||
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox (
|
||||||
|
"#{sQuickMenu5} " + spell->mName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.setSelectedEnchantItem(store.end());
|
||||||
|
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||||
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||||
|
}
|
||||||
else if (type == Type_HandToHand)
|
else if (type == Type_HandToHand)
|
||||||
{
|
{
|
||||||
store.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, player);
|
store.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, player);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define MWGUI_QUICKKEYS_H
|
#define MWGUI_QUICKKEYS_H
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
#include "windowbase.hpp"
|
#include "windowbase.hpp"
|
||||||
|
|
||||||
|
@ -58,6 +59,8 @@ namespace MWGui
|
||||||
MyGUI::EditBox* mInstructionLabel;
|
MyGUI::EditBox* mInstructionLabel;
|
||||||
MyGUI::Button* mOkButton;
|
MyGUI::Button* mOkButton;
|
||||||
|
|
||||||
|
MWWorld::ContainerStore mRefItemContainer;
|
||||||
|
|
||||||
std::vector<ItemWidget*> mQuickKeyButtons;
|
std::vector<ItemWidget*> mQuickKeyButtons;
|
||||||
std::vector<QuickKeyType> mAssigned;
|
std::vector<QuickKeyType> mAssigned;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue