mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Ignore broken items when search for replacement (bug #4453)
This commit is contained in:
		
							parent
							
								
									1ba0317905
								
							
						
					
					
						commit
						61c968d550
					
				
					 5 changed files with 85 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -81,6 +81,47 @@ namespace MWGui
 | 
			
		|||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        key->clearUserStrings();
 | 
			
		||||
| 
						 | 
				
			
			@ -122,13 +163,11 @@ namespace MWGui
 | 
			
		|||
        assert(index != -1);
 | 
			
		||||
        mSelectedIndex = index;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
        // open assign dialog
 | 
			
		||||
        if (!mAssignDialog)
 | 
			
		||||
            mAssignDialog = new QuickKeysMenuAssign(this);
 | 
			
		||||
        mAssignDialog->setVisible (true);
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,21 +335,16 @@ namespace MWGui
 | 
			
		|||
        if (type == Type_Item || type == Type_MagicItem)
 | 
			
		||||
        {
 | 
			
		||||
            MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
 | 
			
		||||
            // make sure the item is available
 | 
			
		||||
            if (item.getRefData ().getCount() < 1)
 | 
			
		||||
            // 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();
 | 
			
		||||
 | 
			
		||||
                for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
 | 
			
		||||
                    {
 | 
			
		||||
                        item = *it;
 | 
			
		||||
                item = store.findReplacement(id);
 | 
			
		||||
                button->setUserData(MWWorld::Ptr(item));
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (item.getRefData().getCount() < 1)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -498,6 +532,9 @@ namespace MWGui
 | 
			
		|||
        ESM::QuickKeys keys;
 | 
			
		||||
        keys.load(reader);
 | 
			
		||||
 | 
			
		||||
        MWWorld::Ptr player = MWMechanics::getPlayer();
 | 
			
		||||
        MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
 | 
			
		||||
 | 
			
		||||
        int i=0;
 | 
			
		||||
        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:
 | 
			
		||||
            {
 | 
			
		||||
                // Find the item by id
 | 
			
		||||
                MWWorld::Ptr player = MWMechanics::getPlayer();
 | 
			
		||||
                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;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                MWWorld::Ptr item = store.findReplacement(id);
 | 
			
		||||
 | 
			
		||||
                if (item.isEmpty())
 | 
			
		||||
                    unassign(button, i);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ namespace MWGui
 | 
			
		|||
        void onAssignMagicItem (MWWorld::Ptr item);
 | 
			
		||||
        void onAssignMagic (const std::string& spellId);
 | 
			
		||||
        void onAssignMagicCancel ();
 | 
			
		||||
        void onOpen();
 | 
			
		||||
 | 
			
		||||
        void activateQuickKey(int index);
 | 
			
		||||
        void updateActivatedQuickKey();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -288,23 +288,9 @@ namespace MWMechanics
 | 
			
		|||
        if (prevItemId.empty())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Find the item 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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Find previous item (or its replacement) by id.
 | 
			
		||||
        // we should equip previous item only if expired bound item was equipped.
 | 
			
		||||
        MWWorld::Ptr item = store.findReplacement(prevItemId);
 | 
			
		||||
        if (item.isEmpty() || !wasEquipped)
 | 
			
		||||
            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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,9 @@ namespace MWWorld
 | 
			
		|||
            ///< This function throws an exception, if ptr does not point to an object, that can be
 | 
			
		||||
            /// 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);
 | 
			
		||||
 | 
			
		||||
            virtual void writeState (ESM::InventoryState& state) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue