package mcjty.rftools.blocks.spawner; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import mcjty.lib.container.InventoryHelper; import mcjty.lib.entity.GenericEnergyReceiverTileEntity; import mcjty.lib.network.Argument; import mcjty.lib.network.PacketServerCommand; import mcjty.lib.varia.BlockTools; import mcjty.lib.varia.Coordinate; import mcjty.lib.varia.Logging; import mcjty.rftools.RFTools; import mcjty.rftools.network.RFToolsMessages; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import java.util.Map; public class MatterBeamerTileEntity extends GenericEnergyReceiverTileEntity implements ISidedInventory { public static final int TICKTIME = 20; public static String CMD_SETDESTINATION = "setDest"; private InventoryHelper inventoryHelper = new InventoryHelper(this, MatterBeamerContainer.factory, 1); // The location of the destination spawner.. private Coordinate destination = null; private int ticker = TICKTIME; public MatterBeamerTileEntity() { super(SpawnerConfiguration.BEAMER_MAXENERGY, SpawnerConfiguration.BEAMER_RECEIVEPERTICK); } @Override protected void checkStateServer() { int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord); if (!BlockTools.getRedstoneSignal(meta)) { disableBlockGlow(); return; } ticker--; if (ticker > 0) { return; } ticker = TICKTIME; TileEntity te = null; if (destination != null) { te = worldObj.getTileEntity(destination.getX(), destination.getY(), destination.getZ()); if (!(te instanceof SpawnerTileEntity)) { setDestination(null); return; } } else { return; } ItemStack itemStack = inventoryHelper.getStackInSlot(0); if (itemStack == null || itemStack.stackSize == 0) { disableBlockGlow(); return; } SpawnerTileEntity spawnerTileEntity = (SpawnerTileEntity) te; int maxblocks = (int) (SpawnerConfiguration.beamBlocksPerSend * (1.01 + getInfusedFactor() * 2.0)); int numblocks = Math.min(maxblocks, itemStack.stackSize); int rf = (int) (SpawnerConfiguration.beamRfPerObject * numblocks * (4.0f - getInfusedFactor()) / 4.0f); if (getEnergyStored(ForgeDirection.DOWN) < rf) { return; } consumeEnergy(rf); spawnerTileEntity.addMatter(itemStack, numblocks); inventoryHelper.decrStackSize(0, numblocks); enableBlockGlow(); } private void disableBlockGlow() { // Bit 0 is active, bit 3 is redstone. int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord); if ((meta & 1) != 0) { worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, (meta & ~1), 3); } } private void enableBlockGlow() { int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord); if ((meta & 1) == 0) { worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, meta | 1, 3); } } @Override public boolean shouldRenderInPass(int pass) { return pass == 1; } @SideOnly(Side.CLIENT) @Override public AxisAlignedBB getRenderBoundingBox() { return AxisAlignedBB.getBoundingBox(xCoord - 4, yCoord - 4, zCoord - 4, xCoord + 5, yCoord + 5, zCoord + 5); } // Called from client side when a wrench is used. public void useWrench(EntityPlayer player) { Coordinate thisCoord = new Coordinate(xCoord, yCoord, zCoord); Coordinate coord = RFTools.instance.clientInfo.getSelectedTE(); TileEntity tileEntity = null; if (coord != null) { tileEntity = worldObj.getTileEntity(coord.getX(), coord.getY(), coord.getZ()); } if (!(tileEntity instanceof MatterBeamerTileEntity)) { // None selected. Just select this one. RFTools.instance.clientInfo.setSelectedTE(thisCoord); SpawnerTileEntity destinationTE = getDestinationTE(); if (destinationTE == null) { RFTools.instance.clientInfo.setDestinationTE(null); } else { RFTools.instance.clientInfo.setDestinationTE(new Coordinate(destinationTE.xCoord, destinationTE.yCoord, destinationTE.zCoord)); } Logging.message(player, "Select a spawner as destination"); } else if (coord.equals(thisCoord)) { // Unselect this one. RFTools.instance.clientInfo.setSelectedTE(null); RFTools.instance.clientInfo.setDestinationTE(null); setDestination(null); Logging.message(player, "Destination cleared!"); } } public void setDestination(Coordinate destination) { this.destination = destination; disableBlockGlow(); markDirty(); if (worldObj.isRemote) { // We're on the client. Send change to server. RFToolsMessages.INSTANCE.sendToServer(new PacketServerCommand(xCoord, yCoord, zCoord, MatterBeamerTileEntity.CMD_SETDESTINATION, new Argument("dest", destination))); } else { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } } public Coordinate getDestination() { return destination; } /** * Get the current destination. This function checks first if that destination is * still valid and if not it is reset to null (i.e. the destination was removed). * @return the destination TE or null if there is no valid one */ private SpawnerTileEntity getDestinationTE() { if (destination == null) { return null; } TileEntity te = worldObj.getTileEntity(destination.getX(), destination.getY(), destination.getZ()); if (te instanceof SpawnerTileEntity) { return (SpawnerTileEntity) te; } else { destination = null; worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); return null; } } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); destination = Coordinate.readFromNBT(tagCompound, "dest"); } @Override public void readRestorableFromNBT(NBTTagCompound tagCompound) { super.readRestorableFromNBT(tagCompound); readBufferFromNBT(tagCompound); } private void readBufferFromNBT(NBTTagCompound tagCompound) { NBTTagList bufferTagList = tagCompound.getTagList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0 ; i < bufferTagList.tagCount() ; i++) { NBTTagCompound nbtTagCompound = bufferTagList.getCompoundTagAt(i); inventoryHelper.setStackInSlot(i, ItemStack.loadItemStackFromNBT(nbtTagCompound)); } } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); Coordinate.writeToNBT(tagCompound, "dest", destination); } @Override public void writeRestorableToNBT(NBTTagCompound tagCompound) { super.writeRestorableToNBT(tagCompound); writeBufferToNBT(tagCompound); } private void writeBufferToNBT(NBTTagCompound tagCompound) { NBTTagList bufferTagList = new NBTTagList(); for (int i = 0 ; i < inventoryHelper.getCount() ; i++) { ItemStack stack = inventoryHelper.getStackInSlot(i); NBTTagCompound nbtTagCompound = new NBTTagCompound(); if (stack != null) { stack.writeToNBT(nbtTagCompound); } bufferTagList.appendTag(nbtTagCompound); } tagCompound.setTag("Items", bufferTagList); } @Override public int[] getAccessibleSlotsFromSide(int side) { return MatterBeamerContainer.factory.getAccessibleSlots(); } @Override public boolean canInsertItem(int index, ItemStack item, int side) { return MatterBeamerContainer.factory.isInputSlot(index); } @Override public boolean canExtractItem(int index, ItemStack item, int side) { return MatterBeamerContainer.factory.isOutputSlot(index); } @Override public int getSizeInventory() { return inventoryHelper.getCount(); } @Override public ItemStack getStackInSlot(int index) { return inventoryHelper.getStackInSlot(index); } @Override public ItemStack decrStackSize(int index, int amount) { return inventoryHelper.decrStackSize(index, amount); } @Override public ItemStack getStackInSlotOnClosing(int index) { return null; } @Override public void setInventorySlotContents(int index, ItemStack stack) { inventoryHelper.setInventorySlotContents(getInventoryStackLimit(), index, stack); } @Override public String getInventoryName() { return "Beamer Inventory"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return canPlayerAccess(player); } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return true; } @Override public boolean execute(EntityPlayerMP playerMP, String command, Map<String, Argument> args) { boolean rc = super.execute(playerMP, command, args); if (rc) { return true; } if (CMD_SETDESTINATION.equals(command)) { setDestination(args.get("dest").getCoordinate()); return true; } return false; } }