package com.jaquadro.minecraft.gardencore.block.tile;
import com.jaquadro.minecraft.gardencore.api.IPlantProxy;
import com.jaquadro.minecraft.gardencore.api.block.garden.ISlotMapping;
import com.jaquadro.minecraft.gardencore.api.plant.PlantItem;
import com.jaquadro.minecraft.gardencore.block.BlockGarden;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class TileEntityGarden extends TileEntity implements IInventory
{
private static final int DEFAULT_BIOME_DATA = 65407;
public static final int SLOT_INVALID = -1;
private ItemStack[] containerStacks;
private PlantItem[] containerPlants;
private String customName;
private ItemStack substrate;
private ItemStack substrateSource;
private boolean hasBiomeOverride;
private int biomeData = DEFAULT_BIOME_DATA;
public TileEntityGarden () {
containerStacks = new ItemStack[containerSlotCount()];
}
protected int containerSlotCount () {
return 0;
}
public ItemStack getPlantInSlot (int slot) {
return getStackInSlot(slot);
}
public void clearPlantedContents () {
BlockGarden block = getGardenBlock();
if (block != null)
clearReachableContents(0, containerSlotCount());
}
public void clearReachableContents () {
clearReachableContents(0, containerStacks.length);
}
public boolean isEmpty () {
for (int i = 0; i < containerStacks.length; i++) {
if (getPlantInSlot(i) != null)
return false;
}
return true;
}
private void clearReachableContents (int start, int length) {
for (int i = start; i < length; i++)
setInventorySlotContents(i, null, false);
BlockGarden.validateBlockState(this);
if (!worldObj.isRemote)
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
public List<ItemStack> getReachableContents () {
List<ItemStack> contents = new ArrayList<ItemStack>();
for (int i = 0; i < containerStacks.length; i++) {
ItemStack item = getStackInSlot(i);
if (item != null)
contents.add(item);
}
return contents;
}
public boolean isSharedSlot (int slot) {
BlockGarden block = getGardenBlock();
if (block == null)
return false;
ISlotMapping[] nmap = block.getSlotShareProfile().getNeighborsForSlot(slot);
return nmap != null && nmap.length > 0;
}
public boolean isSlotValid (int slot) {
if (!isSharedSlot(slot))
return true;
BlockGarden block = getGardenBlock();
for (ISlotMapping mapping : block.getSlotShareProfile().getNeighborsForSlot(slot)) {
if (!block.getConnectionProfile().isAttachedNeighbor(worldObj, xCoord, yCoord, zCoord, xCoord + mapping.getMappedX(), yCoord, zCoord + mapping.getMappedZ()))
return false;
}
return true;
}
public boolean isAttachedNeighbor (int nx, int ny, int nz) {
BlockGarden garden = getGardenBlock();
if (garden == null)
return false;
return garden.getConnectionProfile().isAttachedNeighbor(worldObj, xCoord, yCoord, zCoord, nx, ny, nz);
}
public BlockGarden getGardenBlock () {
Block block = worldObj.getBlock(xCoord, yCoord, zCoord);
if (block instanceof BlockGarden)
return (BlockGarden) block;
return null;
}
public ItemStack getSubstrate () {
return substrate;
}
public ItemStack getSubstrateSource () {
return (substrateSource != null) ? substrateSource : substrate;
}
public void setSubstrate (ItemStack substrate) {
this.substrate = (substrate != null) ? substrate.copy() : null;
this.substrateSource = null;
}
public void setSubstrate (ItemStack substrate, ItemStack substrateSource) {
this.substrate = (substrate != null) ? substrate.copy() : null;
this.substrateSource = (getSubstrateSource() != null) ? substrateSource.copy() : null;
}
public boolean hasBiomeDataOverride () {
return hasBiomeOverride;
}
public int getBiomeData () {
return biomeData;
}
public float getBiomeTemperature () {
return (biomeData & 127) / 127f;
}
public float getBiomeHumidity () {
return ((biomeData >> 7) & 127) / 127f;
}
public void setBiomeData (int data) {
this.biomeData = data;
this.hasBiomeOverride = true;
}
private ItemStack getStackLocal (int slot) {
if (containerPlants == null && hasWorldObj())
initializeContainerPlants();
if (containerPlants != null)
return containerPlants[slot].getPlantSourceItem();
else
return containerStacks[slot];
}
private void setStackLocal (int slot, ItemStack itemStack) {
if (containerPlants == null && hasWorldObj())
initializeContainerPlants();
if (containerPlants != null && hasWorldObj())
containerPlants[slot] = PlantItem.getForItem(worldObj, itemStack);
containerStacks[slot] = itemStack;
}
private void initializeContainerPlants () {
containerPlants = new PlantItem[containerStacks.length];
for (int i = 0; i < containerStacks.length; i++) {
if (containerStacks[i] != null)
containerPlants[i] = PlantItem.getForItem(worldObj, containerStacks[i]);
}
}
@Override
public void setWorldObj (World world) {
super.setWorldObj(world);
if (containerPlants == null && world != null)
initializeContainerPlants();
else if (world == null)
containerPlants = null;
}
@Override
public void readFromNBT (NBTTagCompound tag) {
super.readFromNBT(tag);
NBTTagList itemList = tag.getTagList("Items", 10);
containerStacks = new ItemStack[getSizeInventory()];
containerPlants = null;
for (int i = 0; i < itemList.tagCount(); i++) {
NBTTagCompound item = itemList.getCompoundTagAt(i);
if (!item.hasKey("Slot") || !item.hasKey("Item") || !item.hasKey("Data"))
continue;
byte slot = item.getByte("Slot");
if (slot < 0 || slot >= containerStacks.length)
continue;
Item itemObj = Item.getItemById(item.getShort("Item"));
if (itemObj == null)
continue;
short itemData = item.getShort("Data");
setStackLocal(slot, new ItemStack(itemObj, 1, itemData));
}
customName = null;
if (tag.hasKey("CustomName"))
customName = tag.getString("CustomName");
substrate = null;
substrateSource = null;
if (tag.hasKey("SubId")) {
substrate = new ItemStack(Item.getItemById(tag.getShort("SubId")));
if (tag.hasKey("SubDa"))
substrate.setItemDamage(tag.getShort("SubDa"));
if (tag.hasKey("SubSrcId")) {
substrateSource = new ItemStack(Item.getItemById(tag.getShort("SubSrcId")));
if (tag.hasKey("SubSrcDa"))
substrateSource.setItemDamage(tag.getShort("SubSrcDa"));
if (tag.hasKey("SubSrcTag", 10))
substrateSource.stackTagCompound = tag.getCompoundTag("SubSrcTag");
}
}
hasBiomeOverride = tag.hasKey("Biom");
biomeData = tag.hasKey("Biom") ? tag.getInteger("Biom") : DEFAULT_BIOME_DATA;
}
@Override
public void writeToNBT (NBTTagCompound tag) {
super.writeToNBT(tag);
NBTTagList itemList = new NBTTagList();
for (int i = 0; i < containerStacks.length; i++) {
if (containerStacks[i] == null || containerStacks[i].getItem() == null)
continue;
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte)i);
item.setShort("Item", (short) Item.getIdFromItem(containerStacks[i].getItem()));
item.setShort("Data", (short) containerStacks[i].getItemDamage());
itemList.appendTag(item);
}
tag.setTag("Items", itemList);
if (hasCustomInventoryName())
tag.setString("CustomName", customName);
if (substrate != null) {
tag.setShort("SubId", (short)Item.getIdFromItem(substrate.getItem()));
if (substrate.getItemDamage() != 0)
tag.setShort("SubDa", (short)substrate.getItemDamage());
if (substrateSource != null) {
tag.setShort("SubSrcId", (short)Item.getIdFromItem(substrateSource.getItem()));
if (substrateSource.getItemDamage() != 0)
tag.setShort("SubSrcDa", (short)substrateSource.getItemDamage());
if (substrateSource.stackTagCompound != null)
tag.setTag("SubSrcTag", substrateSource.stackTagCompound);
}
}
if (hasBiomeOverride || biomeData != DEFAULT_BIOME_DATA)
tag.setInteger("Biom", biomeData);
}
@Override
public Packet getDescriptionPacket () {
NBTTagCompound tag = new NBTTagCompound();
writeToNBT(tag);
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 5, tag);
}
@Override
public void onDataPacket (NetworkManager net, S35PacketUpdateTileEntity pkt) {
readFromNBT(pkt.func_148857_g());
getWorldObj().func_147479_m(xCoord, yCoord, zCoord); // markBlockForRenderUpdate
int y = yCoord;
while (getWorldObj().getBlock(xCoord, ++y, zCoord) instanceof IPlantProxy)
getWorldObj().func_147479_m(xCoord, y, zCoord);
}
@Override
public int getSizeInventory () {
return containerStacks.length;
}
@Override
public ItemStack getStackInSlot (int slot) {
if (!isSharedSlot(slot))
return getStackInSlotIsolated(slot);
if (!isSlotValid(slot))
return null;
ItemStack stack = getStackInSlotIsolated(slot);
if (stack != null)
return stack;
BlockGarden block = getGardenBlock();
for (ISlotMapping mapping : block.getSlotShareProfile().getNeighborsForSlot(slot)) {
TileEntity te = worldObj.getTileEntity(xCoord + mapping.getMappedX(), yCoord, zCoord + mapping.getMappedZ());
if (te == null || !(te instanceof TileEntityGarden))
continue;
TileEntityGarden nGarden = (TileEntityGarden)te;
stack = nGarden.getStackInSlotIsolated(mapping.getMappedSlot());
if (stack != null)
return stack;
}
return null;
}
public ItemStack getStackInSlotIsolated (int slot) {
return containerStacks[slot];
}
@Override
public ItemStack decrStackSize (int slot, int count) {
ItemStack stack = getStackInSlot(slot);
if (stack != null) {
if (stack.stackSize <= count) {
setInventorySlotContents(slot, null);
return stack;
}
else {
ItemStack split = stack.splitStack(count);
if (stack.stackSize == 0)
setInventorySlotContents(slot, null);
markDirty();
return split;
}
}
return null;
}
@Override
public ItemStack getStackInSlotOnClosing (int slot) {
return null;
}
@Override
public void setInventorySlotContents (int slot, ItemStack itemStack) {
setInventorySlotContents(slot, itemStack, true);
}
public void setInventorySlotContents (int slot, ItemStack itemStack, boolean notify) {
if (!isSharedSlot(slot)) {
setInventorySlotContentsIsolated(slot, itemStack, notify);
return;
}
BlockGarden block = getGardenBlock();
for (ISlotMapping mapping : block.getSlotShareProfile().getNeighborsForSlot(slot)) {
if (!block.getConnectionProfile().isAttachedNeighbor(worldObj, xCoord, yCoord, zCoord, xCoord + mapping.getMappedX(), yCoord, zCoord + mapping.getMappedZ()))
continue;
TileEntity te = worldObj.getTileEntity(xCoord + mapping.getMappedX(), yCoord, zCoord + mapping.getMappedZ());
if (te == null || !(te instanceof TileEntityGarden))
continue;
TileEntityGarden nGarden = (TileEntityGarden)te;
nGarden.setInventorySlotContentsIsolated(mapping.getMappedSlot(), null, notify);
}
setInventorySlotContentsIsolated(slot, itemStack, notify);
}
protected void setInventorySlotContentsIsolated (int slot, ItemStack itemStack, boolean notify) {
containerStacks[slot] = itemStack;
if (itemStack != null && itemStack.stackSize > getInventoryStackLimit())
itemStack.stackSize = getInventoryStackLimit();
markDirty();
if (notify)
BlockGarden.validateBlockState(this);
}
@Override
public String getInventoryName () {
return hasCustomInventoryName() ? customName : "container.gardencore.garden";
}
@Override
public boolean hasCustomInventoryName () {
return customName != null && customName.length() > 0;
}
@Override
public int getInventoryStackLimit () {
return 1;
}
@Override
public boolean isUseableByPlayer (EntityPlayer player) {
if (worldObj.getTileEntity(xCoord, yCoord, zCoord) != this)
return false;
return player.getDistanceSq(xCoord + .5, yCoord + .5, zCoord + .5) <= 64;
}
@Override
public void openInventory () { }
@Override
public void closeInventory () { }
@Override
public boolean isItemValidForSlot (int slot, ItemStack itemStack) {
if (!isSlotValid(slot))
return false;
PlantItem plant = PlantItem.getForItem(worldObj, itemStack);
if (plant == null)
return false;
BlockGarden block = getGardenBlock();
if (block == null)
return false;
if (!block.isPlantValidForSlot(worldObj, xCoord, yCoord, zCoord, slot, plant))
return false;
return true;
}
}