package com.hbm.tileentity.machine; import com.hbm.inventory.material.Mats; import com.hbm.inventory.material.NTMMaterial; import com.hbm.inventory.material.Mats.MaterialStack; import api.hbm.block.ICrucibleAcceptor; import net.minecraft.nbt.NBTTagCompound; 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 net.minecraftforge.common.util.ForgeDirection; /** * Base class for all foundry channel type blocks - channels, casts, basins, tanks, etc. * Foundry type blocks can only hold one type at a time and usually either store or move it around. * @author hbm * */ public abstract class TileEntityFoundryBase extends TileEntity implements ICrucibleAcceptor { public NTMMaterial type; protected NTMMaterial lastType; public int amount; protected int lastAmount; @Override public void updateEntity() { if(worldObj.isRemote) { if(shouldClientReRender() && this.lastType != this.type || this.lastAmount != this.amount) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); this.lastType = this.type; this.lastAmount = this.amount; } } else { if(this.lastType != this.type || this.lastAmount != this.amount) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); this.lastType = this.type; this.lastAmount = this.amount; } } } /** Recommended FALSE for things that update a whole lot. TRUE if updates only happen once every few ticks. */ protected boolean shouldClientReRender() { return true; } @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); this.writeToNBT(nbt); return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 0, nbt); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { this.readFromNBT(pkt.func_148857_g()); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.type = Mats.matById.get(nbt.getInteger("type")); this.amount = nbt.getInteger("amount"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); if(this.type == null) { nbt.setInteger("type", -1); } else { nbt.setInteger("type", this.type.id); } nbt.setInteger("amount", this.amount); } public abstract int getCapacity(); /** * Standard check for testing if this material stack can be added to the casting block. Checks:
* - type matching
* - amount being at max
*/ public boolean standardCheck(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack) { if(this.type != null && this.type != stack.material && this.amount > 0) return false; //reject if there's already a different material if(this.amount >= this.getCapacity()) return false; //reject if the buffer is already full return true; } /** * Standardized adding of material via pouring or flowing. Does:
* - sets material to match the input * - adds the amount, not exceeding the maximum * - returns the amount that cannot be added */ public MaterialStack standardAdd(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack) { this.type = stack.material; if(stack.amount + this.amount <= this.getCapacity()) { this.amount += stack.amount; return null; } int required = this.getCapacity() - this.amount; this.amount = this.getCapacity(); stack.amount -= required; return stack; } /** Standard check with no additional limitations added */ @Override public boolean canAcceptPartialFlow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack) { return this.standardCheck(world, x, y, z, side, stack); } /** Standard flow, no special handling required */ @Override public MaterialStack flow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack) { return standardAdd(world, x, y, z, side, stack); } /** Standard check, but with the additional limitation that the only valid source direction is UP */ @Override public boolean canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack) { if(side != ForgeDirection.UP) return false; return this.standardCheck(world, x, y, z, side, stack); } /** Standard flow, no special handling required */ @Override public MaterialStack pour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack) { return standardAdd(world, x, y, z, side, stack); } }