mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 01:39:52 +03:00
580 lines
21 KiB
Diff
580 lines
21 KiB
Diff
--- ../src-base/minecraft/net/minecraft/item/ItemStack.java
|
|
+++ ../src-work/minecraft/net/minecraft/item/ItemStack.java
|
|
@@ -5,11 +5,17 @@
|
|
import com.google.common.collect.Multimap;
|
|
import java.text.DecimalFormat;
|
|
import java.util.List;
|
|
+import java.util.Map;
|
|
import java.util.Random;
|
|
import java.util.Map.Entry;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.advancements.CriteriaTriggers;
|
|
import net.minecraft.block.Block;
|
|
+import net.minecraft.block.BlockContainer;
|
|
+import net.minecraft.block.BlockJukebox;
|
|
+import net.minecraft.block.BlockMushroom;
|
|
+import net.minecraft.block.BlockSapling;
|
|
+import net.minecraft.block.SoundType;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.client.util.ITooltipFlag;
|
|
import net.minecraft.enchantment.Enchantment;
|
|
@@ -30,12 +36,16 @@
|
|
import net.minecraft.nbt.NBTBase;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTTagList;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.stats.StatList;
|
|
+import net.minecraft.tileentity.TileEntity;
|
|
+import net.minecraft.tileentity.TileEntitySkull;
|
|
import net.minecraft.util.ActionResult;
|
|
import net.minecraft.util.EnumActionResult;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.EnumHand;
|
|
import net.minecraft.util.ResourceLocation;
|
|
+import net.minecraft.util.SoundCategory;
|
|
import net.minecraft.util.datafix.DataFixer;
|
|
import net.minecraft.util.datafix.FixTypes;
|
|
import net.minecraft.util.datafix.walkers.BlockEntityTag;
|
|
@@ -49,14 +59,21 @@
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.fml.relauncher.Side;
|
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.TreeType;
|
|
+import org.bukkit.block.BlockState;
|
|
+import org.bukkit.craftbukkit.block.CraftBlockState;
|
|
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
|
+import org.bukkit.entity.Player;
|
|
+import org.bukkit.event.world.StructureGrowEvent;
|
|
|
|
-public final class ItemStack
|
|
+public final class ItemStack implements net.minecraftforge.common.capabilities.ICapabilitySerializable<NBTTagCompound>
|
|
{
|
|
public static final ItemStack EMPTY = new ItemStack((Item)null);
|
|
public static final DecimalFormat DECIMALFORMAT = new DecimalFormat("#.##");
|
|
private int stackSize;
|
|
private int animationsToGo;
|
|
- private final Item item;
|
|
+ public Item item; // CatServer - private -> public
|
|
private NBTTagCompound stackTagCompound;
|
|
private boolean isEmpty;
|
|
int itemDamage;
|
|
@@ -66,6 +83,10 @@
|
|
private Block canPlaceOnCacheBlock;
|
|
private boolean canPlaceOnCacheResult;
|
|
|
|
+ private net.minecraftforge.registries.IRegistryDelegate<Item> delegate;
|
|
+ public net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; // CatServer - private -> public
|
|
+ private NBTTagCompound capNBT;
|
|
+
|
|
public ItemStack(Block blockIn)
|
|
{
|
|
this(blockIn, 1);
|
|
@@ -91,8 +112,10 @@
|
|
this(itemIn, amount, 0);
|
|
}
|
|
|
|
- public ItemStack(Item itemIn, int amount, int meta)
|
|
+ public ItemStack(Item itemIn, int amount, int meta){ this(itemIn, amount, meta, null); }
|
|
+ public ItemStack(Item itemIn, int amount, int meta, @Nullable NBTTagCompound capNBT)
|
|
{
|
|
+ this.capNBT = capNBT;
|
|
this.item = itemIn;
|
|
this.itemDamage = meta;
|
|
this.stackSize = amount;
|
|
@@ -103,8 +126,20 @@
|
|
}
|
|
|
|
this.updateEmptyState();
|
|
+ this.forgeInit();
|
|
}
|
|
|
|
+ // CatServer - Add constructor for craftbukkit
|
|
+ public ItemStack(Item itemIn, int amount, int meta, boolean convert)
|
|
+ {
|
|
+ this.item = itemIn;
|
|
+ this.itemDamage = meta;
|
|
+ this.stackSize = amount;
|
|
+
|
|
+ this.updateEmptyState();
|
|
+ this.forgeInit();
|
|
+ }
|
|
+
|
|
private void updateEmptyState()
|
|
{
|
|
this.isEmpty = this.isEmpty();
|
|
@@ -112,44 +147,38 @@
|
|
|
|
public ItemStack(NBTTagCompound compound)
|
|
{
|
|
- this.item = Item.getByNameOrId(compound.getString("id"));
|
|
+ this.load(compound);
|
|
+
|
|
+ this.updateEmptyState();
|
|
+ this.forgeInit();
|
|
+ }
|
|
+
|
|
+ public void load(NBTTagCompound compound)
|
|
+ {
|
|
+ this.capNBT = compound.hasKey("ForgeCaps") ? compound.getCompoundTag("ForgeCaps") : null;
|
|
+ this.item = compound.hasKey("id", 8) ? Item.getByNameOrId(compound.getString("id")) : Items.AIR; //Forge fix tons of NumberFormatExceptions that are caused by deserializing EMPTY ItemStacks.
|
|
this.stackSize = compound.getByte("Count");
|
|
- this.itemDamage = Math.max(0, compound.getShort("Damage"));
|
|
+ // CraftBukkit start - Route through setData for filtering
|
|
+ // this.itemDamage = Math.max(0, compound.getShort("Damage"));
|
|
+ this.setItemDamage(compound.getShort("Damage"));
|
|
|
|
if (compound.hasKey("tag", 10))
|
|
{
|
|
- this.stackTagCompound = compound.getCompoundTag("tag");
|
|
+ // CraftBukkit start - make defensive copy as this data may be coming from the save thread
|
|
+ // this.stackTagCompound = compound.getCompoundTag("tag");
|
|
+ this.stackTagCompound = compound.getCompoundTag("tag").copy();
|
|
|
|
if (this.item != null)
|
|
{
|
|
- this.item.updateItemStackNBT(compound);
|
|
+ // this.item.updateItemStackNBT(compound);
|
|
+ this.item.updateItemStackNBT(this.stackTagCompound);
|
|
}
|
|
}
|
|
-
|
|
- this.updateEmptyState();
|
|
}
|
|
|
|
public boolean isEmpty()
|
|
{
|
|
- if (this == EMPTY)
|
|
- {
|
|
- return true;
|
|
- }
|
|
- else if (this.item != null && this.item != Item.getItemFromBlock(Blocks.AIR))
|
|
- {
|
|
- if (this.stackSize <= 0)
|
|
- {
|
|
- return true;
|
|
- }
|
|
- else
|
|
- {
|
|
- return this.itemDamage < -32768 || this.itemDamage > 65535;
|
|
- }
|
|
- }
|
|
- else
|
|
- {
|
|
- return true;
|
|
- }
|
|
+ return this == EMPTY || this.getItemRaw() == null || this.getItemRaw() == Items.AIR || this.stackSize <= 0 || this.itemDamage < -32768 || this.itemDamage > 65535; // Paper
|
|
}
|
|
|
|
public static void registerFixes(DataFixer fixer)
|
|
@@ -169,11 +198,12 @@
|
|
|
|
public Item getItem()
|
|
{
|
|
- return this.isEmpty ? Item.getItemFromBlock(Blocks.AIR) : this.item;
|
|
+ return this.isEmpty || this.delegate == null ? Items.AIR : this.delegate.get();
|
|
}
|
|
|
|
public EnumActionResult onItemUse(EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ)
|
|
{
|
|
+ if (!worldIn.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(this, playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand);
|
|
EnumActionResult enumactionresult = this.getItem().onItemUse(playerIn, worldIn, pos, hand, side, hitX, hitY, hitZ);
|
|
|
|
if (enumactionresult == EnumActionResult.SUCCESS)
|
|
@@ -184,6 +214,19 @@
|
|
return enumactionresult;
|
|
}
|
|
|
|
+ public EnumActionResult onItemUseFirst(EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ)
|
|
+ {
|
|
+ // copy of onitemuse but for onitemusefirst
|
|
+ EnumActionResult enumactionresult = this.getItem().onItemUseFirst(playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand);
|
|
+
|
|
+ if (enumactionresult == EnumActionResult.SUCCESS)
|
|
+ {
|
|
+ playerIn.addStat(StatList.getObjectUseStats(this.item));
|
|
+ }
|
|
+
|
|
+ return enumactionresult;
|
|
+ }
|
|
+
|
|
public float getDestroySpeed(IBlockState blockIn)
|
|
{
|
|
return this.getItem().getDestroySpeed(this, blockIn);
|
|
@@ -208,15 +251,22 @@
|
|
|
|
if (this.stackTagCompound != null)
|
|
{
|
|
- nbt.setTag("tag", this.stackTagCompound);
|
|
+ // nbt.setTag("tag", this.stackTagCompound);
|
|
+ nbt.setTag("tag", this.stackTagCompound.copy()); // CraftBukkit - make defensive copy, data is going to another thread
|
|
}
|
|
|
|
+ if (this.capabilities != null)
|
|
+ {
|
|
+ NBTTagCompound cnbt = this.capabilities.serializeNBT();
|
|
+ if (!cnbt.hasNoTags()) nbt.setTag("ForgeCaps", cnbt);
|
|
+ }
|
|
+
|
|
return nbt;
|
|
}
|
|
|
|
public int getMaxStackSize()
|
|
{
|
|
- return this.getItem().getItemStackLimit();
|
|
+ return this.getItem().getItemStackLimit(this);
|
|
}
|
|
|
|
public boolean isStackable()
|
|
@@ -230,7 +280,7 @@
|
|
{
|
|
return false;
|
|
}
|
|
- else if (this.item.getMaxDamage() <= 0)
|
|
+ else if (this.item.getMaxDamage(this) <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
@@ -247,32 +297,48 @@
|
|
|
|
public boolean isItemDamaged()
|
|
{
|
|
- return this.isItemStackDamageable() && this.itemDamage > 0;
|
|
+ return this.isItemStackDamageable() && getItem().isDamaged(this);
|
|
}
|
|
|
|
public int getItemDamage()
|
|
{
|
|
- return this.itemDamage;
|
|
+ return getItem().getDamage(this);
|
|
}
|
|
|
|
public int getMetadata()
|
|
{
|
|
- return this.itemDamage;
|
|
+ return getItem().getMetadata(this);
|
|
}
|
|
|
|
public void setItemDamage(int meta)
|
|
{
|
|
- this.itemDamage = meta;
|
|
+ // CraftBukkit start - Filter out data for items that shouldn't have it
|
|
+ // The crafting system uses this value for a special purpose so we have to allow it
|
|
+ if (meta == 32767) {
|
|
+ getItem().setDamage(this, meta);
|
|
+ return;
|
|
+ }
|
|
|
|
- if (this.itemDamage < 0)
|
|
- {
|
|
- this.itemDamage = 0;
|
|
+ // Is this a block?
|
|
+ if (this.getItem() instanceof ItemBlock && ((ItemBlock)this.getItem()).getBlock() != Blocks.AIR) { // CatServer - Replace the Spigot way because it is not suitable for Forge
|
|
+ // If vanilla doesn't use data on it don't allow any
|
|
+ if (!(this.getHasSubtypes() || this.getItem().isDamageable())) {
|
|
+ meta = 0;
|
|
+ }
|
|
}
|
|
+
|
|
+ // Filter invalid plant data
|
|
+ if (CraftMagicNumbers.getBlock(CraftMagicNumbers.getId(this.getItem())) == Blocks.DOUBLE_PLANT && (meta > 5 || meta < 0)) {
|
|
+ meta = 0;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
+ getItem().setDamage(this, meta);
|
|
}
|
|
|
|
public int getMaxDamage()
|
|
{
|
|
- return this.getItem().getMaxDamage();
|
|
+ return this.getItem().getMaxDamage(this);
|
|
}
|
|
|
|
public boolean attemptDamageItem(int amount, Random rand, @Nullable EntityPlayerMP damager)
|
|
@@ -297,7 +363,18 @@
|
|
}
|
|
|
|
amount -= j;
|
|
-
|
|
+ // Spigot start
|
|
+ if (damager != null) {
|
|
+ org.bukkit.craftbukkit.inventory.CraftItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this);
|
|
+ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent(damager.getBukkitEntity(), item, amount);
|
|
+ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event);
|
|
+ if (amount != event.getDamage() || event.isCancelled()) {
|
|
+ event.getPlayer().updateInventory();
|
|
+ }
|
|
+ if (event.isCancelled()) return false;
|
|
+ amount = event.getDamage();
|
|
+ }
|
|
+ // Spigot end
|
|
if (amount <= 0)
|
|
{
|
|
return false;
|
|
@@ -309,8 +386,8 @@
|
|
CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(damager, this, this.itemDamage + amount);
|
|
}
|
|
|
|
- this.itemDamage += amount;
|
|
- return this.itemDamage > this.getMaxDamage();
|
|
+ setItemDamage(getItemDamage() + amount); //Redirect through Item's callback if applicable.
|
|
+ return getItemDamage() > getMaxDamage();
|
|
}
|
|
}
|
|
|
|
@@ -323,6 +400,11 @@
|
|
if (this.attemptDamageItem(amount, entityIn.getRNG(), entityIn instanceof EntityPlayerMP ? (EntityPlayerMP)entityIn : null))
|
|
{
|
|
entityIn.renderBrokenItemStack(this);
|
|
+ // CraftBukkit start - Check for item breaking
|
|
+ if (this.stackSize == 1 && entityIn instanceof EntityPlayer) {
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityPlayer) entityIn, this);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
this.shrink(1);
|
|
|
|
if (entityIn instanceof EntityPlayer)
|
|
@@ -359,7 +441,7 @@
|
|
|
|
public boolean canHarvestBlock(IBlockState blockIn)
|
|
{
|
|
- return this.getItem().canHarvestBlock(blockIn);
|
|
+ return this.getItem().canHarvestBlock(blockIn, this);
|
|
}
|
|
|
|
public boolean interactWithEntity(EntityPlayer playerIn, EntityLivingBase entityIn, EnumHand hand)
|
|
@@ -369,7 +451,7 @@
|
|
|
|
public ItemStack copy()
|
|
{
|
|
- ItemStack itemstack = new ItemStack(this.item, this.stackSize, this.itemDamage);
|
|
+ ItemStack itemstack = new ItemStack(this.item, this.stackSize, this.itemDamage, this.capabilities != null ? this.capabilities.serializeNBT() : null);
|
|
itemstack.setAnimationsToGo(this.getAnimationsToGo());
|
|
|
|
if (this.stackTagCompound != null)
|
|
@@ -394,7 +476,7 @@
|
|
}
|
|
else
|
|
{
|
|
- return stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound);
|
|
+ return (stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound)) && stackA.areCapsCompatible(stackB);
|
|
}
|
|
}
|
|
else
|
|
@@ -435,7 +517,7 @@
|
|
}
|
|
else
|
|
{
|
|
- return this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound);
|
|
+ return (this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound)) && this.areCapsCompatible(other);
|
|
}
|
|
}
|
|
|
|
@@ -862,6 +944,7 @@
|
|
}
|
|
}
|
|
|
|
+ net.minecraftforge.event.ForgeEventFactory.onItemTooltip(this, playerIn, list, advanced);
|
|
return list;
|
|
}
|
|
|
|
@@ -871,6 +954,7 @@
|
|
return this.getItem().hasEffect(this);
|
|
}
|
|
|
|
+ @Deprecated // use Forge version on item
|
|
public EnumRarity getRarity()
|
|
{
|
|
return this.getItem().getRarity(this);
|
|
@@ -957,6 +1041,15 @@
|
|
|
|
public void setRepairCost(int cost)
|
|
{
|
|
+ // CraftBukkit start - remove RepairCost tag when 0 (SPIGOT-3945)
|
|
+ if (cost == 0) {
|
|
+ if (this.hasTagCompound()) {
|
|
+ this.stackTagCompound.removeTag("RepairCost");
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
if (!this.hasTagCompound())
|
|
{
|
|
this.stackTagCompound = new NBTTagCompound();
|
|
@@ -987,7 +1080,7 @@
|
|
}
|
|
else
|
|
{
|
|
- multimap = this.getItem().getItemAttributeModifiers(equipmentSlot);
|
|
+ multimap = this.getItem().getAttributeModifiers(equipmentSlot, this);
|
|
}
|
|
|
|
return multimap;
|
|
@@ -1017,6 +1110,14 @@
|
|
nbttaglist.appendTag(nbttagcompound);
|
|
}
|
|
|
|
+ @Deprecated
|
|
+ public void setItem(Item item) {
|
|
+ this.item = item;
|
|
+ // Update delegate as well
|
|
+ this.delegate = item.delegate;
|
|
+ this.setItemDamage(this.getItemDamage()); // CraftBukkit - Set data again to ensure it is filtered properly
|
|
+ }
|
|
+
|
|
public ITextComponent getTextComponent()
|
|
{
|
|
TextComponentString textcomponentstring = new TextComponentString(this.getDisplayName());
|
|
@@ -1032,7 +1133,7 @@
|
|
{
|
|
NBTTagCompound nbttagcompound = this.writeToNBT(new NBTTagCompound());
|
|
itextcomponent.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponentString(nbttagcompound.toString())));
|
|
- itextcomponent.getStyle().setColor(this.getRarity().rarityColor);
|
|
+ itextcomponent.getStyle().setColor(this.getItem().getForgeRarity(this).getColor());
|
|
}
|
|
|
|
return itextcomponent;
|
|
@@ -1130,4 +1231,140 @@
|
|
{
|
|
this.grow(-quantity);
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, @Nullable net.minecraft.util.EnumFacing facing)
|
|
+ {
|
|
+ return this.isEmpty || this.capabilities == null ? false : this.capabilities.hasCapability(capability, facing);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ @Nullable
|
|
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing)
|
|
+ {
|
|
+ return this.isEmpty || this.capabilities == null ? null : this.capabilities.getCapability(capability, facing);
|
|
+ }
|
|
+
|
|
+ public void deserializeNBT(NBTTagCompound nbt)
|
|
+ {
|
|
+ // TODO do this better while respecting new rules
|
|
+ final ItemStack itemStack = new ItemStack(nbt);
|
|
+ this.stackTagCompound = itemStack.stackTagCompound;
|
|
+ this.capNBT = itemStack.capNBT;
|
|
+ }
|
|
+
|
|
+ public NBTTagCompound serializeNBT()
|
|
+ {
|
|
+ NBTTagCompound ret = new NBTTagCompound();
|
|
+ this.writeToNBT(ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ public boolean areCapsCompatible(ItemStack other)
|
|
+ {
|
|
+ if (this.capabilities == null)
|
|
+ {
|
|
+ if (other.capabilities == null)
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return other.capabilities.areCompatible(null);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return this.capabilities.areCompatible(other.capabilities);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Set up forge's ItemStack additions.
|
|
+ */
|
|
+ private void forgeInit()
|
|
+ {
|
|
+ Item item = getItemRaw();
|
|
+ if (item != null)
|
|
+ {
|
|
+ this.delegate = item.delegate;
|
|
+ net.minecraftforge.common.capabilities.ICapabilityProvider provider = item.initCapabilities(this, this.capNBT);
|
|
+ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this, provider);
|
|
+ if (this.capNBT != null && this.capabilities != null) this.capabilities.deserializeNBT(this.capNBT);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Internal call to get the actual item, not the delegate.
|
|
+ * In all other methods, FML replaces calls to this.item with the item delegate.
|
|
+ */
|
|
+ @Nullable
|
|
+ private Item getItemRaw()
|
|
+ {
|
|
+ return this.item;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Modeled after ItemStack.areItemStacksEqual
|
|
+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities.
|
|
+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag.
|
|
+ */
|
|
+ public static boolean areItemStacksEqualUsingNBTShareTag(ItemStack stackA, ItemStack stackB)
|
|
+ {
|
|
+ if (stackA.isEmpty())
|
|
+ return stackB.isEmpty();
|
|
+ else
|
|
+ return !stackB.isEmpty() && stackA.isItemStackEqualUsingNBTShareTag(stackB);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Modeled after ItemStack.isItemStackEqual
|
|
+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities.
|
|
+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag.
|
|
+ */
|
|
+ private boolean isItemStackEqualUsingNBTShareTag(ItemStack other)
|
|
+ {
|
|
+ return this.stackSize == other.stackSize && this.getItem() == other.getItem() && this.itemDamage == other.itemDamage && areItemStackShareTagsEqual(this, other);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Modeled after ItemStack.areItemStackTagsEqual
|
|
+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities.
|
|
+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag.
|
|
+ */
|
|
+ public static boolean areItemStackShareTagsEqual(ItemStack stackA, ItemStack stackB)
|
|
+ {
|
|
+ NBTTagCompound shareTagA = stackA.getItem().getNBTShareTag(stackA);
|
|
+ NBTTagCompound shareTagB = stackB.getItem().getNBTShareTag(stackB);
|
|
+ if (shareTagA == null)
|
|
+ return shareTagB == null;
|
|
+ else
|
|
+ return shareTagB != null && shareTagA.equals(shareTagB);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ *
|
|
+ * Should this item, when held, allow sneak-clicks to pass through to the underlying block?
|
|
+ *
|
|
+ * @param world The world
|
|
+ * @param pos Block position in world
|
|
+ * @param player The Player that is wielding the item
|
|
+ * @return
|
|
+ */
|
|
+ public boolean doesSneakBypassUse(net.minecraft.world.IBlockAccess world, BlockPos pos, EntityPlayer player)
|
|
+ {
|
|
+ return this.isEmpty() || this.getItem().doesSneakBypassUse(this, world, pos, player);
|
|
+ }
|
|
+
|
|
+ // Spigot start
|
|
+ public static boolean fastMatches(ItemStack itemstack, ItemStack itemstack1) {
|
|
+ if (itemstack == null && itemstack1 == null) {
|
|
+ return true;
|
|
+ }
|
|
+ if (itemstack != null && itemstack1 != null) {
|
|
+ return itemstack.stackSize == itemstack1.stackSize && itemstack.item == itemstack1.item && itemstack.itemDamage == itemstack1.itemDamage;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Spigot end
|
|
}
|