ForgePatch/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandl...

193 lines
6.6 KiB
Java

/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.items;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import java.lang.ref.WeakReference;
import com.google.common.base.Objects;
import javax.annotation.Nonnull;
public class VanillaDoubleChestItemHandler extends WeakReference<TileEntityChest> implements IItemHandlerModifiable
{
// Dummy cache value to signify that we have checked and definitely found no adjacent chests
public static final VanillaDoubleChestItemHandler NO_ADJACENT_CHESTS_INSTANCE = new VanillaDoubleChestItemHandler(null, null, false);
private final boolean mainChestIsUpper;
private final TileEntityChest mainChest;
private final int hashCode;
public VanillaDoubleChestItemHandler(TileEntityChest mainChest, TileEntityChest other, boolean mainChestIsUpper)
{
super(other);
this.mainChest = mainChest;
this.mainChestIsUpper = mainChestIsUpper;
hashCode = Objects.hashCode(mainChestIsUpper ? mainChest : other) * 31 + Objects.hashCode(!mainChestIsUpper ? mainChest : other);
}
public static VanillaDoubleChestItemHandler get(TileEntityChest chest)
{
World world = chest.getWorld();
BlockPos pos = chest.getPos();
if (world == null || pos == null || !world.isBlockLoaded(pos))
return null; // Still loading
Block blockType = chest.getBlockType();
EnumFacing[] horizontals = EnumFacing.HORIZONTALS;
for (int i = horizontals.length - 1; i >= 0; i--) // Use reverse order so we can return early
{
EnumFacing enumfacing = horizontals[i];
BlockPos blockpos = pos.offset(enumfacing);
Block block = world.getBlockState(blockpos).getBlock();
if (block == blockType)
{
TileEntity otherTE = world.getTileEntity(blockpos);
if (otherTE instanceof TileEntityChest)
{
TileEntityChest otherChest = (TileEntityChest) otherTE;
return new VanillaDoubleChestItemHandler(chest, otherChest,
enumfacing != net.minecraft.util.EnumFacing.WEST && enumfacing != net.minecraft.util.EnumFacing.NORTH);
}
}
}
return NO_ADJACENT_CHESTS_INSTANCE; //All alone
}
public TileEntityChest getChest(boolean accessingUpper)
{
if (accessingUpper == mainChestIsUpper)
return mainChest;
else
{
return getOtherChest();
}
}
private TileEntityChest getOtherChest()
{
TileEntityChest tileEntityChest = get();
return tileEntityChest != null && !tileEntityChest.isInvalid() ? tileEntityChest : null;
}
@Override
public int getSlots()
{
return 27 * 2;
}
@Override
@Nonnull
public ItemStack getStackInSlot(int slot)
{
boolean accessingUpperChest = slot < 27;
int targetSlot = accessingUpperChest ? slot : slot - 27;
TileEntityChest chest = getChest(accessingUpperChest);
return chest != null ? chest.getStackInSlot(targetSlot) : ItemStack.field_190927_a;
}
@Override
public void setStackInSlot(int slot, @Nonnull ItemStack stack)
{
boolean accessingUpperChest = slot < 27;
int targetSlot = accessingUpperChest ? slot : slot - 27;
TileEntityChest chest = getChest(accessingUpperChest);
if (chest != null)
{
IItemHandler singleHandler = chest.getSingleChestHandler();
if (singleHandler instanceof IItemHandlerModifiable)
{
((IItemHandlerModifiable) singleHandler).setStackInSlot(targetSlot, stack);
}
}
}
@Override
@Nonnull
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate)
{
boolean accessingUpperChest = slot < 27;
int targetSlot = accessingUpperChest ? slot : slot - 27;
TileEntityChest chest = getChest(accessingUpperChest);
return chest != null ? chest.getSingleChestHandler().insertItem(targetSlot, stack, simulate) : stack;
}
@Override
@Nonnull
public ItemStack extractItem(int slot, int amount, boolean simulate)
{
boolean accessingUpperChest = slot < 27;
int targetSlot = accessingUpperChest ? slot : slot - 27;
TileEntityChest chest = getChest(accessingUpperChest);
return chest != null ? chest.getSingleChestHandler().extractItem(targetSlot, amount, simulate) : ItemStack.field_190927_a;
}
@Override
public int getSlotLimit(int slot)
{
boolean accessingUpperChest = slot < 27;
return getChest(accessingUpperChest).getInventoryStackLimit();
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
VanillaDoubleChestItemHandler that = (VanillaDoubleChestItemHandler) o;
if (hashCode != that.hashCode)
return false;
final TileEntityChest otherChest = getOtherChest();
if (mainChestIsUpper == that.mainChestIsUpper)
return Objects.equal(mainChest, that.mainChest) && Objects.equal(otherChest, that.getOtherChest());
else
return Objects.equal(mainChest, that.getOtherChest()) && Objects.equal(otherChest, that.mainChest);
}
@Override
public int hashCode()
{
return hashCode;
}
public boolean needsRefresh()
{
if (this == NO_ADJACENT_CHESTS_INSTANCE)
return false;
TileEntityChest tileEntityChest = get();
return tileEntityChest == null || tileEntityChest.isInvalid();
}
}