1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-11-04 17:16:20 +00:00

Be less strict in comparing upgrade crafting items

We currently generate the crafting item once when the upgrade is first
created, and cache it for the duration of the game. As the item never
changes throughout the game, and constructing a stack is a little
expensive (we need to fire an event, etc...), the caching is worth
having.

However, some mods may register capabilities after we've constructed our
ItemStack. This means the capability will be present on other items but
not ours, meaning they are not considered equivalent, and thus the item
cannot be equipped.

In order to avoid this, we use compare items using their share-tag, like
Forge's IngredientNBT. This means the items must still be "mostly" the
same (same enchantements, etc...), but allow differing capabilities.

See NillerMedDild/Enigmatica2Expert#655 for the original bug report -
in this case, Astral Sourcery was registering the capability in init,
but we construct upgrades just before then.
This commit is contained in:
SquidDev 2019-01-19 21:57:21 +00:00
parent 443e0f8f76
commit 0ce67afcc1
3 changed files with 23 additions and 2 deletions

View File

@ -49,7 +49,7 @@ public final class PocketUpgrades
for( IPocketUpgrade upgrade : upgrades.values() ) for( IPocketUpgrade upgrade : upgrades.values() )
{ {
ItemStack craftingStack = upgrade.getCraftingItem(); ItemStack craftingStack = upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) ) if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
{ {
return upgrade; return upgrade;
} }

View File

@ -101,7 +101,7 @@ public final class TurtleUpgrades
for( ITurtleUpgrade upgrade : upgrades.values() ) for( ITurtleUpgrade upgrade : upgrades.values() )
{ {
ItemStack craftingStack = upgrade.getCraftingItem(); ItemStack craftingStack = upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) ) if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
{ {
return upgrade; return upgrade;
} }

View File

@ -38,6 +38,27 @@ public class InventoryUtil
return a == b || ItemHandlerHelper.canItemStacksStack( a, b ); return a == b || ItemHandlerHelper.canItemStacksStack( a, b );
} }
/**
* Determines if two items are "mostly" equivalent. Namely, they have the same item and damage, and identical
* share stacks.
*
* This is largely based on {@link net.minecraftforge.common.crafting.IngredientNBT#apply(ItemStack)}. It is
* sufficient to ensure basic information (such as enchantments) are the same, while not having to worry about
* capabilities.
*
* @param a The first stack to check
* @param b The second stack to check
* @return If these items are largely the same.
*/
public static boolean areItemsSimilar( @Nonnull ItemStack a, @Nonnull ItemStack b )
{
if( a == b ) return true;
if( a.isEmpty() ) return !b.isEmpty();
return a.getItem() == b.getItem()
&& a.getItemDamage() == b.getItemDamage()
&& ItemStack.areItemStackShareTagsEqual( a, b );
}
@Nonnull @Nonnull
public static ItemStack copyItem( @Nonnull ItemStack a ) public static ItemStack copyItem( @Nonnull ItemStack a )
{ {