package mekanism.common.multipart; import java.util.Collection; import mekanism.api.gas.Gas; import mekanism.api.gas.GasNetwork; import mekanism.api.gas.GasStack; import mekanism.api.gas.GasTank; import mekanism.api.gas.GasTransmission; import mekanism.api.gas.IGasHandler; import mekanism.api.transmitters.TransmissionType; import mekanism.api.util.CapabilityUtils; import mekanism.common.Tier; import mekanism.common.Tier.BaseTier; import mekanism.common.Tier.TubeTier; import mekanism.common.capabilities.Capabilities; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.Capability; public class PartPressurizedTube extends PartTransmitter<IGasHandler, GasNetwork> implements IGasHandler { public Tier.TubeTier tier = Tier.TubeTier.BASIC; public float currentScale; public GasTank buffer = new GasTank(getCapacity()); public GasStack lastWrite; public PartPressurizedTube(Tier.TubeTier tubeTier) { super(); tier = tubeTier; buffer.setMaxGas(getCapacity()); } @Override public void update() { if(!getWorld().isRemote) { updateShare(); IGasHandler[] connectedAcceptors = GasTransmission.getConnectedAcceptors(getPos(), getWorld()); for(EnumFacing side : getConnections(ConnectionType.PULL)) { if(connectedAcceptors[side.ordinal()] != null) { IGasHandler container = connectedAcceptors[side.ordinal()]; if(container != null) { GasStack received = container.drawGas(side.getOpposite(), tier.tubePullAmount, false); if(received != null && received.amount != 0) { container.drawGas(side.getOpposite(), takeGas(received, true), true); } } } } } else { float targetScale = getTransmitter().hasTransmitterNetwork() ? getTransmitter().getTransmitterNetwork().gasScale : (float)buffer.getStored()/(float)buffer.getMaxGas(); if(Math.abs(currentScale - targetScale) > 0.01) { currentScale = (9 * currentScale + targetScale) / 10; } } super.update(); } @Override public void updateShare() { if(getTransmitter().hasTransmitterNetwork() && getTransmitter().getTransmitterNetworkSize() > 0) { GasStack last = getSaveShare(); if((last != null && !(lastWrite != null && lastWrite.amount == last.amount && lastWrite.getGas() == last.getGas())) || (last == null && lastWrite != null)) { lastWrite = last; markDirty(); } } } private GasStack getSaveShare() { if(getTransmitter().hasTransmitterNetwork() && getTransmitter().getTransmitterNetwork().buffer != null) { int remain = getTransmitter().getTransmitterNetwork().buffer.amount%getTransmitter().getTransmitterNetwork().transmitters.size(); int toSave = getTransmitter().getTransmitterNetwork().buffer.amount/getTransmitter().getTransmitterNetwork().transmitters.size(); if(getTransmitter().getTransmitterNetwork().transmitters.iterator().next().equals(getTransmitter())) { toSave += remain; } return new GasStack(getTransmitter().getTransmitterNetwork().buffer.getGas(), toSave); } return null; } @Override public void onUnloaded() { if(!getWorld().isRemote && getTransmitter().hasTransmitterNetwork()) { if(lastWrite != null && getTransmitter().getTransmitterNetwork().buffer != null) { getTransmitter().getTransmitterNetwork().buffer.amount -= lastWrite.amount; if(getTransmitter().getTransmitterNetwork().buffer.amount <= 0) { getTransmitter().getTransmitterNetwork().buffer = null; } } } super.onUnloaded(); } @Override public void readFromNBT(NBTTagCompound nbtTags) { super.readFromNBT(nbtTags); if(nbtTags.hasKey("tier")) tier = TubeTier.values()[nbtTags.getInteger("tier")]; buffer.setMaxGas(getCapacity()); if(nbtTags.hasKey("cacheGas")) { buffer.setGas(GasStack.readFromNBT(nbtTags.getCompoundTag("cacheGas"))); } else { buffer.setGas(null); } } @Override public NBTTagCompound writeToNBT(NBTTagCompound nbtTags) { super.writeToNBT(nbtTags); if(lastWrite != null && lastWrite.amount > 0) { nbtTags.setTag("cacheGas", lastWrite.write(new NBTTagCompound())); } else { nbtTags.removeTag("cacheGas"); } nbtTags.setInteger("tier", tier.ordinal()); return nbtTags; } @Override public ResourceLocation getType() { return new ResourceLocation("mekanism:pressurized_tube_" + tier.name().toLowerCase()); } @Override public TransmissionType getTransmissionType() { return TransmissionType.GAS; } @Override public TransmitterType getTransmitterType() { return tier.type; } @Override public boolean isValidAcceptor(TileEntity tile, EnumFacing side) { return GasTransmission.isValidAcceptorOnSide(tile, side); } @Override public GasNetwork createNewNetwork() { return new GasNetwork(); } @Override public GasNetwork createNetworkByMerging(Collection<GasNetwork> networks) { return new GasNetwork(networks); } @Override public int getCapacity() { return tier.tubeCapacity; } @Override public GasStack getBuffer() { return buffer == null ? null : buffer.getGas(); } @Override public void takeShare() { if(getTransmitter().hasTransmitterNetwork() && getTransmitter().getTransmitterNetwork().buffer != null && lastWrite != null) { getTransmitter().getTransmitterNetwork().buffer.amount -= lastWrite.amount; buffer.setGas(lastWrite); } } @Override public int receiveGas(EnumFacing side, GasStack stack, boolean doTransfer) { if(getConnectionType(side) == ConnectionType.NORMAL || getConnectionType(side) == ConnectionType.PULL) { return takeGas(stack, doTransfer); } return 0; } @Override public GasStack drawGas(EnumFacing side, int amount, boolean doTransfer) { return null; } @Override public boolean canReceiveGas(EnumFacing side, Gas type) { return getConnectionType(side) == ConnectionType.NORMAL || getConnectionType(side) == ConnectionType.PULL; } @Override public boolean canDrawGas(EnumFacing side, Gas type) { return false; } public int takeGas(GasStack gasStack, boolean doEmit) { if(getTransmitter().hasTransmitterNetwork()) { return getTransmitter().getTransmitterNetwork().emit(gasStack, doEmit); } else { return buffer.receive(gasStack, doEmit); } } @Override public IGasHandler getCachedAcceptor(EnumFacing side) { TileEntity tile = getCachedTile(side); if(CapabilityUtils.hasCapability(tile, Capabilities.GAS_HANDLER_CAPABILITY, side.getOpposite())) { return CapabilityUtils.getCapability(tile, Capabilities.GAS_HANDLER_CAPABILITY, side.getOpposite()); } return null; } @Override public boolean upgrade(int tierOrdinal) { if(tier.ordinal() < BaseTier.ULTIMATE.ordinal() && tierOrdinal == tier.ordinal()+1) { tier = TubeTier.values()[tier.ordinal()+1]; markDirtyTransmitters(); sendDesc = true; return true; } return false; } @Override public void readUpdatePacket(PacketBuffer packet) { tier = TubeTier.values()[packet.readInt()]; super.readUpdatePacket(packet); } @Override public void writeUpdatePacket(PacketBuffer packet) { packet.writeInt(tier.ordinal()); super.writeUpdatePacket(packet); } @Override public boolean hasCapability(Capability<?> capability, EnumFacing side) { return capability == Capabilities.GAS_HANDLER_CAPABILITY || super.hasCapability(capability, side); } @Override public <T> T getCapability(Capability<T> capability, EnumFacing side) { if(capability == Capabilities.GAS_HANDLER_CAPABILITY) { return (T)this; } return super.getCapability(capability, side); } }