diff --git a/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java new file mode 100644 index 00000000..847b26e1 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/GuiFluidLevelMaintainer.java @@ -0,0 +1,4 @@ +package com.glodblock.github.client; + +public class GuiFluidLevelMaintainer { +} diff --git a/src/main/java/com/glodblock/github/client/GuiIngredientBuffer.java b/src/main/java/com/glodblock/github/client/GuiIngredientBuffer.java index c4181619..9fd68d60 100644 --- a/src/main/java/com/glodblock/github/client/GuiIngredientBuffer.java +++ b/src/main/java/com/glodblock/github/client/GuiIngredientBuffer.java @@ -21,7 +21,7 @@ import net.minecraft.util.ResourceLocation; import java.io.IOException; -public class GuiIngredientBuffer extends AEBaseGui { +public class GuiIngredientBuffer extends AEBaseGui { private static final ResourceLocation TEX_BG = FluidCraft.resource("textures/gui/ingredient_buffer.png"); private static final int TANK_X = 47, TANK_X_OFF = 22, TANK_Y = 18; @@ -32,7 +32,7 @@ public class GuiIngredientBuffer extends AEBaseGui { public GuiIngredientBuffer(InventoryPlayer ipl, TileIngredientBuffer tile) { super(new ContainerIngredientBuffer(ipl, tile)); - this.cont = (ContainerIngredientBuffer)inventorySlots; + this.cont = (ContainerIngredientBuffer) inventorySlots; this.ySize = 222; for (int i = 0; i < 4; i++) { mouseRegions.addRegion(TANK_X + TANK_X_OFF * i, TANK_Y, TANK_WIDTH, TANK_HEIGHT, diff --git a/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java new file mode 100644 index 00000000..12105383 --- /dev/null +++ b/src/main/java/com/glodblock/github/client/container/ContainerFluidLevelMaintainer.java @@ -0,0 +1,64 @@ +package com.glodblock.github.client.container; + +import appeng.api.storage.data.IAEItemStack; +import appeng.container.AEBaseContainer; +import appeng.container.slot.SlotFake; +import com.glodblock.github.common.item.ItemFluidDrop; +import com.glodblock.github.common.item.ItemFluidPacket; +import com.glodblock.github.common.tile.TileFluidLevelMaintainer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; +import net.minecraftforge.items.IItemHandler; + +import java.util.Objects; + +public class ContainerFluidLevelMaintainer extends AEBaseContainer { + + private final TileFluidLevelMaintainer tile; + + public ContainerFluidLevelMaintainer(InventoryPlayer ip, TileFluidLevelMaintainer tile) { + super(ip, tile); + this.tile = tile; + IItemHandler inv = tile.getInventoryHandler(); + for (int i = 0; i < 5; i++) { + addSlotToContainer(new DisplayFluidSlot(inv, i, 17, 19 + i * 20)); + } + bindPlayerInventory(ip, 0, 132); + } + + public TileFluidLevelMaintainer getTile() { + return tile; + } + + private static class DisplayFluidSlot extends SlotFake { + + IItemHandler icv; + + public DisplayFluidSlot(IItemHandler inv, int idx, int x, int y) { + super(inv, idx, x, y); + this.icv = inv; + } + + public void putStack(ItemStack is) { + if (is.isEmpty()) { + super.putStack(is); + return; + } + if (is.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)) { + IFluidTankProperties[] tanks = Objects.requireNonNull( + is.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)) + .getTankProperties(); + for (IFluidTankProperties tank : tanks) { + ItemStack drops = ItemFluidDrop.newStack(tank.getContents()); + super.putStack(drops); + return; + } + } + super.putStack(ItemStack.EMPTY); + } + + } + +} diff --git a/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java b/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java index 368c1aa0..360d9da7 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java +++ b/src/main/java/com/glodblock/github/common/tile/TileFluidLevelMaintainer.java @@ -1,24 +1,40 @@ package com.glodblock.github.common.tile; +import appeng.api.AEApi; import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; import appeng.api.networking.GridFlags; import appeng.api.networking.crafting.ICraftingLink; import appeng.api.networking.crafting.ICraftingRequester; +import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.security.IActionSource; import appeng.api.networking.storage.IStackWatcher; import appeng.api.networking.storage.IStackWatcherHost; +import appeng.api.networking.storage.IStorageGrid; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IStorageChannel; +import appeng.api.storage.channels.IFluidStorageChannel; +import appeng.api.storage.channels.IItemStorageChannel; +import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; +import appeng.core.AELog; +import appeng.fluids.util.AEFluidStack; import appeng.helpers.MultiCraftingTracker; import appeng.helpers.Reflected; +import appeng.me.GridAccessException; +import appeng.me.helpers.MachineSource; import appeng.tile.grid.AENetworkTile; import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.util.inv.IAEAppEngInventory; import appeng.util.inv.InvOperation; +import com.glodblock.github.common.item.ItemFluidDrop; +import com.glodblock.github.util.DummyInvAdaptor; import com.google.common.collect.ImmutableSet; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.IItemHandler; public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWatcherHost, ICraftingRequester, IAEAppEngInventory { @@ -27,37 +43,157 @@ public class TileFluidLevelMaintainer extends AENetworkTile implements IStackWat private final AppEngInternalAEInventory config = new AppEngInternalAEInventory(this, MAX_FLUID); private final MultiCraftingTracker craftingTracker = new MultiCraftingTracker(this, MAX_FLUID); + private final long[] request = new long[MAX_FLUID]; + private final long[] reportValue = new long[MAX_FLUID]; private IStackWatcher watcher; + private final IActionSource source; @Reflected public TileFluidLevelMaintainer() { getProxy().setIdlePowerUsage(2D); getProxy().setFlags(GridFlags.REQUIRE_CHANNEL); + this.source = new MachineSource( this ); + } + + public void setConfig(int id, IAEItemStack item) { + if (id < 0 || id > MAX_FLUID) { + return; + } + this.config.setStackInSlot(id, item.getDefinition()); + } + + public void setRequest(int id, long amount) { + if (id < 0 || id > MAX_FLUID) { + return; + } + this.request[id] = amount; + } + + public IItemHandler getInventoryHandler() { + return this.config; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + for (int i = 0; i < MAX_FLUID; i ++) { + request[i] = data.getLong("req" + i); + reportValue[i] = data.getLong("rep" + i); + } + config.readFromNBT(data, "configX"); + craftingTracker.readFromNBT(data); + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + for (int i = 0; i < MAX_FLUID; i ++) { + data.setLong("req" + i, request[i]); + data.setLong("rep" + i, reportValue[i]); + } + config.writeToNBT(data, "configX"); + craftingTracker.writeToNBT(data); + return data; + } + + private IMEMonitor getFluidMonitor() { + return getProxy().getNode().getGrid().getCache(IStorageGrid.class) + .getInventory(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)); } @Override public ImmutableSet getRequestedJobs() { - return null; + return this.craftingTracker.getRequestedJobs(); } @Override - public IAEItemStack injectCraftedItems(ICraftingLink iCraftingLink, IAEItemStack iaeItemStack, Actionable actionable) { - return null; + public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode) { + final IMEMonitor fluidGrid = getFluidMonitor(); + + try { + + if (fluidGrid != null && this.getProxy().isActive()) { + final IEnergyGrid energy = this.getProxy().getEnergy(); + final double power = items.getStackSize() / 1000D; + + if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 ) { + ItemStack inputStack = items.getCachedItemStack( items.getStackSize() ); + + FluidStack inputFluid = ItemFluidDrop.getFluidStack(inputStack); + IAEFluidStack remaining; + + if( mode == Actionable.SIMULATE ) + { + remaining = fluidGrid.injectItems(AEFluidStack.fromFluidStack(inputFluid), Actionable.SIMULATE, source ); + items.setCachedItemStack( inputStack ); + } + else + { + remaining = fluidGrid.injectItems(AEFluidStack.fromFluidStack(inputFluid), Actionable.MODULATE, source ); + if( remaining == null || remaining.getStackSize() <= 0 ) + { + ItemStack tmp = ItemFluidDrop.newAeStack(remaining) != null ? ItemFluidDrop.newAeStack(remaining).getDefinition() : null; + items.setCachedItemStack( tmp ); + } + } + + if( ItemFluidDrop.newStack(remaining != null ? remaining.getFluidStack() : null) == inputStack ) + { + return items; + } + + return ItemFluidDrop.newAeStack(remaining); + } + } + + } catch( final GridAccessException e ) { + AELog.debug( e ); + } + + return items; } @Override - public void jobStateChange(ICraftingLink iCraftingLink) { - + public void jobStateChange(ICraftingLink link) { + this.craftingTracker.jobStateChange( link ); } @Override - public void updateWatcher(IStackWatcher iStackWatcher) { + public void updateWatcher(IStackWatcher iWatcher) { + this.watcher = iWatcher; + configureWatchers(); + } + public void configureWatchers() { + if (this.watcher != null) { + watcher.reset(); + for (int i = 0; i < MAX_FLUID; i ++ ) { + if (this.config.getAEStackInSlot(i) != null && !this.config.getAEStackInSlot(i).getDefinition().isEmpty()) { + watcher.add(this.config.getAEStackInSlot(i)); + } + } + } } @Override - public void onStackChange(IItemList iItemList, IAEStack iaeStack, IAEStack iaeStack1, IActionSource iActionSource, IStorageChannel iStorageChannel) { - + public void onStackChange(IItemList iItemList, IAEStack fullStack, IAEStack diffStack, IActionSource src, IStorageChannel chan) { + if (chan == AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class) && fullStack instanceof IAEFluidStack) { + for (int i = 0; i < MAX_FLUID; i ++) { + try { + IAEItemStack marked = this.config.getAEStackInSlot(i); + IAEFluidStack fluid = ItemFluidDrop.getAeFluidStack(marked); + if (fluid != null && fluid.getFluidStack() != null + && fluid.getFluidStack().isFluidEqual(((IAEFluidStack)diffStack).getFluidStack())) { + this.reportValue[i] = fullStack.getStackSize(); + if (this.reportValue[i] < this.config.getAEStackInSlot(i).getStackSize()) { + this.craftingTracker.handleCrafting(i, request[i], this.config.getAEStackInSlot(i), DummyInvAdaptor.INSTANCE, this.world, this.getProxy().getGrid(), this.getProxy().getCrafting(), this.source ); + } + } + } catch (GridAccessException e) { + // Ignore + } + } + } } @Override diff --git a/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java b/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java new file mode 100644 index 00000000..464a50ce --- /dev/null +++ b/src/main/java/com/glodblock/github/util/DummyInvAdaptor.java @@ -0,0 +1,62 @@ +package com.glodblock.github.util; + +import appeng.api.config.FuzzyMode; +import appeng.util.InventoryAdaptor; +import appeng.util.inv.IInventoryDestination; +import appeng.util.inv.ItemSlot; +import net.minecraft.item.ItemStack; + +import java.util.Iterator; + +/** + * This a dummy InventoryAdaptor, it has infinity capacity and infinity any items. + */ +public class DummyInvAdaptor extends InventoryAdaptor { + + public static final DummyInvAdaptor INSTANCE = new DummyInvAdaptor(); + + @Override + public ItemStack removeItems(int i, ItemStack itemStack, IInventoryDestination iInventoryDestination) { + return itemStack; + } + + @Override + public ItemStack simulateRemove(int i, ItemStack itemStack, IInventoryDestination iInventoryDestination) { + return itemStack; + } + + @Override + public ItemStack removeSimilarItems(int i, ItemStack itemStack, FuzzyMode fuzzyMode, IInventoryDestination iInventoryDestination) { + return itemStack; + } + + @Override + public ItemStack simulateSimilarRemove(int i, ItemStack itemStack, FuzzyMode fuzzyMode, IInventoryDestination iInventoryDestination) { + return itemStack; + } + + @Override + public ItemStack addItems(ItemStack itemStack) { + return null; + } + + @Override + public ItemStack simulateAdd(ItemStack itemStack) { + return null; + } + + @Override + public boolean containsItems() { + return true; + } + + @Override + public boolean hasSlots() { + return false; + } + + @Override + public Iterator iterator() { + return null; + } +} diff --git a/src/main/java/com/glodblock/github/util/NameConst.java b/src/main/java/com/glodblock/github/util/NameConst.java index a945d159..dffc098c 100644 --- a/src/main/java/com/glodblock/github/util/NameConst.java +++ b/src/main/java/com/glodblock/github/util/NameConst.java @@ -11,6 +11,7 @@ public final class NameConst { public static final String BLOCK_INGREDIENT_BUFFER = "ingredient_buffer"; public static final String BLOCK_BURETTE = "burette"; public static final String BLOCK_DUAL_INTERFACE = "dual_interface"; + public static final String BLOCK_FLUID_LEVEL_MAINTAINER = "fluid_level_maintainer"; public static final String ITEM_FLUID_DROP = "fluid_drop"; public static final String ITEM_FLUID_PACKET = "fluid_packet"; @@ -35,6 +36,7 @@ public final class NameConst { public static final String GUI_FLUID_PACKET_DECODER = GUI_KEY + BLOCK_FLUID_PACKET_DECODER; public static final String GUI_INGREDIENT_BUFFER = GUI_KEY + BLOCK_INGREDIENT_BUFFER; public static final String GUI_BURETTE = GUI_KEY + BLOCK_BURETTE; + public static final String GUI_FLUID_LEVEL_MAINTAINER = GUI_KEY + BLOCK_FLUID_LEVEL_MAINTAINER; public static final ResourceLocation MODEL_DENSE_ENCODED_PATTERN = FluidCraft.resource("builtin/dense_encoded_pattern"); public static final ResourceLocation MODEL_FLUID_PACKET = FluidCraft.resource("builtin/fluid_packet"); diff --git a/src/main/resources/assets/ae2fc/lang/en_us.lang b/src/main/resources/assets/ae2fc/lang/en_us.lang index 985e4d28..3dde123e 100644 --- a/src/main/resources/assets/ae2fc/lang/en_us.lang +++ b/src/main/resources/assets/ae2fc/lang/en_us.lang @@ -7,6 +7,7 @@ tile.ae2fc:ingredient_buffer.name=Ingredient Buffer tile.ae2fc:burette.name=Precision Burette tile.ae2fc:dual_interface.name=ME Dual Interface tile.ae2fc:part_dual_interface.name=ME Dual Interface +tile.ae2fc:fluid_level_maintainer.name=ME Fluid Level Maintainer item.ae2fc:fluid_drop.name=Drop of %s item.ae2fc:fluid_packet.name=Fluid Packet @@ -19,6 +20,7 @@ ae2fc.gui.fluid_pattern_encoder=Fluid Pattern Encoder ae2fc.gui.fluid_packet_decoder=ME Fluid Packet Decoder ae2fc.gui.ingredient_buffer=Ingredient Buffer ae2fc.gui.burette=Precision Burette +ae2fc.gui.fluid_level_maintainer=ME Fluid Level Maintainer ae2fc.tooltip.fluid_packet=Use a Fluid Packet Decoder to\nconvert this back into fluid. ae2fc.tooltip.invalid_fluid=Invalid fluid! diff --git a/src/main/resources/assets/ae2fc/textures/gui/fluid_level_maintainer.png b/src/main/resources/assets/ae2fc/textures/gui/fluid_level_maintainer.png new file mode 100644 index 00000000..85118334 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/gui/fluid_level_maintainer.png differ