package micdoodle8.mods.galacticraft.core.tile; import mekanism.api.gas.Gas; import mekanism.api.gas.GasStack; import micdoodle8.mods.galacticraft.api.transmission.NetworkType; import micdoodle8.mods.galacticraft.api.transmission.tile.IOxygenReceiver; import micdoodle8.mods.galacticraft.api.transmission.tile.IOxygenStorage; import micdoodle8.mods.galacticraft.api.vector.BlockVec3; import micdoodle8.mods.galacticraft.core.GCFluids; import micdoodle8.mods.galacticraft.core.energy.EnergyConfigHandler; import micdoodle8.mods.galacticraft.core.energy.tile.TileBaseElectricBlock; import micdoodle8.mods.galacticraft.core.fluid.FluidNetwork; import micdoodle8.mods.galacticraft.core.fluid.NetworkHelper; import micdoodle8.mods.miccore.Annotations; import micdoodle8.mods.miccore.Annotations.NetworkedField; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import java.util.EnumSet; public abstract class TileEntityOxygen extends TileBaseElectricBlock implements IOxygenReceiver, IOxygenStorage, IFluidHandler { public int oxygenPerTick; @NetworkedField(targetSide = Side.CLIENT) public FluidTankGC tank; public float lastStoredOxygen; public static int timeSinceOxygenRequest; public TileEntityOxygen(int maxOxygen, int oxygenPerTick) { this.tank = new FluidTankGC(maxOxygen, this); this.oxygenPerTick = oxygenPerTick; } public int getScaledOxygenLevel(int scale) { return (int) Math.floor(this.getOxygenStored() * scale / (this.getMaxOxygenStored() - this.oxygenPerTick)); } public abstract boolean shouldUseOxygen(); public int getCappedScaledOxygenLevel(int scale) { return (int) Math.max(Math.min(Math.floor((double) this.tank.getFluidAmount() / (double) this.tank.getCapacity() * scale), scale), 0); } @Override public void update() { super.update(); if (!this.worldObj.isRemote) { if (TileEntityOxygen.timeSinceOxygenRequest > 0) { TileEntityOxygen.timeSinceOxygenRequest--; } if (this.shouldUseOxygen()) { if (this.tank.getFluid() != null) { FluidStack fluid = this.tank.getFluid().copy(); fluid.amount = Math.max(fluid.amount - this.oxygenPerTick, 0); this.tank.setFluid(fluid); } } } this.lastStoredOxygen = this.tank.getFluidAmount(); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); if (nbt.hasKey("storedOxygen")) { this.tank.setFluid(new FluidStack(GCFluids.fluidOxygenGas, nbt.getInteger("storedOxygen"))); } else if (nbt.hasKey("storedOxygenF")) { int oxygen = (int) nbt.getFloat("storedOxygenF"); oxygen = Math.min(this.tank.getCapacity(), oxygen); this.tank.setFluid(new FluidStack(GCFluids.fluidOxygenGas, oxygen)); } else { this.tank.readFromNBT(nbt); } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); this.tank.writeToNBT(nbt); } @Override public void setOxygenStored(int oxygen) { this.tank.setFluid(new FluidStack(GCFluids.fluidOxygenGas, (int) Math.max(Math.min(oxygen, this.getMaxOxygenStored()), 0))); } @Override public int getOxygenStored() { return this.tank.getFluidAmount(); } @Override public int getMaxOxygenStored() { return this.tank.getCapacity(); } public EnumSet<EnumFacing> getOxygenInputDirections() { return EnumSet.allOf(EnumFacing.class); } public EnumSet<EnumFacing> getOxygenOutputDirections() { return EnumSet.noneOf(EnumFacing.class); } @Override public boolean canConnect(EnumFacing direction, NetworkType type) { if (direction == null) { return false; } if (type == NetworkType.FLUID) { return this.getOxygenInputDirections().contains(direction) || this.getOxygenOutputDirections().contains(direction); } if (type == NetworkType.POWER) // return this.nodeAvailable(new EnergySourceAdjacent(direction)); { return super.canConnect(direction, type); } return false; } @Override public int receiveOxygen(EnumFacing from, int receive, boolean doReceive) { if (this.getOxygenInputDirections().contains(from)) { if (!doReceive) { return this.getOxygenRequest(from); } return this.receiveOxygen(receive, doReceive); } return 0; } public int receiveOxygen(int receive, boolean doReceive) { if (receive > 0) { int prevOxygenStored = this.getOxygenStored(); int newStoredOxygen = Math.min(prevOxygenStored + receive, this.getMaxOxygenStored()); if (doReceive) { TileEntityOxygen.timeSinceOxygenRequest = 20; this.setOxygenStored(newStoredOxygen); } return Math.max(newStoredOxygen - prevOxygenStored, 0); } return 0; } @Override public int provideOxygen(EnumFacing from, int request, boolean doProvide) { if (this.getOxygenOutputDirections().contains(from)) { return this.drawOxygen(request, doProvide); } return 0; } public int drawOxygen(int request, boolean doProvide) { if (request > 0) { int requestedOxygen = Math.min(request, this.getOxygenStored()); if (doProvide) { this.setOxygenStored(this.getOxygenStored() - requestedOxygen); } return requestedOxygen; } return 0; } public void produceOxygen() { if (!this.worldObj.isRemote) { for (EnumFacing direction : this.getOxygenOutputDirections()) { if (direction != null) { this.produceOxygen(direction); } } } } public boolean produceOxygen(EnumFacing outputDirection) { int provide = this.getOxygenProvide(outputDirection); if (provide > 0) { TileEntity outputTile = new BlockVec3(this).getTileEntityOnSide(this.worldObj, outputDirection); FluidNetwork outputNetwork = NetworkHelper.getFluidNetworkFromTile(outputTile, outputDirection); if (outputNetwork != null) { int gasRequested = outputNetwork.getRequest(); if (gasRequested > 0) { int usedGas = outputNetwork.emitToBuffer(new FluidStack(GCFluids.fluidOxygenGas, Math.min(gasRequested, provide)), true); this.drawOxygen(usedGas, true); return true; } } else if (outputTile instanceof IOxygenReceiver) { float requestedOxygen = ((IOxygenReceiver) outputTile).getOxygenRequest(outputDirection.getOpposite()); if (requestedOxygen > 0) { int acceptedOxygen = ((IOxygenReceiver) outputTile).receiveOxygen(outputDirection.getOpposite(), provide, true); this.drawOxygen(acceptedOxygen, true); return true; } } // else if (EnergyConfigHandler.isMekanismLoaded()) // { // //TODO Oxygen item handling - internal tank (IGasItem) // //int acceptedOxygen = GasTransmission.addGas(itemStack, type, amount); // //this.drawOxygen(acceptedOxygen, true); // // if (outputTile instanceof IGasHandler && ((IGasHandler) outputTile).canReceiveGas(outputDirection.getOpposite(), (Gas) EnergyConfigHandler.gasOxygen)) // { // GasStack toSend = new GasStack((Gas) EnergyConfigHandler.gasOxygen, (int) Math.floor(provide)); // int acceptedOxygen = 0; // try { // acceptedOxygen = ((IGasHandler) outputTile).receiveGas(outputDirection.getOpposite(), toSend); // } catch (Exception e) { } // this.drawOxygen(acceptedOxygen, true); // return true; // } // } } return false; } @Override public int getOxygenRequest(EnumFacing direction) { if (this.shouldPullOxygen()) { return this.oxygenPerTick * 2; } else { return 0; } } @Override public boolean shouldPullOxygen() { return this.getOxygenStored() < this.getMaxOxygenStored(); } /** * Make sure this does not exceed the oxygen stored. * This should return 0 if no oxygen is stored. * Implementing tiles must respect this or you will generate infinite oxygen. */ @Override public int getOxygenProvide(EnumFacing direction) { return 0; } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public int receiveGas(EnumFacing side, GasStack stack, boolean doTransfer) { if (!stack.getGas().getName().equals("oxygen")) { return 0; } return (int) Math.floor(this.receiveOxygen(stack.amount, doTransfer)); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public int receiveGas(EnumFacing side, GasStack stack) { return this.receiveGas(side, stack, true); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public GasStack drawGas(EnumFacing side, int amount, boolean doTransfer) { return new GasStack((Gas) EnergyConfigHandler.gasOxygen, (int) Math.floor(this.drawOxygen(amount, doTransfer))); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public GasStack drawGas(EnumFacing side, int amount) { return this.drawGas(side, amount, true); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public boolean canReceiveGas(EnumFacing side, Gas type) { return type.getName().equals("oxygen") && this.getOxygenInputDirections().contains(side); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public boolean canDrawGas(EnumFacing side, Gas type) { return type.getName().equals("oxygen") && this.getOxygenOutputDirections().contains(side); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.ITubeConnection", modID = "Mekanism") public boolean canTubeConnect(EnumFacing side) { return this.canConnect(side, NetworkType.FLUID); } @Override public int fill(EnumFacing from, FluidStack resource, boolean doFill) { if (this.getOxygenInputDirections().contains(from) && resource != null) { if (!doFill) { return this.getOxygenRequest(from); } return this.receiveOxygen(resource.amount, doFill); } return 0; } @Override public FluidStack drain(EnumFacing from, FluidStack resource, boolean doDrain) { return resource == null ? null : drain(from, resource.amount, doDrain); } @Override public FluidStack drain(EnumFacing from, int maxDrain, boolean doDrain) { if (this.getOxygenOutputDirections().contains(from)) { return new FluidStack(GCFluids.fluidOxygenGas, this.drawOxygen(maxDrain, doDrain)); } return null; } @Override public boolean canFill(EnumFacing from, Fluid fluid) { return this.getOxygenInputDirections().contains(from) && (fluid == null || fluid.getName().equals("oxygen")); } @Override public boolean canDrain(EnumFacing from, Fluid fluid) { return this.getOxygenOutputDirections().contains(from) && (fluid == null || fluid.getName().equals("oxygen")); } @Override public FluidTankInfo[] getTankInfo(EnumFacing from) { if (canConnect(from, NetworkType.FLUID)) { return new FluidTankInfo[] { this.tank.getInfo() }; } return new FluidTankInfo[] {}; } }