package micdoodle8.mods.galacticraft.planets.mars.tile; import mekanism.api.gas.Gas; import mekanism.api.gas.GasStack; import micdoodle8.mods.galacticraft.api.prefab.world.gen.WorldProviderSpace; import micdoodle8.mods.galacticraft.api.tile.IDisableableMachine; import micdoodle8.mods.galacticraft.api.transmission.NetworkType; import micdoodle8.mods.galacticraft.api.world.IAtmosphericGas; import micdoodle8.mods.galacticraft.core.GCBlocks; import micdoodle8.mods.galacticraft.core.energy.item.ItemElectricBase; import micdoodle8.mods.galacticraft.core.energy.tile.TileBaseElectricBlockWithInventory; import micdoodle8.mods.galacticraft.core.util.ConfigManagerCore; import micdoodle8.mods.galacticraft.core.util.FluidUtil; import micdoodle8.mods.galacticraft.core.util.GCCoreUtil; import micdoodle8.mods.galacticraft.core.util.OxygenUtil; import micdoodle8.mods.galacticraft.planets.asteroids.items.AsteroidsItems; import micdoodle8.mods.galacticraft.planets.asteroids.items.ItemAtmosphericValve; import micdoodle8.mods.galacticraft.planets.mars.blocks.BlockMachineMarsT2; import micdoodle8.mods.galacticraft.planets.mars.items.MarsItems; import micdoodle8.mods.miccore.Annotations; import micdoodle8.mods.miccore.Annotations.NetworkedField; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.IChatComponent; import net.minecraft.world.WorldProvider; import net.minecraftforge.fluids.*; import net.minecraftforge.fml.relauncher.Side; import java.util.ArrayList; public class TileEntityMethaneSynthesizer extends TileBaseElectricBlockWithInventory implements ISidedInventory, IDisableableMachine, IFluidHandler { private final int tankCapacity = 4000; @NetworkedField(targetSide = Side.CLIENT) public FluidTank gasTank = new FluidTank(this.tankCapacity); @NetworkedField(targetSide = Side.CLIENT) public FluidTank gasTank2 = new FluidTank(this.tankCapacity / 2); @NetworkedField(targetSide = Side.CLIENT) public FluidTank liquidTank = new FluidTank(this.tankCapacity / 2); public int processTimeRequired = 3; @NetworkedField(targetSide = Side.CLIENT) public int processTicks = -8; private ItemStack[] containingItems = new ItemStack[5]; private int hasCO2 = -1; private boolean noCoal = true; private int coalPartial = 0; public TileEntityMethaneSynthesizer() { this.storage.setMaxExtract(ConfigManagerCore.hardMode ? 90 : 45); this.setTierGC(2); } @Override public void update() { super.update(); if (this.hasCO2 == -1) { this.hasCO2 = this.getAirProducts(); } if (!this.worldObj.isRemote) { //If somehow it has CO2 in a CO2-free dimension, flush it out if (this.hasCO2 == 0 && this.gasTank2.getFluidAmount() > 0) { this.gasTank2.drain(this.gasTank2.getFluidAmount(), true); } //First, see if any gas needs to be put into the hydogen storage //TODO - in 1.7.10 implement support for Mekanism internal hydrogen tanks //TODO add support for hydrogen atmospheres //Now check the CO2 storage ItemStack inputCanister = this.containingItems[2]; if (inputCanister != null) { if (inputCanister.getItem() instanceof ItemAtmosphericValve && this.hasCO2 > 0) { //CO2 -> CO2 tank if (this.gasTank2.getFluidAmount() < this.gasTank2.getCapacity()) { Block blockAbove = this.worldObj.getBlockState(this.getPos().up()).getBlock(); if (blockAbove != null && blockAbove.getMaterial() == Material.air && blockAbove != GCBlocks.breatheableAir && blockAbove != GCBlocks.brightBreatheableAir) { if (!OxygenUtil.inOxygenBubble(this.worldObj, this.getPos().getX() + 0.5D, this.getPos().getY() + 1D, this.getPos().getZ() + 0.5D)) { FluidStack gcAtmosphere = FluidRegistry.getFluidStack("carbondioxide", 4); this.gasTank2.fill(gcAtmosphere, true); } } } } } //Now see if any methane from the methane tank needs to be put into the output slot checkFluidTankTransfer(4, this.liquidTank); if (this.hasEnoughEnergyToRun && this.canProcess()) { //50% extra speed boost for Tier 2 machine if powered by Tier 2 power if (this.tierGC == 2) { this.processTimeRequired = Math.max(1, 4 - this.poweredByTierGC); } if (this.processTicks <= 0) { this.processTicks = this.processTimeRequired; } else { if (--this.processTicks <= 0) { this.doLiquefaction(); this.processTicks = this.canProcess() ? this.processTimeRequired : 0; } } } else { if (this.processTicks > 0) { this.processTicks = 0; } else if (--this.processTicks <= -8) { this.processTicks = -8; } } } } private void checkFluidTankTransfer(int slot, FluidTank tank) { if (FluidUtil.isValidContainer(this.containingItems[slot])) { final FluidStack liquid = tank.getFluid(); if (liquid != null) { FluidUtil.tryFillContainer(tank, liquid, this.containingItems, slot, AsteroidsItems.methaneCanister); } } else if (this.containingItems[slot] != null && this.containingItems[slot].getItem() instanceof ItemAtmosphericValve) { tank.drain(4, true); } } public int getScaledGasLevel(int i) { return this.gasTank.getFluid() != null ? this.gasTank.getFluid().amount * i / this.gasTank.getCapacity() : 0; } public int getScaledGasLevel2(int i) { return this.gasTank2.getFluid() != null ? this.gasTank2.getFluid().amount * i / this.gasTank2.getCapacity() : 0; } public int getScaledFuelLevel(int i) { return this.liquidTank.getFluid() != null ? this.liquidTank.getFluid().amount * i / this.liquidTank.getCapacity() : 0; } public boolean canProcess() { if (this.gasTank.getFluid() == null || this.gasTank.getFluid().amount <= 0 || this.getDisabled(0)) { return false; } this.noCoal = this.containingItems[3] == null || this.containingItems[3].stackSize == 0 || this.containingItems[3].getItem() != MarsItems.carbonFragments; if (this.noCoal && this.coalPartial == 0 && (this.gasTank2.getFluid() == null || this.gasTank2.getFluidAmount() <= 0)) { return false; } return this.liquidTank.getFluidAmount() < this.liquidTank.getCapacity(); } public int getAirProducts() { WorldProvider WP = this.worldObj.provider; if (WP instanceof WorldProviderSpace) { ArrayList<IAtmosphericGas> atmos = ((WorldProviderSpace) WP).getCelestialBody().atmosphere.composition; if (atmos.size() > 0) { if (atmos.get(0) == IAtmosphericGas.CO2) { return 1; } } if (atmos.size() > 1) { if (atmos.get(1) == IAtmosphericGas.CO2) { return 1; } } if (atmos.size() > 2) { if (atmos.get(2) == IAtmosphericGas.CO2) { return 1; } } return 0; } return 0; } public void doLiquefaction() { if (this.noCoal && this.coalPartial == 0) { if (this.gasTank2.getFluid() == null || this.gasTank2.drain(1, true).amount < 1) { return; } } else { if (this.coalPartial == 0) { this.decrStackSize(3, 1); } this.coalPartial++; if (this.coalPartial == 40) { this.coalPartial = 0; } } this.gasTank.drain(this.placeIntoFluidTanks(2) * 8, true); } private int placeIntoFluidTanks(int amountToDrain) { final int fuelSpace = this.liquidTank.getCapacity() - this.liquidTank.getFluidAmount(); if (fuelSpace > 0) { if (amountToDrain > fuelSpace) { amountToDrain = fuelSpace; } this.liquidTank.fill(FluidRegistry.getFluidStack("methane", amountToDrain), true); } else { amountToDrain = 0; } return amountToDrain; } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.processTicks = nbt.getInteger("smeltingTicks"); this.containingItems = this.readStandardItemsFromNBT(nbt); if (nbt.hasKey("gasTank")) { this.gasTank.readFromNBT(nbt.getCompoundTag("gasTank")); } if (nbt.hasKey("gasTank2")) { this.gasTank2.readFromNBT(nbt.getCompoundTag("gasTank2")); } if (nbt.hasKey("liquidTank")) { this.liquidTank.readFromNBT(nbt.getCompoundTag("liquidTank")); } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setInteger("smeltingTicks", this.processTicks); this.writeStandardItemsToNBT(nbt); if (this.gasTank.getFluid() != null) { nbt.setTag("gasTank", this.gasTank.writeToNBT(new NBTTagCompound())); } if (this.gasTank2.getFluid() != null) { nbt.setTag("gasTank2", this.gasTank2.writeToNBT(new NBTTagCompound())); } if (this.liquidTank.getFluid() != null) { nbt.setTag("liquidTank", this.liquidTank.writeToNBT(new NBTTagCompound())); } } @Override protected ItemStack[] getContainingItems() { return this.containingItems; } @Override public boolean hasCustomName() { return true; } @Override public String getName() { return GCCoreUtil.translate("tile.mars_machine.5.name"); } // ISidedInventory Implementation: @Override public int[] getSlotsForFace(EnumFacing side) { return new int[] { 0, 1, 2, 3, 4 }; } @Override public boolean canInsertItem(int slotID, ItemStack itemstack, EnumFacing side) { if (this.isItemValidForSlot(slotID, itemstack)) { switch (slotID) { case 0: return ItemElectricBase.isElectricItem(itemstack.getItem()); case 3: return itemstack.getItem() == MarsItems.carbonFragments; case 4: return FluidUtil.isEmptyContainer(itemstack, AsteroidsItems.methaneCanister); default: return false; } } return false; } @Override public boolean canExtractItem(int slotID, ItemStack itemstack, EnumFacing side) { if (this.isItemValidForSlot(slotID, itemstack)) { switch (slotID) { case 0: return itemstack.getItem() instanceof ItemElectricBase && ((ItemElectricBase) itemstack.getItem()).getElectricityStored(itemstack) <= 0 || !this.shouldPullEnergy(); case 4: return FluidUtil.isFullContainer(itemstack); default: return false; } } return false; } @Override public boolean isItemValidForSlot(int slotID, ItemStack itemstack) { switch (slotID) { case 0: return ItemElectricBase.isElectricItem(itemstack.getItem()); case 1: return false; case 2: return itemstack.getItem() instanceof ItemAtmosphericValve; case 3: return itemstack.getItem() == MarsItems.carbonFragments; case 4: return FluidUtil.isValidContainer(itemstack); } return false; } @Override public boolean shouldUseEnergy() { return this.canProcess(); } @Override public double getPacketRange() { return 320.0D; } @Override public EnumFacing getElectricInputDirection() { return EnumFacing.DOWN; } @Override public boolean canDrain(EnumFacing from, Fluid fluid) { if (from == this.getHydrogenInputDirection().getOpposite()) { return this.liquidTank.getFluid() != null && this.liquidTank.getFluidAmount() > 0; } return false; } @Override public FluidStack drain(EnumFacing from, FluidStack resource, boolean doDrain) { if (from == this.getHydrogenInputDirection().getOpposite()) { if (resource != null && resource.isFluidEqual(this.liquidTank.getFluid())) { return this.liquidTank.drain(resource.amount, doDrain); } } return null; } @Override public FluidStack drain(EnumFacing from, int maxDrain, boolean doDrain) { if (from == getHydrogenInputDirection().getOpposite()) { return this.liquidTank.drain(maxDrain, doDrain); } return null; } @Override public boolean canFill(EnumFacing from, Fluid fluid) { if (from == this.getHydrogenInputDirection()) { return fluid == null || "hydrogen".equals(fluid.getName()); } return false; } @Override public int fill(EnumFacing from, FluidStack resource, boolean doFill) { int used = 0; if (resource != null && this.canFill(from, resource.getFluid())) { if (this.gasTank.getFluidAmount() < this.gasTank.getCapacity()) { used = this.gasTank.fill(resource, doFill); } } return used; } @Override public FluidTankInfo[] getTankInfo(EnumFacing from) { FluidTankInfo[] tankInfo = new FluidTankInfo[] {}; if (from == this.getHydrogenInputDirection()) { tankInfo = new FluidTankInfo[] { new FluidTankInfo(this.gasTank) }; } else if (from == this.getHydrogenInputDirection().getOpposite()) { tankInfo = new FluidTankInfo[] { new FluidTankInfo(this.liquidTank) }; } return tankInfo; } @Override public int getBlockMetadata() { return this.getBlockType().getMetaFromState(this.worldObj.getBlockState(getPos())); } @Override public IChatComponent getDisplayName() { return null; } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public int receiveGas(EnumFacing side, GasStack stack, boolean doTransfer) { if (!stack.getGas().getName().equals("hydrogen")) { return 0; } int used = 0; //System.out.println("Giving gas amount "+stack.amount); if (this.gasTank.getFluidAmount() < this.gasTank.getCapacity()) { used = this.gasTank.fill(FluidRegistry.getFluidStack("hydrogen", stack.amount), doTransfer); } return used; } @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 null; } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public GasStack drawGas(EnumFacing side, int amount) { return null; } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public boolean canReceiveGas(EnumFacing side, Gas type) { //System.out.println("Testing receipt of gas "+type.getName()); return type.getName().equals("hydrogen") && side.equals(this.getHydrogenInputDirection()); } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.IGasHandler", modID = "Mekanism") public boolean canDrawGas(EnumFacing side, Gas type) { return false; } @Annotations.RuntimeInterface(clazz = "mekanism.api.gas.ITubeConnection", modID = "Mekanism") public boolean canTubeConnect(EnumFacing side) { return side.equals(this.getHydrogenInputDirection()); } @Override public boolean canConnect(EnumFacing direction, NetworkType type) { if (direction == null) { return false; } if (type == NetworkType.POWER) { return direction == this.getElectricInputDirection(); } //Hydrogen pipe if (type == NetworkType.FLUID) { return direction == this.getHydrogenInputDirection() || direction == this.getHydrogenInputDirection().getOpposite(); } return false; } public int getHydrogenRequest(EnumFacing direction) { return this.receiveHydrogen(direction, 1000000F, false); } public boolean shouldPullHydrogen() { return this.gasTank.getFluidAmount() < this.gasTank.getCapacity(); } public int receiveHydrogen(EnumFacing from, float receive, boolean doReceive) { if (from == this.getHydrogenInputDirection() && this.shouldPullHydrogen()) { FluidStack fluidToFill = FluidRegistry.getFluidStack("hydrogen", (int) (receive)); return this.gasTank.fill(fluidToFill, doReceive); } return 0; } @Override public EnumFacing getFront() { return this.worldObj.getBlockState(getPos()).getValue(BlockMachineMarsT2.FACING); } public EnumFacing getHydrogenInputDirection() { return this.getFront().rotateY(); } }