From 15013cb4b2b35d46dc5706db49ee5589b744b198 Mon Sep 17 00:00:00 2001 From: Oleg Kalandarashvili Date: Thu, 30 Jan 2020 12:58:47 +0300 Subject: [PATCH] Fluid mode for storage monitor. Implements #2234 (#2413) --- .../node/StorageMonitorNetworkNode.java | 165 +++++++++++++++++- .../container/StorageMonitorContainer.java | 6 +- .../tesr/StorageMonitorTileRenderer.java | 161 ++++++++++++----- .../screen/StorageMonitorScreen.java | 2 + .../tile/StorageMonitorTile.java | 31 +++- 5 files changed, 307 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/StorageMonitorNetworkNode.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/StorageMonitorNetworkNode.java index f474114b3..3301fa144 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/StorageMonitorNetworkNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/StorageMonitorNetworkNode.java @@ -5,9 +5,12 @@ import com.raoulvdberge.refinedstorage.api.network.security.Permission; import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.inventory.fluid.FluidInventory; import com.raoulvdberge.refinedstorage.inventory.item.BaseItemHandler; import com.raoulvdberge.refinedstorage.inventory.listener.NetworkNodeInventoryListener; +import com.raoulvdberge.refinedstorage.tile.StorageMonitorTile; import com.raoulvdberge.refinedstorage.tile.config.IComparable; +import com.raoulvdberge.refinedstorage.tile.config.IType; import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode; import com.raoulvdberge.refinedstorage.util.StackUtils; import com.raoulvdberge.refinedstorage.util.WorldUtils; @@ -20,17 +23,23 @@ import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidAttributes; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; import org.apache.commons.lang3.tuple.Pair; import java.util.HashMap; import java.util.Map; -public class StorageMonitorNetworkNode extends NetworkNode implements IComparable { +public class StorageMonitorNetworkNode extends NetworkNode implements IComparable, IType { public static final int DEPOSIT_ALL_MAX_DELAY = 500; public static final ResourceLocation ID = new ResourceLocation(RS.ID, "storage_monitor"); private static final String NBT_COMPARE = "Compare"; + private static final String NBT_TYPE = "Type"; + private static final String NBT_FLUID_FILTERS = "FluidFilters"; private BaseItemHandler itemFilter = new BaseItemHandler(1) .addListener(new NetworkNodeInventoryListener(this)) @@ -40,9 +49,16 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl } }); + private FluidInventory fluidFilter = new FluidInventory(1, 1000) + .addListener((handler, slot, reading) -> { + if (!reading) { + WorldUtils.updateBlock(world, pos); + } + }); private Map> deposits = new HashMap<>(); private int compare = IComparer.COMPARE_NBT; + private int type = IType.ITEMS; private int oldAmount = -1; @@ -66,6 +82,9 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl } public ActionResultType depositAll(PlayerEntity player) { + if (getType() != IType.ITEMS) { + return ActionResultType.FAIL; + } if (network == null) { return ActionResultType.FAIL; } @@ -105,6 +124,16 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl return ActionResultType.FAIL; } + if (getType() == IType.ITEMS) { + depositItems(player, toInsert); + } else if (getType() == IType.FLUIDS) { + depositFluids(player, toInsert); + } + + return ActionResultType.SUCCESS; + } + + private void depositItems(PlayerEntity player, ItemStack toInsert) { ItemStack filter = itemFilter.getStackInSlot(0); if (!filter.isEmpty() && API.instance().getComparer().isEqual(filter, toInsert, compare)) { @@ -112,8 +141,28 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl deposits.put(player.getGameProfile().getName(), Pair.of(toInsert, System.currentTimeMillis())); } + } - return ActionResultType.SUCCESS; + private void depositFluids(PlayerEntity player, ItemStack toInsert) { + FluidStack filter = fluidFilter.getFluid(0); + Pair result = StackUtils.getFluid(toInsert, true); + if (filter.isEmpty() || !API.instance().getComparer().isEqual(filter, result.getRight(), compare)) { + return; + } + if (!result.getValue().isEmpty() && network.insertFluid(result.getValue(), result.getValue().getAmount(), Action.SIMULATE).isEmpty()) { + network.getFluidStorageTracker().changed(player, result.getValue().copy()); + + result = StackUtils.getFluid(toInsert, false); + + network.insertFluidTracked(result.getValue(), result.getValue().getAmount()); + + player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY); + + ItemStack container = result.getLeft(); + if (!player.inventory.addItemStackToInventory(container.copy())) { + InventoryHelper.spawnItemStack(player.getEntityWorld(), player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), container); + } + } } public void extract(PlayerEntity player, Direction side) { @@ -125,6 +174,14 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl return; } + if (getType() == IType.ITEMS) { + extractItems(player); + } else if (getType() == IType.FLUIDS) { + extractFluids(player); + } + } + + private void extractItems(PlayerEntity player) { ItemStack filter = itemFilter.getStackInSlot(0); int toExtract = player.isCrouching() ? 1 : 64; @@ -132,8 +189,58 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl if (!filter.isEmpty()) { ItemStack result = network.extractItem(filter, toExtract, compare, Action.PERFORM); - if (!result.isEmpty() && !player.inventory.addItemStackToInventory(result.copy())) { - InventoryHelper.spawnItemStack(world, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), result); + if (!result.isEmpty()) { + if (!player.inventory.addItemStackToInventory(result.copy())) { + InventoryHelper.spawnItemStack(world, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), result); + } + } + } + } + + private void extractFluids(PlayerEntity player) { + + FluidStack filter = fluidFilter.getFluid(0); + + if (filter.isEmpty()) { + return; + } + + FluidStack stack = network.getFluidStorageCache().getList().get(filter); + if (stack == null || stack.getAmount() < FluidAttributes.BUCKET_VOLUME) { + return; + } + + boolean shift = player.isCrouching(); + if (shift) { + ItemStack bucket = ItemStack.EMPTY; + + for (int i = 0; i < player.inventory.getSizeInventory(); ++i) { + ItemStack slot = player.inventory.getStackInSlot(i); + + if (API.instance().getComparer().isEqualNoQuantity(StackUtils.EMPTY_BUCKET, slot)) { + bucket = StackUtils.EMPTY_BUCKET.copy(); + + player.inventory.decrStackSize(i, 1); + + break; + } + } + + if (bucket.isEmpty()) { + bucket = network.extractItem(StackUtils.EMPTY_BUCKET, 1, Action.PERFORM); + } + + if (!bucket.isEmpty()) { + bucket.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null).ifPresent(fluidHandler -> { + + network.getFluidStorageTracker().changed(player, stack.copy()); + + fluidHandler.fill(network.extractFluid(stack, FluidAttributes.BUCKET_VOLUME, Action.PERFORM), IFluidHandler.FluidAction.EXECUTE); + + if (!player.inventory.addItemStackToInventory(fluidHandler.getContainer().copy())) { + InventoryHelper.spawnItemStack(player.getEntityWorld(), player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), fluidHandler.getContainer()); + } + }); } } } @@ -167,9 +274,12 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl super.writeConfiguration(tag); tag.putInt(NBT_COMPARE, compare); + tag.putInt(NBT_TYPE, type); StackUtils.writeItems(itemFilter, 0, tag); + tag.put(NBT_FLUID_FILTERS, fluidFilter.writeToNbt()); + return tag; } @@ -181,7 +291,15 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl compare = tag.getInt(NBT_COMPARE); } + if (tag.contains(NBT_TYPE)) { + type = tag.getInt(NBT_TYPE); + } + StackUtils.readItems(itemFilter, 0, tag); + + if (tag.contains(NBT_FLUID_FILTERS)) { + fluidFilter.readFromNbt(tag.getCompound(NBT_FLUID_FILTERS)); + } } public int getAmount() { @@ -189,21 +307,50 @@ public class StorageMonitorNetworkNode extends NetworkNode implements IComparabl return 0; } - ItemStack toCheck = itemFilter.getStackInSlot(0); + if (getType() == IType.ITEMS) { + ItemStack toCheck = itemFilter.getStackInSlot(0); - if (toCheck.isEmpty()) { - return 0; + if (toCheck.isEmpty()) { + return 0; + } + + ItemStack stored = network.getItemStorageCache().getList().get(toCheck, compare); + + return stored != null ? stored.getCount() : 0; + } else if (getType() == IType.FLUIDS) { + FluidStack toCheck = fluidFilter.getFluid(0); + if (toCheck.isEmpty()) { + return 0; + } + + FluidStack stored = network.getFluidStorageCache().getList().get(toCheck, compare); + return stored != null ? stored.getAmount() : 0; } + return 0; + } - ItemStack stored = network.getItemStorageCache().getList().get(toCheck, compare); + @Override + public int getType() { + return world.isRemote ? StorageMonitorTile.TYPE.getValue() : type; + } - return stored != null ? stored.getCount() : 0; + @Override + public void setType(int type) { + this.type = type; + + WorldUtils.updateBlock(world, pos); + markDirty(); } public BaseItemHandler getItemFilters() { return itemFilter; } + @Override + public FluidInventory getFluidFilters() { + return fluidFilter; + } + @Override public void setRedstoneMode(RedstoneMode mode) { // NO OP diff --git a/src/main/java/com/raoulvdberge/refinedstorage/container/StorageMonitorContainer.java b/src/main/java/com/raoulvdberge/refinedstorage/container/StorageMonitorContainer.java index 9148fa1af..fb131b8cf 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/container/StorageMonitorContainer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/container/StorageMonitorContainer.java @@ -2,17 +2,21 @@ package com.raoulvdberge.refinedstorage.container; import com.raoulvdberge.refinedstorage.RSContainers; import com.raoulvdberge.refinedstorage.container.slot.filter.FilterSlot; +import com.raoulvdberge.refinedstorage.container.slot.filter.FluidFilterSlot; import com.raoulvdberge.refinedstorage.tile.StorageMonitorTile; +import com.raoulvdberge.refinedstorage.tile.config.IType; import net.minecraft.entity.player.PlayerEntity; public class StorageMonitorContainer extends BaseContainer { public StorageMonitorContainer(StorageMonitorTile storageMonitor, PlayerEntity player, int windowId) { super(RSContainers.STORAGE_MONITOR, storageMonitor, player, windowId); - addSlot(new FilterSlot(storageMonitor.getNode().getItemFilters(), 0, 80, 20)); + addSlot(new FilterSlot(storageMonitor.getNode().getItemFilters(), 0, 80, 20).setEnableHandler(() -> storageMonitor.getNode().getType() == IType.ITEMS)); + addSlot(new FluidFilterSlot(storageMonitor.getNode().getFluidFilters(), 0, 80, 20).setEnableHandler(() -> storageMonitor.getNode().getType() == IType.FLUIDS)); addPlayerInventory(8, 55); transferManager.addItemFilterTransfer(player.inventory, storageMonitor.getNode().getItemFilters()); + transferManager.addFluidFilterTransfer(player.inventory, storageMonitor.getNode().getFluidFilters()); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/StorageMonitorTileRenderer.java b/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/StorageMonitorTileRenderer.java index b8d7a87a0..78484b55e 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/StorageMonitorTileRenderer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/StorageMonitorTileRenderer.java @@ -1,28 +1,41 @@ package com.raoulvdberge.refinedstorage.render.tesr; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.block.StorageMonitorBlock; import com.raoulvdberge.refinedstorage.tile.StorageMonitorTile; +import com.raoulvdberge.refinedstorage.tile.config.IType; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.fluid.Fluid; +import net.minecraft.inventory.container.PlayerContainer; +import net.minecraft.item.ItemStack; import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.model.TransformationHelper; +import net.minecraftforge.fluids.FluidAttributes; +import net.minecraftforge.fluids.FluidStack; public class StorageMonitorTileRenderer extends TileEntityRenderer { + public static final int DEFAULT_LIGHTMAP = 15728880; + public StorageMonitorTileRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } @Override public void render(StorageMonitorTile tile, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer renderTypeBuffer, int i, int i1) { + Minecraft.getInstance().getProfiler().startSection("StorageMonitorTileRenderer"); Direction direction = Direction.NORTH; BlockState state = tile.getWorld().getBlockState(tile.getPos()); @@ -30,67 +43,125 @@ public class StorageMonitorTileRenderer extends TileEntityRenderer> 16 & 0xFF; + final int colorGreen = fluidColor >> 8 & 0xFF; + final int colorBlue = fluidColor & 0xFF; + final int colorAlpha = fluidColor >> 24 & 0xFF; + buffer.pos(matrixStack.getLast().getPositionMatrix(), -0.5F, -0.5F, 0F) + .color(colorRed, colorGreen, colorBlue, colorAlpha) + .tex(sprite.getMinU(), sprite.getMinV()) + .lightmap(light) + .endVertex(); + buffer.pos(matrixStack.getLast().getPositionMatrix(), 0.5F, -0.5F, 0F) + .color(colorRed, colorGreen, colorBlue, colorAlpha) + .tex(sprite.getMaxU(), sprite.getMinV()) + .lightmap(light) + .endVertex(); + buffer.pos(matrixStack.getLast().getPositionMatrix(), 0.5F, -1.5F, 0F) + .color(colorRed, colorGreen, colorBlue, colorAlpha) + .tex(sprite.getMaxU(), sprite.getMaxV()) + .lightmap(light) + .endVertex(); + buffer.pos(matrixStack.getLast().getPositionMatrix(), -0.5F, -1.5F, 0F) + .color(colorRed, colorGreen, colorBlue, colorAlpha) + .tex(sprite.getMinU(), sprite.getMaxV()) + .lightmap(light) + .endVertex(); - Minecraft.getInstance().fontRenderer.renderString( - amount, - 0, - 0, - -1, - false, - matrixStack.getLast().getPositionMatrix(), - renderTypeBuffer, - false, - 0, - 15728880 - ); - - // Pop - matrixStack.pop(); - } + matrixStack.pop(); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/screen/StorageMonitorScreen.java b/src/main/java/com/raoulvdberge/refinedstorage/screen/StorageMonitorScreen.java index 7d895fe53..406ec4fca 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/screen/StorageMonitorScreen.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/screen/StorageMonitorScreen.java @@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.screen; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.container.StorageMonitorContainer; import com.raoulvdberge.refinedstorage.screen.widget.sidebutton.ExactModeSideButton; +import com.raoulvdberge.refinedstorage.screen.widget.sidebutton.TypeSideButton; import com.raoulvdberge.refinedstorage.tile.StorageMonitorTile; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.PlayerInventory; @@ -15,6 +16,7 @@ public class StorageMonitorScreen extends BaseScreen { @Override public void onPostInit(int x, int y) { + addSideButton(new TypeSideButton(this, StorageMonitorTile.TYPE)); addSideButton(new ExactModeSideButton(this, StorageMonitorTile.COMPARE)); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/StorageMonitorTile.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/StorageMonitorTile.java index 56aa863dc..64730d10a 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/StorageMonitorTile.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/StorageMonitorTile.java @@ -3,28 +3,37 @@ package com.raoulvdberge.refinedstorage.tile; import com.raoulvdberge.refinedstorage.RSTiles; import com.raoulvdberge.refinedstorage.apiimpl.network.node.StorageMonitorNetworkNode; import com.raoulvdberge.refinedstorage.tile.config.IComparable; +import com.raoulvdberge.refinedstorage.tile.config.IType; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; import javax.annotation.Nullable; public class StorageMonitorTile extends NetworkNodeTile { public static final TileDataParameter COMPARE = IComparable.createParameter(); + public static final TileDataParameter TYPE = IType.createParameter(); + private static final String NBT_TYPE = "Type"; + private static final String NBT_FLUIDSTACK = "FluidStack"; private static final String NBT_STACK = "Stack"; private static final String NBT_AMOUNT = "Amount"; + private int type; private int amount; @Nullable - private ItemStack itemStack; + private ItemStack itemStack = ItemStack.EMPTY; + @Nullable + private FluidStack fluidStack = FluidStack.EMPTY; public StorageMonitorTile() { super(RSTiles.STORAGE_MONITOR); dataManager.addWatchedParameter(COMPARE); + dataManager.addWatchedParameter(TYPE); } @Override @@ -42,6 +51,12 @@ public class StorageMonitorTile extends NetworkNodeTile