package slimeknights.tconstruct.shared.tileentity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockPane;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import slimeknights.mantle.tileentity.TileInventory;
import slimeknights.tconstruct.common.TinkerNetwork;
import slimeknights.tconstruct.common.config.Config;
import slimeknights.tconstruct.library.client.model.ModelHelper;
import slimeknights.tconstruct.shared.block.BlockTable;
import slimeknights.tconstruct.shared.block.PropertyTableItem;
import slimeknights.tconstruct.tools.common.network.InventorySlotSyncPacket;
public class TileTable extends TileInventory {
public static final String FEET_TAG = "textureBlock";
public static final String FACE_TAG = "facing";
protected int displaySlot = 0;
// default constructor for loading
public TileTable() {
super("", 0, 0);
}
public TileTable(String name, int inventorySize) {
super(name, inventorySize);
}
public TileTable(String name, int inventorySize, int maxStackSize) {
super(name, inventorySize, maxStackSize);
}
public IExtendedBlockState writeExtendedBlockState(IExtendedBlockState state) {
String texture = getTileData().getString("texture");
// texture not loaded
if(texture == null || texture.isEmpty()) {
// load it from saved block
ItemStack stack = ItemStack.loadItemStackFromNBT(getTileData().getCompoundTag(FEET_TAG));
if(stack != null) {
Block block = Block.getBlockFromItem(stack.getItem());
texture = ModelHelper.getTextureFromBlock(block, stack.getItemDamage()).getIconName();
getTileData().setString("texture", texture);
}
}
if(texture != null && !texture.isEmpty()) {
state = state.withProperty(BlockTable.TEXTURE, texture);
}
EnumFacing facing = getFacing();
state = state.withProperty((IUnlistedProperty<EnumFacing>) BlockTable.FACING, facing);
state = setInventoryDisplay(state);
return state;
}
protected IExtendedBlockState setInventoryDisplay(IExtendedBlockState state) {
PropertyTableItem.TableItems toDisplay = new PropertyTableItem.TableItems();
if(getStackInSlot(displaySlot) != null) {
ItemStack stack = getStackInSlot(displaySlot);
PropertyTableItem.TableItem item = getTableItem(stack, getWorld(), null);
if(item != null) {
toDisplay.items.add(item);
}
}
// add inventory if needed
return state.withProperty(BlockTable.INVENTORY, toDisplay);
}
public boolean isInventoryEmpty() {
for (int i = 0; i < this.getSizeInventory(); ++i) {
if (this.getStackInSlot(i) != null) {
return false;
}
}
return true;
}
@SideOnly(Side.CLIENT)
public static PropertyTableItem.TableItem getTableItem(ItemStack stack, World world, EntityLivingBase entity) {
if(stack == null) {
return null;
}
if(!Config.renderTableItems) {
return new PropertyTableItem.TableItem(stack, null);
}
IBakedModel model = ModelHelper.getBakedModelForItem(stack, world, entity);
PropertyTableItem.TableItem item = new PropertyTableItem.TableItem(stack, model, 0, -0.46875f, 0, 0.8f, (float) (Math.PI / 2));
if(stack.getItem() instanceof ItemBlock) {
if(!(Block.getBlockFromItem(stack.getItem()) instanceof BlockPane)) {
item.y = -0.3125f;
item.r = 0;
}
item.s = 0.375f;
}
return item;
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
// note that this sends all of the tile data. you should change this if you use additional tile data
NBTTagCompound tag = getTileData().copy();
writeToNBT(tag);
return new SPacketUpdateTileEntity(this.getPos(), this.getBlockMetadata(), tag);
}
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
NBTTagCompound tag = pkt.getNbtCompound();
NBTBase feet = tag.getTag(FEET_TAG);
if(feet != null) {
getTileData().setTag(FEET_TAG, feet);
}
NBTBase facing = tag.getTag(FACE_TAG);
if(facing != null) {
getTileData().setTag(FACE_TAG, facing);
}
readFromNBT(tag);
}
@Nonnull
@Override
public NBTTagCompound getUpdateTag() {
// new tag instead of super since default implementation calls the super of writeToNBT
return writeToNBT(new NBTTagCompound());
}
@Override
public void handleUpdateTag(@Nonnull NBTTagCompound tag) {
readFromNBT(tag);
}
public void setFacing(EnumFacing face) {
getTileData().setInteger(FACE_TAG, face.getIndex());
}
public EnumFacing getFacing() {
return EnumFacing.getFront(getTileData().getInteger(FACE_TAG));
}
public void updateTextureBlock(NBTTagCompound tag) {
getTileData().setTag(FEET_TAG, tag);
}
public NBTTagCompound getTextureBlock() {
return getTileData().getCompoundTag(FEET_TAG);
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack) {
// we sync slot changes to all clients around
if(getWorld() != null && getWorld() instanceof WorldServer && !getWorld().isRemote && !ItemStack.areItemStacksEqual(itemstack, getStackInSlot(slot))) {
TinkerNetwork.sendToClients((WorldServer) getWorld(), this.pos, new InventorySlotSyncPacket(itemstack, slot, pos));
}
super.setInventorySlotContents(slot, itemstack);
if(getWorld() != null && getWorld().isRemote && Config.renderTableItems) {
Minecraft.getMinecraft().renderGlobal.notifyBlockUpdate(null, pos, null, null, 0);
}
}
}