package crazypants.enderio.machine.generator.zombie; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import com.enderio.core.api.common.util.ITankAccess; import com.enderio.core.common.util.BlockCoord; import com.enderio.core.common.util.FluidUtil; import crazypants.enderio.EnderIO; import crazypants.enderio.ModObject; import crazypants.enderio.config.Config; import crazypants.enderio.machine.IoMode; import crazypants.enderio.machine.SlotDefinition; import crazypants.enderio.machine.generator.AbstractGeneratorEntity; import crazypants.enderio.network.PacketHandler; import crazypants.enderio.power.PowerDistributor; import crazypants.enderio.tool.SmartTank; public class TileZombieGenerator extends AbstractGeneratorEntity implements IFluidHandler, ITankAccess, IHasNutrientTank { private static int IO_MB_TICK = 250; final SmartTank fuelTank = new SmartTank(EnderIO.fluidNutrientDistillation, FluidContainerRegistry.BUCKET_VOLUME * 2); int outputPerTick = Config.zombieGeneratorRfPerTick; int tickPerBucketOfFuel = Config.zombieGeneratorTicksPerBucketFuel; private boolean tanksDirty; private boolean active = false; private PowerDistributor powerDis; private int ticksRemaingFuel; private boolean inPause; public TileZombieGenerator() { super(new SlotDefinition(0, 0, 0)); } @Override public String getMachineName() { return ModObject.blockZombieGenerator.unlocalisedName; } @Override public boolean supportsMode(ForgeDirection faceHit, IoMode mode) { return mode != IoMode.PUSH && mode != IoMode.PUSH_PULL; } @Override protected boolean doPull(ForgeDirection dir) { boolean res = super.doPull(dir); BlockCoord loc = getLocation().getLocation(dir); IFluidHandler target = FluidUtil.getFluidHandler(worldObj, loc); if(target != null) { FluidTankInfo[] infos = target.getTankInfo(dir.getOpposite()); if(infos != null) { for (FluidTankInfo info : infos) { if(info.fluid != null && info.fluid.amount > 0) { if(canFill(dir, info.fluid.getFluid())) { FluidStack canPull = info.fluid.copy(); canPull.amount = Math.min(IO_MB_TICK, canPull.amount); FluidStack drained = target.drain(dir.getOpposite(), canPull, false); if(drained != null && drained.amount > 0) { int filled = fill(dir, drained, false); if(filled > 0) { drained = target.drain(dir.getOpposite(), filled, true); fill(dir, drained, true); return res; } } } } } } } return res; } @Override public int getPowerUsePerTick() { return outputPerTick; } @Override protected boolean isMachineItemValidForSlot(int i, ItemStack itemstack) { return false; } @Override public boolean isActive() { return active; } @Override public void onNeighborBlockChange(Block blockId) { super.onNeighborBlockChange(blockId); if(powerDis != null) { powerDis.neighboursChanged(); } } @Override protected boolean processTasks(boolean redstoneCheckPassed) { boolean res = false; if(!redstoneCheckPassed) { if(active) { active = false; res = true; } return res; } else { boolean isActive = generateEnergy(); if(isActive != active) { active = isActive; res = true; } if(getEnergyStored() >= getMaxEnergyStored()) { inPause = true; } transmitEnergy(); } if(tanksDirty) { PacketHandler.sendToAllAround(new PacketNutrientTank(this), this); tanksDirty = false; } return res; } private boolean generateEnergy() { //once full, don't start again until we have drained 10 seconds worth of power to prevent //flickering on and off constantly when powering a machine that draws less than this produces if (inPause && getEnergyStored() >= (getMaxEnergyStored() - (outputPerTick * 200)) && getEnergyStored() > (getMaxEnergyStored() / 8)) { return false; } inPause = false; if(fuelTank.getFluidAmount() < getActivationAmount()) { return false; } ticksRemaingFuel--; if(ticksRemaingFuel <= 0) { fuelTank.drain(1, true); ticksRemaingFuel = tickPerBucketOfFuel/1000; tanksDirty = true; } setEnergyStored(getEnergyStored() + outputPerTick); return true; } int getActivationAmount() { return (int) (fuelTank.getCapacity() * 0.7f); } private boolean transmitEnergy() { if(getEnergyStored() <= 0) { return false; } if(powerDis == null) { powerDis = new PowerDistributor(new BlockCoord(this)); } int transmitted = powerDis.transmitEnergy(worldObj, Math.min(outputPerTick * 2, getEnergyStored())); setEnergyStored(getEnergyStored() - transmitted); return transmitted > 0; } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { int res = fuelTank.fill(resource, doFill); if(res > 0 && doFill) { tanksDirty = true; } return res; } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { return null; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { return null; } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return fuelTank.canFill(fluid); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return false; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { return new FluidTankInfo[] { fuelTank.getInfo() }; } public int getFluidStored(ForgeDirection from) { return fuelTank.getFluidAmount(); } @Override public void readCustomNBT(NBTTagCompound nbtRoot) { super.readCustomNBT(nbtRoot); active = nbtRoot.getBoolean("active"); } @Override public boolean shouldRenderInPass(int pass) { if(pass == 0) { return true; } if(pass == 1) { return fuelTank.getFluidAmount() > 0; } return false; } @Override public void readCommon(NBTTagCompound nbtRoot) { super.readCommon(nbtRoot); fuelTank.readCommon("fuelTank", nbtRoot); } @Override public void writeCommon(NBTTagCompound nbtRoot) { super.writeCommon(nbtRoot); fuelTank.writeCommon("fuelTank", nbtRoot); } @Override public void writeCustomNBT(NBTTagCompound nbtRoot) { super.writeCustomNBT(nbtRoot); nbtRoot.setBoolean("active", active); } @Override public FluidTank getInputTank(FluidStack forFluidType) { if (forFluidType != null && forFluidType.getFluid() == EnderIO.fluidNutrientDistillation) { return fuelTank; } return null; } @Override public FluidTank[] getOutputTanks() { return new FluidTank[] { /* fuelTank */}; } @Override public void setTanksDirty() { tanksDirty = true; } @Override public SmartTank getNutrientTank() { return fuelTank; } }