diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidConfigurable.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidConfigurable.java index 4d385c72..d4818dc6 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidConfigurable.java +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidConfigurable.java @@ -69,18 +69,18 @@ public abstract class ContainerFluidConfigurable extends ContainerUpgradeable { final IInventory inv = Ae2Reflect.getUpgradeList(this).getInventoryByName( "config" ); final int y = 40; final int x = 80; - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 0, x, y, 0, 0, 0 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 0, x, y, 0, 0, 0 ) ); if( this.supportCapacity() ) { - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 1, x, y, -1, 0, 1 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 2, x, y, 1, 0, 1 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 3, x, y, 0, -1, 1 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 4, x, y, 0, 1, 1 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 1, x, y, -1, 0, 1 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 2, x, y, 1, 0, 1 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 3, x, y, 0, -1, 1 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 4, x, y, 0, 1, 1 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 5, x, y, -1, -1, 2 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 6, x, y, 1, -1, 2 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 7, x, y, -1, 1, 2 ) ); - this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, this, 8, x, y, 1, 1, 2 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 5, x, y, -1, -1, 2 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 6, x, y, 1, -1, 2 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 7, x, y, -1, 1, 2 ) ); + this.addSlotToContainer( new OptionalFluidSlotFakeTypeOnly( inv, null, this, 8, x, y, 1, 1, 2 ) ); } } diff --git a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidInterface.java b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidInterface.java index af0bb12c..34f0599e 100644 --- a/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidInterface.java +++ b/src/main/java/com/glodblock/github/client/gui/container/ContainerFluidInterface.java @@ -29,7 +29,7 @@ public class ContainerFluidInterface extends AEBaseContainer implements IOptiona final int y = 35; final int x = 35; for (int i = 0; i < 6; i++) { - addSlotToContainer(new OptionalFluidSlotFakeTypeOnly(inv, this, i, x, y, i, 0, 0)); + addSlotToContainer(new OptionalFluidSlotFakeTypeOnly(inv, tile.getDualityFluid().getConfig(), this, i, x, y, i, 0, 0)); } bindPlayerInventory(ipl, 0, 149); } @@ -41,7 +41,7 @@ public class ContainerFluidInterface extends AEBaseContainer implements IOptiona final int y = 35; final int x = 35; for (int i = 0; i < 6; i++) { - addSlotToContainer(new OptionalFluidSlotFakeTypeOnly(inv, this, i, x, y, i, 0, 0)); + addSlotToContainer(new OptionalFluidSlotFakeTypeOnly(inv, tile.getDualityFluid().getConfig(), this, i, x, y, i, 0, 0)); } bindPlayerInventory(ipl, 0, 149); } diff --git a/src/main/java/com/glodblock/github/common/parts/PartFluidInterface.java b/src/main/java/com/glodblock/github/common/parts/PartFluidInterface.java index 276d9044..2848ea2b 100644 --- a/src/main/java/com/glodblock/github/common/parts/PartFluidInterface.java +++ b/src/main/java/com/glodblock/github/common/parts/PartFluidInterface.java @@ -4,6 +4,9 @@ import appeng.api.config.Actionable; import appeng.api.config.Upgrades; import appeng.api.networking.IGridNode; import appeng.api.networking.energy.IEnergyGrid; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.MachineSource; import appeng.api.networking.storage.IStorageGrid; @@ -27,6 +30,7 @@ import com.glodblock.github.inventory.IAEFluidTank; import com.glodblock.github.inventory.InventoryHandler; import com.glodblock.github.inventory.gui.GuiType; import com.glodblock.github.util.BlockPos; +import com.glodblock.github.util.DualityFluidInterface; import com.glodblock.github.util.Util; import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.relauncher.Side; @@ -49,11 +53,8 @@ import java.util.Objects; public class PartFluidInterface extends PartInterface implements IFluidHandler, IAEFluidInventory { private final BaseActionSource ownActionSource = new MachineSource(this); - private final AEFluidInventory invFluids = new AEFluidInventory(this, 6, 16000); private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, 6 ); - - private final boolean[] tickState = new boolean[]{true, true, true, true, true, true}; - private final int[] tickCount = new int[]{0, 0, 0, 0, 0, 0}; + private final DualityFluidInterface fluidDuality = new DualityFluidInterface(this.getProxy(), this); public PartFluidInterface(ItemStack is) { super(is); @@ -98,29 +99,62 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, rh.renderInventoryBox( renderer ); } + @MENetworkEventSubscribe + public void stateChange(final MENetworkChannelsChanged c) { + fluidDuality.onChannelStateChange(c); + } + + @MENetworkEventSubscribe + public void stateChange(final MENetworkPowerStatusChange c) { + fluidDuality.onPowerStateChange(c); + } + + @Override + public void gridChanged() { + super.gridChanged(); + fluidDuality.gridChanged(); + } + + public DualityFluidInterface getDualityFluid() { + return fluidDuality; + } + public AEFluidInventory getInternalFluid() { - return invFluids; + return fluidDuality.getTanks(); } public AppEngInternalAEInventory getConfig() { + for (int i = 0; i < fluidDuality.getConfig().getSlots(); i ++) { + IAEFluidStack fluid = fluidDuality.getConfig().getFluidInSlot(i); + if (fluid == null) { + config.setInventorySlotContents(i, null); + } + else { + config.setInventorySlotContents(i, ItemFluidPacket.newDisplayStack(fluid.getFluidStack())); + } + } return config; } @Override public void writeToStream(ByteBuf data) throws IOException { - super.writeToStream( data ); + super.writeToStream(data); for (int i = 0; i < config.getSizeInventory(); i++) { ByteBufUtils.writeItemStack(data, config.getStackInSlot(i)); + for (int j = 0; j < config.getSizeInventory(); j ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(j)); + fluidDuality.getConfig().setFluidInSlot(j, fluidDuality.getStandardFluid(fluid)); + } } int fluidMask = 0; - for (int i = 0; i < invFluids.getSlots(); i++) { - if (invFluids.getFluidInSlot(i) != null) { + for (int i = 0; i < getInternalFluid().getSlots(); i++) { + if (getInternalFluid().getFluidInSlot(i) != null) { fluidMask |= 1 << i; } } data.writeByte(fluidMask); - for (int i = 0; i < invFluids.getSlots(); i++) { - IAEFluidStack fluid = invFluids.getFluidInSlot(i); + for (int i = 0; i < getInternalFluid().getSlots(); i++) { + IAEFluidStack fluid = getInternalFluid().getFluidInSlot(i); if (fluid != null) { fluid.writeToPacket(data); } @@ -137,20 +171,24 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, config.setInventorySlotContents(i, stack); changed = true; } + for (int j = 0; j < config.getSizeInventory(); j ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(j)); + fluidDuality.getConfig().setFluidInSlot(j, fluidDuality.getStandardFluid(fluid)); + } } int fluidMask = data.readByte(); - for (int i = 0; i < invFluids.getSlots(); i++) { + for (int i = 0; i < getInternalFluid().getSlots(); i++) { if ((fluidMask & (1 << i)) != 0) { IAEFluidStack fluid = AEFluidStack.loadFluidStackFromPacket(data); if (fluid != null) { // this shouldn't happen, but better safe than sorry - IAEFluidStack origFluid = invFluids.getFluidInSlot(i); + IAEFluidStack origFluid = getInternalFluid().getFluidInSlot(i); if (!fluid.equals(origFluid) || fluid.getStackSize() != origFluid.getStackSize()) { - invFluids.setFluidInSlot(i, fluid); + getInternalFluid().setFluidInSlot(i, fluid); changed = true; } } - } else if (invFluids.getFluidInSlot(i) != null) { - invFluids.setFluidInSlot(i, null); + } else if (getInternalFluid().getFluidInSlot(i) != null) { + getInternalFluid().setFluidInSlot(i, null); changed = true; } } @@ -158,17 +196,21 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, } @Override - public void readFromNBT( NBTTagCompound extra ) { - super.readFromNBT( extra ); - config.readFromNBT(extra, "ConfigInv"); - invFluids.readFromNBT(extra, "FluidInv"); + public void readFromNBT( NBTTagCompound data ) { + super.readFromNBT( data ); + config.readFromNBT(data, "ConfigInv"); + for (int i = 0; i < config.getSizeInventory(); i ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(i)); + fluidDuality.getConfig().setFluidInSlot(i, fluidDuality.getStandardFluid(fluid)); + } + getInternalFluid().readFromNBT(data, "FluidInv"); } @Override - public void writeToNBT( NBTTagCompound extra ) { - super.writeToNBT(extra); - config.writeToNBT(extra, "ConfigInv"); - invFluids.writeToNBT(extra, "FluidInv"); + public void writeToNBT( NBTTagCompound data ) { + super.writeToNBT(data); + config.writeToNBT(data, "ConfigInv"); + getInternalFluid().writeToNBT(data, "FluidInv"); } @Override @@ -211,12 +253,12 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { - return invFluids.drain(from, resource, doDrain); + return fluidDuality.drain(from, resource, doDrain); } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { - return invFluids.drain(from, maxDrain, doDrain); + return fluidDuality.drain(from, maxDrain, doDrain); } @Override @@ -231,7 +273,7 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { - return invFluids.getTankInfo(from); + return fluidDuality.getTankInfo(from); } @Override @@ -252,93 +294,43 @@ public class PartFluidInterface extends PartInterface implements IFluidHandler, public void onFluidInventoryChanged(IAEFluidTank inv, int slot) { saveChanges(); getTileEntity().markDirty(); + fluidDuality.onFluidInventoryChanged(inv, slot); } public void setConfig(int id, IAEFluidStack fluid) { if (id >= 0 && id < 6) { config.setInventorySlotContents(id, ItemFluidPacket.newDisplayStack(fluid == null ? null : fluid.getFluidStack())); + fluidDuality.getConfig().setFluidInSlot(id, fluidDuality.getStandardFluid(fluid)); } } public void setFluidInv(int id, IAEFluidStack fluid) { if (id >= 0 && id < 6) { - invFluids.setFluidInSlot(id, fluid); + getInternalFluid().setFluidInSlot(id, fluid); } } @Override public TickingRequest getTickingRequest( final IGridNode node ) { - return new TickingRequest( TickRates.Interface.getMin(), TickRates.Interface.getMax(), false, true ); + TickingRequest item = super.getTickingRequest(node); + TickingRequest fluid = fluidDuality.getTickingRequest(node); + return new TickingRequest( + Math.min(item.minTickRate, fluid.minTickRate), + Math.max(item.maxTickRate, fluid.maxTickRate), + item.isSleeping && fluid.isSleeping, + true); } @Override public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) { - //Very Hacky thing. - if (!isActive()) { - return TickRateModulation.SLEEP; + TickRateModulation item = super.tickingRequest(node, TicksSinceLastCall); + TickRateModulation fluid = fluidDuality.tickingRequest(node, TicksSinceLastCall); + if (item.ordinal() >= fluid.ordinal()) { + return item; + } else { + return fluid; } - for (int i = 0; i < 6; i ++) { - - FluidStack configFluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(i)); - FluidStack storedFluid = invFluids.getFluidInSlot(i) == null ? null : invFluids.getFluidInSlot(i).getFluidStack(); - - if (!Util.areFluidsEqual(configFluid, storedFluid)) { - if (storedFluid != null) { - int ori = storedFluid.amount; - int filled = fill(ForgeDirection.UNKNOWN, storedFluid, false); - if (ori == filled) { - fill(ForgeDirection.UNKNOWN, storedFluid, true); - invFluids.setFluidInSlot(i, null); - } - else { - tickState[i] = false; - } - } - } - - if (configFluid != null) { - if (tickState[i]) { - if (getFluidGrid() != null) { - FluidStack configCopy = configFluid.copy(); - configCopy.amount = Math.min(8000, getLeftSpace(storedFluid, configCopy)); - IAEFluidStack fluidDrain = getFluidGrid().extractItems(AEFluidStack.create(configCopy), Actionable.MODULATE, ownActionSource); - if (fluidDrain != null && fluidDrain.getStackSize() != 0) { - invFluids.fill(i, fluidDrain.getFluidStack(), true); - } else { - tickState[i] = false; - } - } - } - else if (tickCount[i] % 40 == 0) { - if (getFluidGrid() != null) { - FluidStack configCopy = configFluid.copy(); - configCopy.amount = Math.min(8000, getLeftSpace(storedFluid, configCopy)); - IAEFluidStack fluidDrain = getFluidGrid().extractItems(AEFluidStack.create(configCopy), Actionable.MODULATE, ownActionSource); - if (fluidDrain != null && fluidDrain.getStackSize() != 0) { - invFluids.fill(i, fluidDrain.getFluidStack(), true); - tickState[i] = true; - } - } - } - } - - tickCount[i] ++; - if (tickCount[i] > 500) { - tickCount[i] = 1; - } - } - super.tickingRequest(node, TicksSinceLastCall); - return TickRateModulation.URGENT; } - private int getLeftSpace(FluidStack stored, FluidStack req) { - if (stored == null) { - return 16000; - } - if (!Util.areFluidsEqual(stored, req)) { - return 0; - } - return 16000 - stored.amount; - } } diff --git a/src/main/java/com/glodblock/github/common/tile/TileFluidDiscretizer.java b/src/main/java/com/glodblock/github/common/tile/TileFluidDiscretizer.java index c8e1c0d4..20b40225 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileFluidDiscretizer.java +++ b/src/main/java/com/glodblock/github/common/tile/TileFluidDiscretizer.java @@ -131,11 +131,6 @@ public class TileFluidDiscretizer extends AENetworkTile implements IPriorityHost updateState(); } - private boolean checkDiscreatizer() { - int amount = getProxy().getNode().getGrid().getMachines(this.getClass()).size(); - return amount <= 1; - } - private class FluidDiscretizingInventory implements IMEInventory, IMEMonitorHandlerReceiver { private final MEInventoryHandler invHandler = new MEInventoryHandler<>(this, getChannel()); diff --git a/src/main/java/com/glodblock/github/common/tile/TileFluidInterface.java b/src/main/java/com/glodblock/github/common/tile/TileFluidInterface.java index 7b9ece7c..8cb5268f 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileFluidInterface.java +++ b/src/main/java/com/glodblock/github/common/tile/TileFluidInterface.java @@ -1,11 +1,16 @@ package com.glodblock.github.common.tile; -import appeng.api.config.Actionable; import appeng.api.config.Upgrades; +import appeng.api.networking.IGridNode; import appeng.api.networking.energy.IEnergyGrid; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.MachineSource; import appeng.api.networking.storage.IStorageGrid; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; import appeng.api.storage.IMEMonitor; import appeng.api.storage.data.IAEFluidStack; import appeng.me.GridAccessException; @@ -13,14 +18,13 @@ import appeng.tile.TileEvent; import appeng.tile.events.TileEventType; import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.misc.TileInterface; -import appeng.util.Platform; import appeng.util.item.AEFluidStack; import com.glodblock.github.common.item.ItemFluidPacket; import com.glodblock.github.inventory.AEFluidInventory; import com.glodblock.github.inventory.IAEFluidInventory; import com.glodblock.github.inventory.IAEFluidTank; import com.glodblock.github.loader.ItemAndBlockHolder; -import com.glodblock.github.util.Util; +import com.glodblock.github.util.DualityFluidInterface; import cpw.mods.fml.common.network.ByteBufUtils; import io.netty.buffer.ByteBuf; import net.minecraft.item.ItemStack; @@ -37,52 +41,91 @@ import java.io.IOException; public class TileFluidInterface extends TileInterface implements IFluidHandler, IAEFluidInventory { - private final BaseActionSource ownActionSource = new MachineSource(this); - private final AEFluidInventory invFluids = new AEFluidInventory(this, 6, 16000); - private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, 6 ); - - private final boolean[] tickState = new boolean[]{true, true, true, true, true, true}; - private final int[] tickCount = new int[]{0, 0, 0, 0, 0, 0}; - private int tickMain = 0; - - private IMEMonitor getFluidGrid() { - try { - return getProxy().getGrid().getCache(IStorageGrid.class).getFluidInventory(); - } catch (GridAccessException e) { - return null; + private final DualityFluidInterface fluidDuality = new DualityFluidInterface(this.getProxy(), this) { + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return this.getTanks().drain(from.ordinal(), maxDrain, doDrain); } + }; + private final AppEngInternalAEInventory config = new AppEngInternalAEInventory(this, 6); + + @MENetworkEventSubscribe + public void stateChange(final MENetworkChannelsChanged c) { + fluidDuality.onChannelStateChange(c); } - private IEnergyGrid getEnergyGrid() { - try { - return getProxy().getGrid().getCache(IEnergyGrid.class); - } catch (GridAccessException e) { - return null; - } + @MENetworkEventSubscribe + public void stateChange(final MENetworkPowerStatusChange c) { + fluidDuality.onPowerStateChange(c); + } + + @Override + public void gridChanged() { + super.gridChanged(); + fluidDuality.gridChanged(); + } + + public DualityFluidInterface getDualityFluid() { + return fluidDuality; } public AEFluidInventory getInternalFluid() { - return invFluids; + return fluidDuality.getTanks(); } public AppEngInternalAEInventory getConfig() { + for (int i = 0; i < fluidDuality.getConfig().getSlots(); i ++) { + IAEFluidStack fluid = fluidDuality.getConfig().getFluidInSlot(i); + if (fluid == null) { + config.setInventorySlotContents(i, null); + } + else { + config.setInventorySlotContents(i, ItemFluidPacket.newDisplayStack(fluid.getFluidStack())); + } + } return config; } + @Override + public TickingRequest getTickingRequest(IGridNode node) { + TickingRequest item = super.getTickingRequest(node); + TickingRequest fluid = fluidDuality.getTickingRequest(node); + return new TickingRequest( + Math.min(item.minTickRate, fluid.minTickRate), + Math.max(item.maxTickRate, fluid.maxTickRate), + item.isSleeping && fluid.isSleeping, + true); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) { + TickRateModulation item = super.tickingRequest(node, ticksSinceLastCall); + TickRateModulation fluid = fluidDuality.tickingRequest(node, ticksSinceLastCall); + if (item.ordinal() >= fluid.ordinal()) { + return item; + } else { + return fluid; + } + } + @TileEvent( TileEventType.NETWORK_WRITE ) protected void writeToStream(ByteBuf data) throws IOException { for (int i = 0; i < config.getSizeInventory(); i++) { ByteBufUtils.writeItemStack(data, config.getStackInSlot(i)); + for (int j = 0; j < config.getSizeInventory(); j ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(j)); + fluidDuality.getConfig().setFluidInSlot(j, fluidDuality.getStandardFluid(fluid)); + } } int fluidMask = 0; - for (int i = 0; i < invFluids.getSlots(); i++) { - if (invFluids.getFluidInSlot(i) != null) { + for (int i = 0; i < getInternalFluid().getSlots(); i++) { + if (getInternalFluid().getFluidInSlot(i) != null) { fluidMask |= 1 << i; } } data.writeByte(fluidMask); - for (int i = 0; i < invFluids.getSlots(); i++) { - IAEFluidStack fluid = invFluids.getFluidInSlot(i); + for (int i = 0; i < getInternalFluid().getSlots(); i++) { + IAEFluidStack fluid = getInternalFluid().getFluidInSlot(i); if (fluid != null) { fluid.writeToPacket(data); } @@ -98,20 +141,24 @@ public class TileFluidInterface extends TileInterface implements IFluidHandler, config.setInventorySlotContents(i, stack); changed = true; } + for (int j = 0; j < config.getSizeInventory(); j ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(j)); + fluidDuality.getConfig().setFluidInSlot(j, fluidDuality.getStandardFluid(fluid)); + } } int fluidMask = data.readByte(); - for (int i = 0; i < invFluids.getSlots(); i++) { + for (int i = 0; i < getInternalFluid().getSlots(); i++) { if ((fluidMask & (1 << i)) != 0) { IAEFluidStack fluid = AEFluidStack.loadFluidStackFromPacket(data); if (fluid != null) { // this shouldn't happen, but better safe than sorry - IAEFluidStack origFluid = invFluids.getFluidInSlot(i); + IAEFluidStack origFluid = getInternalFluid().getFluidInSlot(i); if (!fluid.equals(origFluid) || fluid.getStackSize() != origFluid.getStackSize()) { - invFluids.setFluidInSlot(i, fluid); + getInternalFluid().setFluidInSlot(i, fluid); changed = true; } } - } else if (invFluids.getFluidInSlot(i) != null) { - invFluids.setFluidInSlot(i, null); + } else if (getInternalFluid().getFluidInSlot(i) != null) { + getInternalFluid().setFluidInSlot(i, null); changed = true; } } @@ -121,13 +168,17 @@ public class TileFluidInterface extends TileInterface implements IFluidHandler, @TileEvent( TileEventType.WORLD_NBT_READ ) public void readFromNBTEvent(NBTTagCompound data) { config.readFromNBT(data, "ConfigInv"); - invFluids.readFromNBT(data, "FluidInv"); + for (int i = 0; i < config.getSizeInventory(); i ++) { + FluidStack fluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(i)); + fluidDuality.getConfig().setFluidInSlot(i, fluidDuality.getStandardFluid(fluid)); + } + getInternalFluid().readFromNBT(data, "FluidInv"); } @TileEvent( TileEventType.WORLD_NBT_WRITE ) public NBTTagCompound writeToNBTEvent(NBTTagCompound data) { config.writeToNBT(data, "ConfigInv"); - invFluids.writeToNBT(data, "FluidInv"); + getInternalFluid().writeToNBT(data, "FluidInv"); return data; } @@ -148,33 +199,22 @@ public class TileFluidInterface extends TileInterface implements IFluidHandler, @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { - IMEMonitor fluidGrid = getFluidGrid(); - IEnergyGrid energyGrid = getEnergyGrid(); - if (energyGrid == null || fluidGrid == null || resource == null) - return 0; - int ori = resource.amount; - IAEFluidStack remove; - if (doFill) { - remove = fluidGrid.injectItems(AEFluidStack.create(resource), Actionable.MODULATE, ownActionSource); - } else { - remove = fluidGrid.injectItems(AEFluidStack.create(resource), Actionable.SIMULATE, ownActionSource); - } - return remove == null ? ori : (int) (ori - remove.getStackSize()); + return fluidDuality.fill(from, resource, doFill); } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { - return invFluids.drain(from, resource, doDrain); + return fluidDuality.drain(from, resource, doDrain); } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { - return invFluids.drain(from.ordinal(), maxDrain, doDrain); + return fluidDuality.drain(from, maxDrain, doDrain); } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { - return true; + return fluidDuality.canFill(from, fluid); } @Override @@ -184,95 +224,27 @@ public class TileFluidInterface extends TileInterface implements IFluidHandler, @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { - return invFluids.getTankInfo(from); + return fluidDuality.getTankInfo(from); } @Override public void onFluidInventoryChanged(IAEFluidTank inv, int slot) { saveChanges(); markForUpdate(); + fluidDuality.onFluidInventoryChanged(inv, slot); } public void setConfig(int id, IAEFluidStack fluid) { if (id >= 0 && id < 6) { config.setInventorySlotContents(id, ItemFluidPacket.newDisplayStack(fluid == null ? null : fluid.getFluidStack())); + fluidDuality.getConfig().setFluidInSlot(id, fluidDuality.getStandardFluid(fluid)); } } public void setFluidInv(int id, IAEFluidStack fluid) { if (id >= 0 && id < 6) { - invFluids.setFluidInSlot(id, fluid); + getInternalFluid().setFluidInSlot(id, fluid); } } - @TileEvent( TileEventType.TICK ) - public void updateTick() { - //Very Hacky thing. - if (tickMain % 20 == 0) { - tickMain = 0; - for (int i = 0; i < 6; i ++) { - - FluidStack configFluid = ItemFluidPacket.getFluidStack(config.getStackInSlot(i)); - FluidStack storedFluid = invFluids.getFluidInSlot(i) == null ? null : invFluids.getFluidInSlot(i).getFluidStack(); - - if (!Util.areFluidsEqual(configFluid, storedFluid)) { - if (storedFluid != null) { - int ori = storedFluid.amount; - int filled = fill(ForgeDirection.UNKNOWN, storedFluid, false); - if (ori == filled) { - fill(ForgeDirection.UNKNOWN, storedFluid, true); - invFluids.setFluidInSlot(i, null); - tickState[i] = true; - } - else { - tickState[i] = false; - } - } - } - - if (configFluid != null) { - if (tickState[i]) { - if (getFluidGrid() != null) { - FluidStack configCopy = configFluid.copy(); - configCopy.amount = Math.min(8000, getLeftSpace(storedFluid, configCopy)); - IAEFluidStack fluidDrain = getFluidGrid().extractItems(AEFluidStack.create(configCopy), Actionable.MODULATE, ownActionSource); - if (fluidDrain != null && fluidDrain.getStackSize() != 0) { - invFluids.fill(i, fluidDrain.getFluidStack(), true); - } else { - tickState[i] = false; - } - } - } - else if (tickCount[i] % 5 == 0) { - if (getFluidGrid() != null) { - FluidStack configCopy = configFluid.copy(); - configCopy.amount = Math.min(8000, getLeftSpace(storedFluid, configCopy)); - IAEFluidStack fluidDrain = getFluidGrid().extractItems(AEFluidStack.create(configCopy), Actionable.MODULATE, ownActionSource); - if (fluidDrain != null && fluidDrain.getStackSize() != 0) { - invFluids.fill(i, fluidDrain.getFluidStack(), true); - tickState[i] = true; - } - } - } - } - - tickCount[i] ++; - if (tickCount[i] > 500) { - tickCount[i] = 1; - } - } - } - tickMain ++; - } - - private int getLeftSpace(FluidStack stored, FluidStack req) { - if (stored == null) { - return 16000; - } - if (!Util.areFluidsEqual(stored, req)) { - return 0; - } - return 16000 - stored.amount; - } - } diff --git a/src/main/java/com/glodblock/github/inventory/MEMonitorIFluidHandler.java b/src/main/java/com/glodblock/github/inventory/MEMonitorIFluidHandler.java new file mode 100644 index 00000000..4a260af6 --- /dev/null +++ b/src/main/java/com/glodblock/github/inventory/MEMonitorIFluidHandler.java @@ -0,0 +1,203 @@ +package com.glodblock.github.inventory; + +import appeng.api.AEApi; +import appeng.api.config.AccessRestriction; +import appeng.api.config.Actionable; +import appeng.api.config.StorageFilter; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IMEMonitorHandlerReceiver; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.util.item.AEFluidStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; + +import java.util.*; + +public class MEMonitorIFluidHandler implements IMEMonitor { + private final IFluidHandler handler; + private IItemList cache = AEApi.instance().storage().createFluidList(); + private final HashMap, Object> listeners = new HashMap<>(); + private BaseActionSource mySource; + private StorageFilter mode; + + public MEMonitorIFluidHandler(IFluidHandler handler) { + this.mode = StorageFilter.EXTRACTABLE_ONLY; + this.handler = handler; + } + + public void addListener(IMEMonitorHandlerReceiver l, Object verificationToken) { + this.listeners.put(l, verificationToken); + } + + public void removeListener(IMEMonitorHandlerReceiver l) { + this.listeners.remove(l); + } + + public IAEFluidStack injectItems(IAEFluidStack input, Actionable type, BaseActionSource src) { + int filled = this.handler.fill(ForgeDirection.UNKNOWN, input.getFluidStack(), type == Actionable.MODULATE); + if (filled == 0) { + return input.copy(); + } else if ((long)filled == input.getStackSize()) { + return null; + } else { + IAEFluidStack o = input.copy(); + o.setStackSize(input.getStackSize() - (long)filled); + if (type == Actionable.MODULATE) { + IAEFluidStack added = o.copy(); + this.cache.add(added); + this.postDifference(Collections.singletonList(added)); + this.onTick(); + } + return o; + } + } + + public IAEFluidStack extractItems(IAEFluidStack request, Actionable type, BaseActionSource src) { + FluidStack removed = this.handler.drain(ForgeDirection.UNKNOWN, request.getFluidStack(), type == Actionable.MODULATE); + if (removed != null && removed.amount != 0) { + IAEFluidStack o = request.copy(); + o.setStackSize(removed.amount); + if (type == Actionable.MODULATE) { + IAEFluidStack cachedStack = this.cache.findPrecise(request); + if (cachedStack != null) { + cachedStack.decStackSize(o.getStackSize()); + this.postDifference(Collections.singletonList(o.copy().setStackSize(-o.getStackSize()))); + } + } + return o; + } else { + return null; + } + } + + @Override + public StorageChannel getChannel() + { + return StorageChannel.FLUIDS; + } + + //*Decompiled Stuff*// + + public TickRateModulation onTick() { + boolean changed = false; + List changes = new ArrayList<>(); + FluidTankInfo[] tankProperties = this.handler.getTankInfo(ForgeDirection.UNKNOWN); + IItemList currentlyOnStorage = AEApi.instance().storage().createFluidList(); + + for (FluidTankInfo tankProperty : tankProperties) { + if (this.mode != StorageFilter.EXTRACTABLE_ONLY || this.handler.drain(ForgeDirection.UNKNOWN, 1, false) != null) { + currentlyOnStorage.add(AEFluidStack.create(tankProperty.fluid)); + } + } + + Iterator var9 = this.cache.iterator(); + + IAEFluidStack is; + while(var9.hasNext()) { + is = (IAEFluidStack)var9.next(); + is.setStackSize(-is.getStackSize()); + } + + var9 = currentlyOnStorage.iterator(); + + while(var9.hasNext()) { + is = (IAEFluidStack)var9.next(); + this.cache.add(is); + } + + var9 = this.cache.iterator(); + + while(var9.hasNext()) { + is = (IAEFluidStack)var9.next(); + if (is.getStackSize() != 0L) { + changes.add(is); + } + } + + this.cache = currentlyOnStorage; + if (!changes.isEmpty()) { + this.postDifference(changes); + changed = true; + } + + return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER; + } + + private void postDifference(Iterable a) { + if (a != null) { + Iterator i = this.listeners.entrySet().iterator(); + + while(i.hasNext()) { + Map.Entry, Object> l = (Map.Entry)i.next(); + IMEMonitorHandlerReceiver key = l.getKey(); + if (key.isValid(l.getValue())) { + key.postChange(this, a, this.getActionSource()); + } else { + i.remove(); + } + } + } + + } + + public AccessRestriction getAccess() { + return AccessRestriction.READ_WRITE; + } + + public boolean isPrioritized(IAEFluidStack input) { + return false; + } + + public boolean canAccept(IAEFluidStack input) { + return true; + } + + public int getPriority() { + return 0; + } + + public int getSlot() { + return 0; + } + + public boolean validForPass(int i) { + return true; + } + + public IItemList getAvailableItems(IItemList out) { + Iterator var2 = this.cache.iterator(); + + while(var2.hasNext()) { + IAEFluidStack fs = (IAEFluidStack)var2.next(); + out.addStorage(fs); + } + + return out; + } + + public IItemList getStorageList() { + return this.cache; + } + + private StorageFilter getMode() { + return this.mode; + } + + public void setMode(StorageFilter mode) { + this.mode = mode; + } + + private BaseActionSource getActionSource() { + return this.mySource; + } + + public void setActionSource(BaseActionSource mySource) { + this.mySource = mySource; + } +} diff --git a/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFakeTypeOnly.java b/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFakeTypeOnly.java index 05b1bfe4..9eeaa70b 100644 --- a/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFakeTypeOnly.java +++ b/src/main/java/com/glodblock/github/inventory/slot/OptionalFluidSlotFakeTypeOnly.java @@ -2,7 +2,9 @@ package com.glodblock.github.inventory.slot; import appeng.container.slot.IOptionalSlotHost; import appeng.container.slot.OptionalSlotFakeTypeOnly; +import appeng.util.item.AEFluidStack; import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.inventory.AEFluidInventory; import com.glodblock.github.util.Util; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -10,8 +12,11 @@ import net.minecraftforge.fluids.FluidStack; public class OptionalFluidSlotFakeTypeOnly extends OptionalSlotFakeTypeOnly { - public OptionalFluidSlotFakeTypeOnly(IInventory inv, IOptionalSlotHost containerBus, int idx, int x, int y, int offX, int offY, int groupNum) { + AEFluidInventory fluidInv; + + public OptionalFluidSlotFakeTypeOnly(IInventory inv, AEFluidInventory fluidInv, IOptionalSlotHost containerBus, int idx, int x, int y, int offX, int offY, int groupNum) { super(inv, containerBus, idx, x, y, offX, offY, groupNum); + this.fluidInv = fluidInv; } @Override @@ -20,10 +25,18 @@ public class OptionalFluidSlotFakeTypeOnly extends OptionalSlotFakeTypeOnly { FluidStack fluidStack = Util.getFluidFromItem(is); if (fluidStack != null) { ItemStack tmp = ItemFluidPacket.newDisplayStack(fluidStack); + if (fluidInv != null) { + FluidStack standard = fluidStack.copy(); + standard.amount = 8000; + fluidInv.setFluidInSlot(getSlotIndex(), AEFluidStack.create(standard)); + } super.putStack(tmp); } else { super.putStack(null); + if (fluidInv != null) { + fluidInv.setFluidInSlot(getSlotIndex(), null); + } } } diff --git a/src/main/java/com/glodblock/github/util/DualityFluidInterface.java b/src/main/java/com/glodblock/github/util/DualityFluidInterface.java new file mode 100644 index 00000000..50febdf1 --- /dev/null +++ b/src/main/java/com/glodblock/github/util/DualityFluidInterface.java @@ -0,0 +1,434 @@ +package com.glodblock.github.util; + +import appeng.api.config.Actionable; +import appeng.api.config.Upgrades; +import appeng.api.implementations.IUpgradeableHost; +import appeng.api.networking.GridFlags; +import appeng.api.networking.IGridNode; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.MachineSource; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IStorageMonitorable; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.util.IConfigManager; +import appeng.core.settings.TickRates; +import appeng.helpers.IInterfaceHost; +import appeng.me.GridAccessException; +import appeng.me.helpers.AENetworkProxy; +import appeng.me.storage.MEMonitorPassThrough; +import appeng.me.storage.NullInventory; +import appeng.util.ConfigManager; +import appeng.util.IConfigManagerHost; +import appeng.util.Platform; +import appeng.util.item.AEFluidStack; +import com.glodblock.github.inventory.AEFluidInventory; +import com.glodblock.github.inventory.IAEFluidInventory; +import com.glodblock.github.inventory.IAEFluidTank; +import com.glodblock.github.inventory.MEMonitorIFluidHandler; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; + +import java.util.Objects; + +public class DualityFluidInterface implements IGridTickable, IStorageMonitorable, IAEFluidInventory, IUpgradeableHost, IConfigManagerHost, IFluidHandler { + + public static final int NUMBER_OF_TANKS = 6; + public static final long TANK_CAPACITY = 16000; + private final ConfigManager cm = new ConfigManager(this); + private final AENetworkProxy gridProxy; + private final IInterfaceHost iHost; + private final BaseActionSource mySource; + private boolean hasConfig = false; + private final AEFluidInventory tanks = new AEFluidInventory(this, NUMBER_OF_TANKS, (int) TANK_CAPACITY); + private final AEFluidInventory config = new AEFluidInventory( this, NUMBER_OF_TANKS, Integer.MAX_VALUE ); + private final IAEFluidStack[] requireWork; + private int isWorking = -1; + private final MEMonitorPassThrough items = new MEMonitorPassThrough( new NullInventory(), StorageChannel.ITEMS ); + private final MEMonitorPassThrough fluids = new MEMonitorPassThrough(new NullInventory<>(), StorageChannel.FLUIDS ); + private boolean resetConfigCache = true; + + public DualityFluidInterface(final AENetworkProxy networkProxy, final IInterfaceHost ih) { + this.gridProxy = networkProxy; + this.gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL); + this.iHost = ih; + this.mySource = new MachineSource(this.iHost); + this.fluids.setChangeSource(this.mySource); + this.items.setChangeSource(this.mySource); + this.requireWork = new IAEFluidStack[6]; + + for(int i = 0; i < 6; ++i) { + this.requireWork[i] = null; + } + } + + public IAEFluidStack getStandardFluid(IAEFluidStack fluid) { + if (fluid == null) { + return null; + } + else { + return AEFluidStack.create(new FluidStack(fluid.getFluid(), 8000)); + } + } + + public IAEFluidStack getStandardFluid(FluidStack fluid) { + if (fluid == null) { + return null; + } + else { + return AEFluidStack.create(new FluidStack(fluid.getFluid(), 8000)); + } + } + + public void onChannelStateChange(final MENetworkChannelsChanged c) { + this.notifyNeighbors(); + } + + public void onPowerStateChange(final MENetworkPowerStatusChange c) { + this.notifyNeighbors(); + } + + public void gridChanged() { + try { + this.items.setInternal(this.gridProxy.getStorage().getItemInventory()); + this.fluids.setInternal(this.gridProxy.getStorage().getFluidInventory()); + } catch (GridAccessException var2) { + this.items.setInternal(new NullInventory<>()); + this.fluids.setInternal(new NullInventory<>()); + } + this.notifyNeighbors(); + } + + public void writeToNBT(NBTTagCompound data) { + this.tanks.writeToNBT(data, "storage"); + this.config.writeToNBT(data, "config"); + } + + public void readFromNBT(NBTTagCompound data) { + this.config.readFromNBT(data, "config"); + this.tanks.readFromNBT(data, "storage"); + this.readConfig(); + } + + public AEFluidInventory getConfig() { + return this.config; + } + + public AEFluidInventory getTanks() { + return this.tanks; + } + + private IMEMonitor getFluidGrid() { + try { + return gridProxy.getGrid().getCache(IStorageGrid.class).getFluidInventory(); + } catch (GridAccessException e) { + return null; + } + } + + @Override + public int getInstalledUpgrades(Upgrades u) { + return 0; + } + + @Override + public TileEntity getTile() { + return (TileEntity) (this.iHost instanceof TileEntity ? this.iHost : null); + } + + @Override + public IInventory getInventoryByName(String name) { + return null; + } + + public IFluidHandler getFluidInventoryByName(String name) { + return name.equals("config") ? this.config : null; + } + + @Override + public TickingRequest getTickingRequest(IGridNode node) { + return new TickingRequest(TickRates.Interface.getMin(), TickRates.Interface.getMax(), !this.hasWorkToDo(), true); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) { + if (!this.gridProxy.isActive()) { + return TickRateModulation.SLEEP; + } else { + boolean couldDoWork = this.updateStorage(); + return this.hasWorkToDo() ? (couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER) : TickRateModulation.SLEEP; + } + } + + @Override + public IMEMonitor getItemInventory() { + if( this.hasConfig ) + { + return null; + } + return this.items; + } + + @Override + public IMEMonitor getFluidInventory() { + if( this.hasConfig ) + { + if (this.resetConfigCache) { + this.resetConfigCache = false; + return new InterfaceInventory(this); + } + } + return this.fluids; + } + + @Override + public IConfigManager getConfigManager() { + return this.cm; + } + + @Override + public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue) { + + } + + @Override + public void onFluidInventoryChanged(IAEFluidTank inventory, int slot) { + if (this.isWorking != slot) { + boolean had; + if (inventory == this.config) { + had = this.hasConfig; + this.readConfig(); + if (had != this.hasConfig) { + this.resetConfigCache = true; + this.notifyNeighbors(); + } + } else if (inventory == this.tanks) { + this.saveChanges(); + had = this.hasWorkToDo(); + this.updatePlan(slot); + boolean now = this.hasWorkToDo(); + if (had != now) { + try { + if (now) { + this.gridProxy.getTick().alertDevice(this.gridProxy.getNode()); + } else { + this.gridProxy.getTick().sleepDevice(this.gridProxy.getNode()); + } + } catch (GridAccessException ignored) { + } + } + } + + } + } + + private boolean hasWorkToDo() { + for (IAEFluidStack requiredWork : this.requireWork) { + if (requiredWork != null) { + return true; + } + } + return false; + } + + private boolean updateStorage() { + boolean didSomething = false; + for(int x = 0; x < 6; ++x) { + if (this.requireWork[x] != null) { + didSomething = this.usePlan(x) || didSomething; + } + } + return didSomething; + } + + private boolean usePlan(int slot) { + IAEFluidStack work = this.requireWork[slot]; + this.isWorking = slot; + boolean changed = false; + + IMEInventory dest = getFluidGrid(); + if (dest == null) { + this.isWorking = -1; + return false; + } + IAEFluidStack toStore; + if (work.getStackSize() > 0L) { + if ((long)this.tanks.fill(slot, work.getFluidStack(), false) != work.getStackSize()) { + changed = true; + } else if (Objects.requireNonNull(getFluidGrid()).getStorageList().findPrecise(work) != null) { + toStore = dest.extractItems(work, Actionable.MODULATE, this.mySource); + if (toStore != null) { + changed = true; + int filled = this.tanks.fill(slot, toStore.getFluidStack(), true); + if ((long)filled != toStore.getStackSize()) { + throw new IllegalStateException("bad attempt at managing tanks. ( fill )"); + } + } + } + } else if (work.getStackSize() < 0L) { + toStore = work.copy(); + toStore.setStackSize(-toStore.getStackSize()); + FluidStack canExtract = this.tanks.drain(slot, toStore.getFluidStack(), false); + if (canExtract != null && (long)canExtract.amount == toStore.getStackSize()) { + IAEFluidStack notStored = dest.injectItems(toStore, Actionable.MODULATE, this.mySource);; + toStore.setStackSize(toStore.getStackSize() - (notStored == null ? 0L : notStored.getStackSize())); + if (toStore.getStackSize() > 0L) { + changed = true; + FluidStack removed = this.tanks.drain(slot, toStore.getFluidStack(), true); + if (removed == null || toStore.getStackSize() != (long)removed.amount) { + throw new IllegalStateException("bad attempt at managing tanks. ( drain )"); + } + } + } else { + changed = true; + } + } + + if (changed) { + this.updatePlan(slot); + } + + this.isWorking = -1; + return changed; + } + + private void updatePlan(int slot) { + IAEFluidStack req = this.config.getFluidInSlot(slot); + IAEFluidStack stored = this.tanks.getFluidInSlot(slot); + IAEFluidStack work; + if (req == null && stored != null && stored.getStackSize() > 0L) { + work = stored.copy(); + this.requireWork[slot] = work.setStackSize(-work.getStackSize()); + } else { + if (req != null) { + if (stored == null || stored.getStackSize() == 0L) { + this.requireWork[slot] = req.copy(); + this.requireWork[slot].setStackSize(TANK_CAPACITY); + return; + } + + if (!req.equals(stored)) { + work = stored.copy(); + this.requireWork[slot] = work.setStackSize(-work.getStackSize()); + return; + } + + if (stored.getStackSize() < TANK_CAPACITY) { + this.requireWork[slot] = req.copy(); + this.requireWork[slot].setStackSize(TANK_CAPACITY - stored.getStackSize()); + return; + } + } + this.requireWork[slot] = null; + } + } + + public void notifyNeighbors() { + if (this.gridProxy.isActive()) { + try { + this.gridProxy.getTick().wakeDevice(this.gridProxy.getNode()); + } catch (GridAccessException ignored) { + } + } + TileEntity te = this.iHost.getTileEntity(); + if (te != null && te.getWorldObj() != null) { + Platform.notifyBlocksOfNeighbors(te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord); + } + } + + public void saveChanges() { + this.iHost.saveChanges(); + } + + private void readConfig() { + this.hasConfig = false; + + for(int i = 0; i < this.config.getSlots(); ++i) { + if (this.config.getFluidInSlot(i) != null) { + this.hasConfig = true; + break; + } + } + + boolean had = this.hasWorkToDo(); + + for(int x = 0; x < 6; ++x) { + this.updatePlan(x); + } + + boolean has = this.hasWorkToDo(); + if (had != has) { + try { + if (has) { + this.gridProxy.getTick().alertDevice(this.gridProxy.getNode()); + } else { + this.gridProxy.getTick().sleepDevice(this.gridProxy.getNode()); + } + } catch (GridAccessException ignored) { + } + } + + this.notifyNeighbors(); + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + IMEMonitor fluidGrid = getFluidGrid(); + if (fluidGrid == null || resource == null) + return 0; + int ori = resource.amount; + IAEFluidStack remove; + if (doFill) { + remove = fluidGrid.injectItems(AEFluidStack.create(resource), Actionable.MODULATE, this.mySource); + } else { + remove = fluidGrid.injectItems(AEFluidStack.create(resource), Actionable.SIMULATE, this.mySource); + } + return remove == null ? ori : (int) (ori - remove.getStackSize()); + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + return this.tanks.drain(from, resource, doDrain); + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return this.tanks.drain(from, maxDrain, doDrain); + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) { + return true; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return true; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + return this.tanks.getTankInfo(from); + } + + private static class InterfaceInventory extends MEMonitorIFluidHandler { + InterfaceInventory(DualityFluidInterface tileInterface) { + super(tileInterface.tanks); + } + } + +}