/** * Copyright (c) Lambda Innovation, 2013-2016 * This file is part of the AcademyCraft mod. * https://github.com/LambdaInnovation/AcademyCraft * Licensed under GPLv3, see project root for more information. */ package cn.academy.energy.block; import cn.academy.core.block.TileGeneratorBase; import cn.academy.crafting.ModuleCrafting; import cn.academy.crafting.item.ItemMatterUnit; import cn.academy.energy.IFConstants; import cn.academy.energy.client.render.block.RenderPhaseGen; import cn.lambdalib.annoreg.core.Registrant; import cn.lambdalib.annoreg.mc.RegTileEntity; import cn.lambdalib.s11n.network.TargetPoints; import cn.lambdalib.s11n.network.NetworkMessage; import cn.lambdalib.s11n.network.NetworkMessage.Listener; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.*; /** * @author WeAthFolD */ @Registrant @RegTileEntity @RegTileEntity.HasRender public class TilePhaseGen extends TileGeneratorBase implements IFluidHandler { // 废话~~~ public static final int SLOT_LIQUID_IN = ContainerPhaseGen.SLOT_LIQUID_IN, SLOT_LIQUID_OUT = ContainerPhaseGen.SLOT_LIQUID_OUT, SLOT_OUTPUT = ContainerPhaseGen.SLOT_OUTPUT; @RegTileEntity.Render @SideOnly(Side.CLIENT) public static RenderPhaseGen renderer; static final int CONSUME_PER_TICK = 100; static final double GEN_PER_MB = 0.5; int untilSync; public TilePhaseGen() { super("phase_gen", 3, 6000, IFConstants.LATENCY_MK1); } @Override public double getGeneration(double required) { int maxDrain = (int) Math.min(CONSUME_PER_TICK, required / GEN_PER_MB); FluidStack fs = tank.drain(maxDrain, true); return fs == null ? 0 : fs.amount * GEN_PER_MB; } @Override public void updateEntity() { super.updateEntity(); if(!getWorldObj().isRemote) { if(++untilSync == 10) { untilSync = 0; sync(); } ItemStack stack; { // Sink in liquid stack = getStackInSlot(SLOT_LIQUID_IN); if(stack != null && isPhaseLiquid(stack) && isOutputSlotAvailable() && (getTankSize() - getLiquidAmount() > PER_UNIT)) { if(stack.stackSize > 0) { tank.fill(new FluidStack(ModuleCrafting.fluidImagProj, PER_UNIT), true); --stack.stackSize; } if(stack.stackSize <= 0) setInventorySlotContents(0, null); ItemStack output = getStackInSlot(SLOT_LIQUID_OUT); if(output != null) { ++output.stackSize; } else { this.setInventorySlotContents(SLOT_LIQUID_OUT, ModuleCrafting.matterUnit.create(ItemMatterUnit.NONE)); } } } { // Output energy stack = getStackInSlot(SLOT_OUTPUT); if(stack != null) this.tryChargeStack(stack); } } } // Fluid handling static final int TANK_SIZE = 8000; static final int PER_UNIT = 1000; protected FluidTank tank = new FluidTank(TANK_SIZE); public int getLiquidAmount() { return tank.getFluidAmount(); } public int getTankSize() { return tank.getCapacity(); } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { if(resource.getFluid() != ModuleCrafting.fluidImagProj) { return 0; } return tank.fill(resource, doFill); } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { return tank.drain(resource.amount, doDrain); } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { return tank.drain(maxDrain, doDrain); } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return fluid == ModuleCrafting.fluidImagProj; } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return fluid == ModuleCrafting.fluidImagProj; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { return new FluidTankInfo[] { tank.getInfo() }; } @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); tank.readFromNBT(tag); } @Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tank.writeToNBT(tag); } private void sync() { NetworkMessage.sendToAllAround(TargetPoints.convert(this, 20), this, "sync", getLiquidAmount()); } @Listener(channel="sync", side=Side.CLIENT) private void hSync(int fluidAmount) { tank.setFluid(new FluidStack(ModuleCrafting.fluidImagProj, fluidAmount)); } private boolean isPhaseLiquid(ItemStack stack) { return stack.getItem() == ModuleCrafting.matterUnit && ModuleCrafting.matterUnit.getMaterial(stack) == ModuleCrafting.imagPhase.mat; } private boolean isOutputSlotAvailable() { ItemStack stack = getStackInSlot(SLOT_LIQUID_OUT); return stack == null || (stack.getItem() == ModuleCrafting.matterUnit && ModuleCrafting.matterUnit.getMaterial(stack) == ItemMatterUnit.NONE && stack.stackSize < stack.getMaxStackSize()); } }