package zmaster587.advancedRocketry.tile.infrastructure; import io.netty.buffer.ByteBuf; import java.util.ArrayList; import java.util.List; import cpw.mods.fml.relauncher.Side; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; 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.util.ChatComponentText; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry; import zmaster587.advancedRocketry.api.fuel.FuelRegistry; import zmaster587.advancedRocketry.api.fuel.FuelRegistry.FuelType; import zmaster587.advancedRocketry.api.AdvancedRocketryBlocks; import zmaster587.advancedRocketry.api.Configuration; import zmaster587.advancedRocketry.api.EntityRocketBase; import zmaster587.advancedRocketry.api.IInfrastructure; import zmaster587.advancedRocketry.api.IMission; import zmaster587.advancedRocketry.block.BlockTileRedstoneEmitter; import zmaster587.advancedRocketry.tile.TileRocketBuilder; import zmaster587.libVulpes.gui.CommonResources; import zmaster587.libVulpes.interfaces.ILinkableTile; import zmaster587.libVulpes.inventory.modules.IButtonInventory; import zmaster587.libVulpes.inventory.modules.IModularInventory; import zmaster587.libVulpes.inventory.modules.ModuleBase; import zmaster587.libVulpes.inventory.modules.ModuleImage; import zmaster587.libVulpes.inventory.modules.ModuleLiquidIndicator; import zmaster587.libVulpes.inventory.modules.ModulePower; import zmaster587.libVulpes.inventory.modules.ModuleRedstoneOutputButton; import zmaster587.libVulpes.inventory.modules.ModuleSlotArray; import zmaster587.libVulpes.items.ItemLinker; import zmaster587.libVulpes.network.PacketHandler; import zmaster587.libVulpes.network.PacketMachine; import zmaster587.libVulpes.tile.IMultiblock; import zmaster587.libVulpes.tile.TileInventoriedRFConsumerTank; import zmaster587.libVulpes.util.BlockPosition; import zmaster587.libVulpes.util.INetworkMachine; import zmaster587.libVulpes.util.IconResource; import zmaster587.libVulpes.util.ZUtils.RedstoneState; public class TileEntityFuelingStation extends TileInventoriedRFConsumerTank implements IModularInventory, IMultiblock, IInfrastructure, ILinkableTile, IButtonInventory, INetworkMachine { EntityRocketBase linkedRocket; BlockPosition masterBlock; ModuleRedstoneOutputButton redstoneControl; RedstoneState state; public TileEntityFuelingStation() { super(1000,3, 5000); masterBlock = new BlockPosition(0, -1, 0); redstoneControl = new ModuleRedstoneOutputButton(174, 4, 0, "", this); state = RedstoneState.ON; } @Override public int getMaxLinkDistance() { return 10; } private void setRedstoneState(boolean condition) { if(state == RedstoneState.INVERTED) condition = !condition; else if(state == RedstoneState.OFF) condition = false; ((BlockTileRedstoneEmitter)AdvancedRocketryBlocks.blockFuelingStation).setRedstoneState(worldObj, xCoord, yCoord, zCoord, condition); } @Override public void performFunction() { if(!worldObj.isRemote) { if(tank.getFluid() != null) { float multiplier = FuelRegistry.instance.getMultiplier(FuelType.LIQUID, tank.getFluid().getFluid()); tank.drain(linkedRocket.addFuelAmount((int)(multiplier*Configuration.fuelPointsPer10Mb)), true); } //If the rocket is full then emit redstone setRedstoneState(linkedRocket.getFuelAmount() == linkedRocket.getFuelCapacity()); } useBucket(0, inventory.getStackInSlot(0)); } @Override public int getPowerPerOperation() { return 30; } @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); nbt.setByte("state", (byte)state.ordinal()); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, nbt); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { state = RedstoneState.values()[pkt.func_148857_g().getByte("state")]; redstoneControl.setRedstoneState(state); super.onDataPacket(net, pkt); } @Override public void updateEntity() { super.updateEntity(); } @Override public boolean canPerformFunction() { // TODO Solid fuel? return linkedRocket != null && ( /*(inv != null) ||*/ (tank.getFluid() != null && tank.getFluidAmount() > 9 && linkedRocket.getRocketStats().getFuelAmount(FuelType.LIQUID) < linkedRocket.getRocketStats().getFuelCapacity(FuelType.LIQUID)) ); } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return FuelRegistry.instance.isFuel(FuelType.LIQUID,fluid); } @Override public String getModularInventoryName() { return "Fueling Station"; } @Override public boolean hasCustomInventoryName() { return true; } @Override public void setInventorySlotContents(int slot, ItemStack stack) { super.setInventorySlotContents(slot, stack); while(useBucket(0, getStackInSlot(0))); } //Yes i was lazy //TODO: make better private boolean useBucket( int slot, ItemStack stack) { if(slot == 0 && FluidContainerRegistry.isFilledContainer(stack) && FuelRegistry.instance.isFuel(FuelType.LIQUID,FluidContainerRegistry.getFluidForFilledItem(stack).getFluid()) && tank.getFluidAmount() + FluidContainerRegistry.getContainerCapacity(stack) <= tank.getCapacity()) { ItemStack emptyContainer = FluidContainerRegistry.drainFluidContainer(stack); if(emptyContainer != null && inventory.getStackInSlot(1) == null || (emptyContainer.isItemEqual(inventory.getStackInSlot(1)) && inventory.getStackInSlot(1).stackSize < inventory.getStackInSlot(1).getMaxStackSize())) { tank.fill(FluidContainerRegistry.getFluidForFilledItem(stack), true); if(inventory.getStackInSlot(1) == null) super.setInventorySlotContents(1, emptyContainer); else inventory.getStackInSlot(1).stackSize++; decrStackSize(0, 1); } else return false; } else return false; return true; } @Override public boolean isItemValidForSlot(int slot, ItemStack stack) { if(FluidContainerRegistry.isFilledContainer(stack)) return FuelRegistry.instance.isFuel(FuelType.LIQUID, FluidContainerRegistry.getFluidForFilledItem(stack).getFluid()); return FuelRegistry.instance.isFuel(FuelType.LIQUID,stack); } @Override public void unlinkRocket() { this.linkedRocket = null; ((BlockTileRedstoneEmitter)AdvancedRocketryBlocks.blockFuelingStation).setRedstoneState(worldObj, xCoord, yCoord, zCoord, false); } @Override public boolean disconnectOnLiftOff() { return true; } @Override public boolean linkRocket(EntityRocketBase rocket) { this.linkedRocket = rocket; setRedstoneState( linkedRocket.getFuelAmount() == linkedRocket.getFuelCapacity()); return true; } @Override public boolean onLinkStart(ItemStack item, TileEntity entity, EntityPlayer player, World world) { ItemLinker.setMasterCoords(item, this.xCoord, this.yCoord, this.zCoord); if(this.linkedRocket != null) { this.linkedRocket.unlinkInfrastructure(this); this.unlinkRocket(); } if(player.worldObj.isRemote) Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage((new ChatComponentText("You program the linker with the fueling station at: " + this.xCoord + " " + this.yCoord + " " + this.zCoord))); return true; } @Override public void invalidate() { super.invalidate(); if(getMasterBlock() instanceof TileRocketBuilder) ((TileRocketBuilder)getMasterBlock()).removeConnectedInfrastructure(this); //Mostly for client rendering stuff if(linkedRocket != null) linkedRocket.unlinkInfrastructure(this); } @Override public boolean onLinkComplete(ItemStack item, TileEntity entity, EntityPlayer player, World world) { if(player.worldObj.isRemote) Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage((new ChatComponentText("This must be the first machine to link!"))); return false; } @Override public int[] getAccessibleSlotsFromSide(int side) { if(ForgeDirection.getOrientation(side) == ForgeDirection.DOWN) return new int[]{1}; return new int[]{0}; } @Override public List<ModuleBase> getModules(int ID, EntityPlayer player) { List<ModuleBase> list = new ArrayList<ModuleBase>(); list.add(new ModulePower(156, 12, this)); list.add(redstoneControl); list.add(new ModuleSlotArray(45, 18, this, 0, 1)); list.add(new ModuleSlotArray(45, 54, this, 1, 2)); if(worldObj.isRemote) list.add(new ModuleImage(44, 35, new IconResource(194, 0, 18, 18, CommonResources.genericBackground))); list.add(new ModuleLiquidIndicator(27, 18, this)); return list; } @Override public String getInventoryName() { return null; } @Override public boolean canInteractWithContainer(EntityPlayer entity) { return true; } @Override public boolean linkMission(IMission misson) { return false; } @Override public void unlinkMission() { } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setByte("redstoneState", (byte) state.ordinal()); if(hasMaster()) { nbt.setIntArray("masterPos", new int[] {masterBlock.x, masterBlock.y, masterBlock.z}); } } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); state = RedstoneState.values()[nbt.getByte("redstoneState")]; redstoneControl.setRedstoneState(state); if(nbt.hasKey("masterPos")) { int[] pos = nbt.getIntArray("masterPos"); setMasterBlock(pos[0], pos[1], pos[2]); } } @Override public boolean hasMaster() { return masterBlock.y > -1; } @Override public TileEntity getMasterBlock() { return worldObj.getTileEntity(masterBlock.x, masterBlock.y, masterBlock.z); } @Override public void setComplete(int x, int y, int z) { } @Override public void setIncomplete() { masterBlock.y = -1; } @Override public void setMasterBlock(int x, int y, int z) { masterBlock = new BlockPosition(x, y, z); } public boolean canRenderConnection() { return true; } @Override public void onInventoryButtonPressed(int buttonId) { state = redstoneControl.getState(); PacketHandler.sendToServer(new PacketMachine(this, (byte)0)); } @Override public void writeDataToNetwork(ByteBuf out, byte id) { out.writeByte(state.ordinal()); } @Override public void readDataFromNetwork(ByteBuf in, byte packetId, NBTTagCompound nbt) { nbt.setByte("state", in.readByte()); } @Override public void useNetworkData(EntityPlayer player, Side side, byte id, NBTTagCompound nbt) { state = RedstoneState.values()[nbt.getByte("state")]; if(linkedRocket != null) setRedstoneState(linkedRocket.getFuelAmount() == linkedRocket.getFuelCapacity()); } }