From dc252ddcd2d79a657afa95d73ce20025968092d5 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:29:17 +0000 Subject: [PATCH 01/11] start on a pipe traversal system for mass colouring pipelikes --- .../gregtech/api/pipenet/block/BlockPipe.java | 15 +++- .../java/gregtech/api/util/GTUtility.java | 21 ++++++ .../gregtech/common/ToolEventHandlers.java | 2 +- .../items/behaviors/ColorSprayBehaviour.java | 69 +++++++++++++++---- 4 files changed, 91 insertions(+), 16 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 667b67fcf52..f0d58c25071 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -656,8 +656,8 @@ private List getCollisionBox(IBlockAccess world, BlockPos pos, @ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, Entity entity) { if (entity instanceof EntityPlayer) { - return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND)) || - hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND)) || + return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND), entity) || + hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND), entity) || entity.isSneaking() && isHoldingPipe((EntityPlayer) entity); } return false; @@ -665,9 +665,14 @@ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, En public abstract boolean isHoldingPipe(EntityPlayer player); - public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack) { + public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack, @Nullable Entity entity) { if (isPipeTool(stack)) return true; + if (entity != null && entity.isSneaking() && entity instanceof EntityPlayer player && + (GTUtility.isSprayCan(player.getHeldItem(EnumHand.MAIN_HAND)) || + GTUtility.isSprayCan(player.getHeldItem(EnumHand.OFF_HAND)))) + return true; + IPipeTile pipeTile = getPipeTileEntity(world, pos); if (pipeTile == null) return false; @@ -680,6 +685,10 @@ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, It return GTUtility.isCoverBehaviorItem(stack, () -> hasAnyCover, coverDef -> acceptsCovers); } + public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack) { + return hasPipeCollisionChangingItem(world, pos, stack, null); + } + @Override public boolean canRenderInLayer(@NotNull IBlockState state, @NotNull BlockRenderLayer layer) { return true; diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 553279c72f4..6d8a2de42e0 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -19,6 +19,8 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.items.behaviors.ColorSprayBehaviour; + import net.minecraft.block.BlockRedstoneWire; import net.minecraft.block.BlockSnow; import net.minecraft.block.material.MapColor; @@ -567,6 +569,25 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack, @Nullable Boolean return false; } + /** Checks if an item is a spray can for rendering the machine grid + * + * @param itemStack itemStack to check + * @return If the itemStack has the behaviour of a spray can + */ + public static boolean isSprayCan(ItemStack itemStack) { + Item item = itemStack.getItem(); + if (item instanceof MetaItem metaItem) { + MetaItem.MetaValueItem valueItem = metaItem.getItem(itemStack); + if (valueItem != null) { + for (IItemBehaviour behaviour : valueItem.getBehaviours()) { + return behaviour instanceof ColorSprayBehaviour; + } + } + } + return false; + } + + /** * Default function for tank sizes, takes a tier input and returns the corresponding size */ diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index 62195e49791..e840cc6d6d2 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -305,7 +305,7 @@ private static boolean shouldRenderGridOverlays(@NotNull IBlockState state, @Nul ItemStack mainHand, ItemStack offHand, boolean isSneaking) { if (state.getBlock() instanceof BlockPipepipe) { if (isSneaking && - (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass())) { + (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass() || GTUtility.isSprayCan(mainHand) || GTUtility.isSprayCan(offHand))) { return true; } else { Set mainToolClasses = mainHand.getItem().getToolClasses(mainHand); diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 69bf9e9640c..7dca7ff9c57 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,5 +1,9 @@ package gregtech.common.items.behaviors; +import codechicken.lib.raytracer.RayTracer; + +import gregtech.api.GTValues; +import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -22,6 +26,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import appeng.api.util.AEColor; @@ -37,6 +42,7 @@ public class ColorSprayBehaviour extends AbstractUsableBehaviour implements IIte private final ItemStack empty; private final EnumDyeColor color; private final Pair durabilityBarColors; + private static final int MAX_PIPE_TRAVERSAL_LENGTH = 256; public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) { super(totalUses); @@ -51,11 +57,11 @@ public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) { @Override public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { - ItemStack stack = player.getHeldItem(hand); + ItemStack stack = player.getHeldItem(hand); if (!player.canPlayerEdit(pos, facing, stack)) { return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); } - if (!tryPaintBlock(player, world, pos, facing)) { + if (!tryPaintBlock(player, world, pos, facing, hand)) { return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); } useItemDurability(player, hand, stack, empty.copy()); @@ -64,16 +70,16 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, EnumFacing side) { + private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, EnumFacing side, EnumHand hand) { IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); if (color == null) { return tryStripBlockColor(player, world, pos, block, side); } - return block.recolorBlock(world, pos, side, this.color) || tryPaintSpecialBlock(player, world, pos, block); + return tryPaintSpecialBlock(player, world, pos, block, hand) || block.recolorBlock(world, pos, side, this.color); } - private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block) { + private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block, EnumHand hand) { if (block == Blocks.GLASS) { IBlockState newBlockState = Blocks.STAINED_GLASS.getDefaultState() .withProperty(BlockStainedGlass.COLOR, this.color); @@ -92,10 +98,20 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos world.setBlockState(pos, newBlockState); return true; } + TileEntity te = world.getTileEntity(pos); + if (player.isSneaking() && te instanceof IPipeTile mainPipe) { + RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); + if (hitResult != null) { + EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); + if (facing != null && mainPipe.isConnected(facing)) { + traversePipes(player, world, hand, pos, facing); + block.recolorBlock(world, pos, EnumFacing.DOWN, this.color); + return true; + } + } + } if (Mods.AppliedEnergistics2.isModLoaded()) { - TileEntity te = world.getTileEntity(pos); - if (te instanceof TileCableBus) { - TileCableBus cable = (TileCableBus) te; + if (te instanceof TileCableBus cable) { // do not try to recolor if it already is this color if (cable.getColor().ordinal() != color.ordinal()) { cable.recolourBlock(null, AEColor.values()[color.ordinal()], player); @@ -106,6 +122,37 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos return false; } + private void traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, EnumFacing facing) { + startPos = startPos.offset(facing); + TileEntity connectedTe = world.getTileEntity(startPos); + int count = 1; + while (connectedTe instanceof IPipeTile connectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { + if (connectedPipe.getPaintingColor() != this.color.colorValue) { + connectedPipe.setPaintingColor(this.color.colorValue); + if (getUsesLeft(player.getHeldItem(hand)) == 1 && !player.isCreative()) { + useItemDurability(player, hand, player.getHeldItem(hand), empty.copy()); + return; + } + useItemDurability(player, hand, player.getHeldItem(hand), empty.copy()); + } + if (connectedPipe.getNumConnections() == 2) { + int connections = connectedPipe.getConnections(); + connections &= ~(1 << facing.getOpposite().getIndex()); + for (EnumFacing other: EnumFacing.VALUES) { + if ((connections & (1 << other.getIndex())) != 0) { + facing = other; + startPos = startPos.offset(facing); + connectedTe = world.getTileEntity(startPos); + count++; + break; + } + } + } else { + break; + } + } + } + @SuppressWarnings("unchecked, rawtypes") private static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, EnumFacing side) { @@ -136,8 +183,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // TileEntityPipeBase special case - if (te instanceof IPipeTile) { - IPipeTile pipe = (IPipeTile) te; + if (te instanceof IPipeTile pipe) { if (pipe.isPainted()) { pipe.setPaintingColor(-1); return true; @@ -146,8 +192,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc // AE2 cable special case if (Mods.AppliedEnergistics2.isModLoaded()) { - if (te instanceof TileCableBus) { - TileCableBus cable = (TileCableBus) te; + if (te instanceof TileCableBus cable) { // do not try to strip color if it is already colorless if (cable.getColor() != AEColor.TRANSPARENT) { cable.recolourBlock(null, AEColor.TRANSPARENT, player); From a4f96eaca68cdc1fa8e9bc00d2b1cf23faf0e7a8 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:24:12 +0000 Subject: [PATCH 02/11] add solvent support + proper chunk updates --- .../items/behaviors/ColorSprayBehaviour.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 7dca7ff9c57..6dd698d0dd2 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -74,7 +74,7 @@ private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, En IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); if (color == null) { - return tryStripBlockColor(player, world, pos, block, side); + return tryStripBlockColor(player, world, pos, block, side, hand); } return tryPaintSpecialBlock(player, world, pos, block, hand) || block.recolorBlock(world, pos, side, this.color); } @@ -105,7 +105,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); if (facing != null && mainPipe.isConnected(facing)) { traversePipes(player, world, hand, pos, facing); - block.recolorBlock(world, pos, EnumFacing.DOWN, this.color); + mainPipe.setPaintingColor(this.color.colorValue); return true; } } @@ -127,8 +127,9 @@ private void traversePipes(EntityPlayer player, World world, EnumHand hand, Bloc TileEntity connectedTe = world.getTileEntity(startPos); int count = 1; while (connectedTe instanceof IPipeTile connectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { - if (connectedPipe.getPaintingColor() != this.color.colorValue) { - connectedPipe.setPaintingColor(this.color.colorValue); + if (connectedPipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { + connectedPipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); + connectedPipe.scheduleRenderUpdate(); if (getUsesLeft(player.getHeldItem(hand)) == 1 && !player.isCreative()) { useItemDurability(player, hand, player.getHeldItem(hand), empty.copy()); return; @@ -154,8 +155,8 @@ private void traversePipes(EntityPlayer player, World world, EnumHand hand, Bloc } @SuppressWarnings("unchecked, rawtypes") - private static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, - EnumFacing side) { + private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, + EnumFacing side, EnumHand hand) { // MC special cases if (block == Blocks.STAINED_GLASS) { world.setBlockState(pos, Blocks.GLASS.getDefaultState()); @@ -184,7 +185,17 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc // TileEntityPipeBase special case if (te instanceof IPipeTile pipe) { - if (pipe.isPainted()) { + if (player.isSneaking()) { + RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); + if (hitResult != null) { + EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); + if (facing != null && pipe.isConnected(facing)) { + traversePipes(player, world, hand, pos, facing); + pipe.setPaintingColor(-1); + return true; + } + } + } else if (pipe.isPainted()) { pipe.setPaintingColor(-1); return true; } else return false; From 75473fbe385f3bdd77cf7f2d51ab544442fb1709 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:09:42 +0000 Subject: [PATCH 03/11] fix some off by one errors --- .../items/behaviors/ColorSprayBehaviour.java | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 6dd698d0dd2..cf677b88c2f 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -104,9 +104,16 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos if (hitResult != null) { EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); if (facing != null && mainPipe.isConnected(facing)) { - traversePipes(player, world, hand, pos, facing); - mainPipe.setPaintingColor(this.color.colorValue); - return true; + boolean paintedOthers = traversePipes(player, world, hand, pos, facing); + if (mainPipe.getPaintingColor() != this.color.colorValue) { + mainPipe.setPaintingColor(this.color.colorValue); + // Account for traversePipes having the durability used off by one + if (paintedOthers) { + ItemStack heldItem = player.getHeldItem(hand); + useItemDurability(player, hand, heldItem, empty.copy()); + } + return true; + } else return paintedOthers; } } } @@ -122,19 +129,27 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos return false; } - private void traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, EnumFacing facing) { + // note: automatically uses durability from recolouring pipes, apart from the last use, as this allows for proper + // animation of the item's use + private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, EnumFacing facing) { startPos = startPos.offset(facing); TileEntity connectedTe = world.getTileEntity(startPos); int count = 1; + boolean painted = false; while (connectedTe instanceof IPipeTile connectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { if (connectedPipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { connectedPipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); connectedPipe.scheduleRenderUpdate(); - if (getUsesLeft(player.getHeldItem(hand)) == 1 && !player.isCreative()) { - useItemDurability(player, hand, player.getHeldItem(hand), empty.copy()); - return; + ItemStack heldItem = player.getHeldItem(hand); + if (getUsesLeft(heldItem) == 1 && !player.isCreative()) { + useItemDurability(player, hand, heldItem, empty.copy()); + return true; } - useItemDurability(player, hand, player.getHeldItem(hand), empty.copy()); + // Off by one durability as the final use is handled by onItemUse, along with the use animation + if (painted) { + useItemDurability(player, hand, heldItem, empty.copy()); + } + painted = true; } if (connectedPipe.getNumConnections() == 2) { int connections = connectedPipe.getConnections(); @@ -152,6 +167,7 @@ private void traversePipes(EntityPlayer player, World world, EnumHand hand, Bloc break; } } + return painted; } @SuppressWarnings("unchecked, rawtypes") @@ -190,9 +206,15 @@ private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos po if (hitResult != null) { EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); if (facing != null && pipe.isConnected(facing)) { - traversePipes(player, world, hand, pos, facing); - pipe.setPaintingColor(-1); - return true; + boolean paintedOthers = traversePipes(player, world, hand, pos, facing); + if (pipe.isPainted()) { + pipe.setPaintingColor(-1); + if (paintedOthers) { + ItemStack heldItem = player.getHeldItem(hand); + useItemDurability(player, hand, heldItem, empty.copy()); + } + return true; + } else return paintedOthers; } } } else if (pipe.isPainted()) { From 3c227dd7d1de3d2ece83b0ed867b7ea0563f3faf Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:26:00 +0000 Subject: [PATCH 04/11] sprayless --- .../gregtech/api/pipenet/block/BlockPipe.java | 9 +++++--- .../java/gregtech/api/util/GTUtility.java | 7 +++---- .../gregtech/common/ToolEventHandlers.java | 3 ++- .../items/behaviors/ColorSprayBehaviour.java | 21 ++++++++++--------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index f0d58c25071..e111abfc080 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -656,8 +656,10 @@ private List getCollisionBox(IBlockAccess world, BlockPos pos, @ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, Entity entity) { if (entity instanceof EntityPlayer) { - return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND), entity) || - hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND), entity) || + return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND), + entity) || + hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND), + entity) || entity.isSneaking() && isHoldingPipe((EntityPlayer) entity); } return false; @@ -665,7 +667,8 @@ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, En public abstract boolean isHoldingPipe(EntityPlayer player); - public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack, @Nullable Entity entity) { + public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack, + @Nullable Entity entity) { if (isPipeTool(stack)) return true; if (entity != null && entity.isSneaking() && entity instanceof EntityPlayer player && diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 6d8a2de42e0..341927c4d53 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -18,7 +18,6 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.ore.OrePrefix; - import gregtech.common.items.behaviors.ColorSprayBehaviour; import net.minecraft.block.BlockRedstoneWire; @@ -569,14 +568,15 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack, @Nullable Boolean return false; } - /** Checks if an item is a spray can for rendering the machine grid + /** + * Checks if an item is a spray can for rendering the machine grid * * @param itemStack itemStack to check * @return If the itemStack has the behaviour of a spray can */ public static boolean isSprayCan(ItemStack itemStack) { Item item = itemStack.getItem(); - if (item instanceof MetaItem metaItem) { + if (item instanceof MetaItemmetaItem) { MetaItem.MetaValueItem valueItem = metaItem.getItem(itemStack); if (valueItem != null) { for (IItemBehaviour behaviour : valueItem.getBehaviours()) { @@ -587,7 +587,6 @@ public static boolean isSprayCan(ItemStack itemStack) { return false; } - /** * Default function for tank sizes, takes a tier input and returns the corresponding size */ diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index e840cc6d6d2..eb3a2e4cba4 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -305,7 +305,8 @@ private static boolean shouldRenderGridOverlays(@NotNull IBlockState state, @Nul ItemStack mainHand, ItemStack offHand, boolean isSneaking) { if (state.getBlock() instanceof BlockPipepipe) { if (isSneaking && - (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass() || GTUtility.isSprayCan(mainHand) || GTUtility.isSprayCan(offHand))) { + (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass() || + GTUtility.isSprayCan(mainHand) || GTUtility.isSprayCan(offHand))) { return true; } else { Set mainToolClasses = mainHand.getItem().getToolClasses(mainHand); diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index cf677b88c2f..9cc27303b2e 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,7 +1,5 @@ package gregtech.common.items.behaviors; -import codechicken.lib.raytracer.RayTracer; - import gregtech.api.GTValues; import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; @@ -31,6 +29,7 @@ import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; +import codechicken.lib.raytracer.RayTracer; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; @@ -57,7 +56,7 @@ public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) { @Override public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { - ItemStack stack = player.getHeldItem(hand); + ItemStack stack = player.getHeldItem(hand); if (!player.canPlayerEdit(pos, facing, stack)) { return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); } @@ -76,7 +75,8 @@ private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, En if (color == null) { return tryStripBlockColor(player, world, pos, block, side, hand); } - return tryPaintSpecialBlock(player, world, pos, block, hand) || block.recolorBlock(world, pos, side, this.color); + return tryPaintSpecialBlock(player, world, pos, block, hand) || + block.recolorBlock(world, pos, side, this.color); } private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block, EnumHand hand) { @@ -99,7 +99,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos return true; } TileEntity te = world.getTileEntity(pos); - if (player.isSneaking() && te instanceof IPipeTile mainPipe) { + if (player.isSneaking() && te instanceof IPipeTilemainPipe) { RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); if (hitResult != null) { EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); @@ -131,12 +131,13 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos // note: automatically uses durability from recolouring pipes, apart from the last use, as this allows for proper // animation of the item's use - private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, EnumFacing facing) { + private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, + EnumFacing facing) { startPos = startPos.offset(facing); TileEntity connectedTe = world.getTileEntity(startPos); int count = 1; boolean painted = false; - while (connectedTe instanceof IPipeTile connectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { + while (connectedTe instanceof IPipeTileconnectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { if (connectedPipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { connectedPipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); connectedPipe.scheduleRenderUpdate(); @@ -154,7 +155,7 @@ private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, B if (connectedPipe.getNumConnections() == 2) { int connections = connectedPipe.getConnections(); connections &= ~(1 << facing.getOpposite().getIndex()); - for (EnumFacing other: EnumFacing.VALUES) { + for (EnumFacing other : EnumFacing.VALUES) { if ((connections & (1 << other.getIndex())) != 0) { facing = other; startPos = startPos.offset(facing); @@ -172,7 +173,7 @@ private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, B @SuppressWarnings("unchecked, rawtypes") private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, - EnumFacing side, EnumHand hand) { + EnumFacing side, EnumHand hand) { // MC special cases if (block == Blocks.STAINED_GLASS) { world.setBlockState(pos, Blocks.GLASS.getDefaultState()); @@ -200,7 +201,7 @@ private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos po } // TileEntityPipeBase special case - if (te instanceof IPipeTile pipe) { + if (te instanceof IPipeTilepipe) { if (player.isSneaking()) { RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); if (hitResult != null) { From 847cab8ae751f22e9e4e81aaef69c3fb6201ba39 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:06:56 +0000 Subject: [PATCH 05/11] add tooltip --- src/main/java/gregtech/api/util/GTUtility.java | 4 ++-- src/main/java/gregtech/common/items/MetaItem1.java | 6 +++--- .../{ColorSprayBehaviour.java => ColorSprayBehavior.java} | 6 +++--- src/main/resources/assets/gregtech/lang/en_us.lang | 1 + 4 files changed, 9 insertions(+), 8 deletions(-) rename src/main/java/gregtech/common/items/behaviors/{ColorSprayBehaviour.java => ColorSprayBehavior.java} (98%) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 341927c4d53..8beba99ae85 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -18,7 +18,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.ore.OrePrefix; -import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.ColorSprayBehavior; import net.minecraft.block.BlockRedstoneWire; import net.minecraft.block.BlockSnow; @@ -580,7 +580,7 @@ public static boolean isSprayCan(ItemStack itemStack) { MetaItem.MetaValueItem valueItem = metaItem.getItem(itemStack); if (valueItem != null) { for (IItemBehaviour behaviour : valueItem.getBehaviours()) { - return behaviour instanceof ColorSprayBehaviour; + return behaviour instanceof ColorSprayBehavior; } } } diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 23c6f54c761..318ff17e2cf 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -34,7 +34,7 @@ import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.entities.GTBoatEntity.GTBoatType; import gregtech.common.items.behaviors.ClipboardBehavior; -import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.ColorSprayBehavior; import gregtech.common.items.behaviors.DataItemBehavior; import gregtech.common.items.behaviors.DoorBehavior; import gregtech.common.items.behaviors.DynamiteBehaviour; @@ -180,13 +180,13 @@ public void registerSubItems() { // out of registry order so it can reference the Empty Spray Can SPRAY_SOLVENT = addItem(60, "spray.solvent").setMaxStackSize(1) - .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 1024, -1)) + .addComponents(new ColorSprayBehavior(SPRAY_EMPTY.getStackForm(), 1024, -1)) .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); for (int i = 0; i < EnumDyeColor.values().length; i++) { SPRAY_CAN_DYES[i] = addItem(62 + i, "spray.can.dyes." + EnumDyeColor.values()[i].getName()) .setMaxStackSize(1) - .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i)) + .addComponents(new ColorSprayBehavior(SPRAY_EMPTY.getStackForm(), 512, i)) .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); } diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java similarity index 98% rename from src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java rename to src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java index 9cc27303b2e..4d5eb0ab0db 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java @@ -1,6 +1,5 @@ package gregtech.common.items.behaviors; -import gregtech.api.GTValues; import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; @@ -36,14 +35,14 @@ import java.awt.*; import java.util.List; -public class ColorSprayBehaviour extends AbstractUsableBehaviour implements IItemDurabilityManager { +public class ColorSprayBehavior extends AbstractUsableBehaviour implements IItemDurabilityManager { private final ItemStack empty; private final EnumDyeColor color; private final Pair durabilityBarColors; private static final int MAX_PIPE_TRAVERSAL_LENGTH = 256; - public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) { + public ColorSprayBehavior(ItemStack empty, int totalUses, int color) { super(totalUses); this.empty = empty; EnumDyeColor[] colors = EnumDyeColor.values(); @@ -268,6 +267,7 @@ public void addInformation(ItemStack itemStack, List lines) { } lines.add(I18n.format("behaviour.paintspray.uses", remainingUses)); lines.add(I18n.format("behaviour.paintspray.offhand")); + lines.add(I18n.format("behaviour.paintspray.crouch")); } @Override diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index d041e2f0126..3543ddadc92 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4717,6 +4717,7 @@ behaviour.paintspray.red.tooltip=Can paint things in Red behaviour.paintspray.black.tooltip=Can paint things in Black behaviour.paintspray.uses=Remaining Uses: %,d behaviour.paintspray.offhand=Hold in offhand to color while placing blocks +behaviour.paintspray.crouch=Crouch to spray a line of pipes behaviour.prospecting=Usable for Prospecting # Multiblock machine controllers From ef9eed672203069bf58a8dac96a5bf4764d1892c Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:14:41 +0000 Subject: [PATCH 06/11] review comments --- .../gregtech/common/items/behaviors/ColorSprayBehavior.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java index 4d5eb0ab0db..311aa64d780 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java @@ -134,14 +134,14 @@ private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, B EnumFacing facing) { startPos = startPos.offset(facing); TileEntity connectedTe = world.getTileEntity(startPos); - int count = 1; + int count = 0; boolean painted = false; + ItemStack heldItem = player.getHeldItem(hand); while (connectedTe instanceof IPipeTileconnectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { if (connectedPipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { connectedPipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); connectedPipe.scheduleRenderUpdate(); - ItemStack heldItem = player.getHeldItem(hand); - if (getUsesLeft(heldItem) == 1 && !player.isCreative()) { + if (getUsesLeft(heldItem) == 1) { useItemDurability(player, hand, heldItem, empty.copy()); return true; } From 0ec26628af6168d3df2887b6eb0bb1169e108194 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:03:49 +0100 Subject: [PATCH 07/11] Use a PipeNetWalker instead of manually iterating over a pipenet --- .../gregtech/common/ToolEventHandlers.java | 3 +- .../items/behaviors/ColorSprayBehavior.java | 44 +++++------- .../common/pipelike/PipeCollectorWalker.java | 69 +++++++++++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 2 +- 4 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index eb3a2e4cba4..62195e49791 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -305,8 +305,7 @@ private static boolean shouldRenderGridOverlays(@NotNull IBlockState state, @Nul ItemStack mainHand, ItemStack offHand, boolean isSneaking) { if (state.getBlock() instanceof BlockPipepipe) { if (isSneaking && - (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass() || - GTUtility.isSprayCan(mainHand) || GTUtility.isSprayCan(offHand))) { + (mainHand.isEmpty() || mainHand.getItem().getClass() == Item.getItemFromBlock(pipe).getClass())) { return true; } else { Set mainToolClasses = mainHand.getItem().getToolClasses(mainHand); diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java index 311aa64d780..aeb0883d9fa 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java @@ -7,6 +7,7 @@ import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.GradientUtil; import gregtech.api.util.Mods; +import gregtech.common.pipelike.PipeCollectorWalker; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; @@ -134,38 +135,27 @@ private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, B EnumFacing facing) { startPos = startPos.offset(facing); TileEntity connectedTe = world.getTileEntity(startPos); - int count = 0; boolean painted = false; ItemStack heldItem = player.getHeldItem(hand); - while (connectedTe instanceof IPipeTileconnectedPipe && count < MAX_PIPE_TRAVERSAL_LENGTH) { - if (connectedPipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { - connectedPipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); - connectedPipe.scheduleRenderUpdate(); - if (getUsesLeft(heldItem) == 1) { - useItemDurability(player, hand, heldItem, empty.copy()); - return true; - } - // Off by one durability as the final use is handled by onItemUse, along with the use animation - if (painted) { - useItemDurability(player, hand, heldItem, empty.copy()); - } - painted = true; - } - if (connectedPipe.getNumConnections() == 2) { - int connections = connectedPipe.getConnections(); - connections &= ~(1 << facing.getOpposite().getIndex()); - for (EnumFacing other : EnumFacing.VALUES) { - if ((connections & (1 << other.getIndex())) != 0) { - facing = other; - startPos = startPos.offset(facing); - connectedTe = world.getTileEntity(startPos); - count++; - break; + if (connectedTe instanceof IPipeTilestartPipe) { + List> pipes = PipeCollectorWalker.collectPipeNet(world, startPos, startPipe, + Math.min(MAX_PIPE_TRAVERSAL_LENGTH, getUsesLeft(heldItem))); + for (IPipeTile pipe : pipes) { + if (pipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { + pipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); + pipe.scheduleRenderUpdate(); + if (getUsesLeft(heldItem) == 1) { + useItemDurability(player, hand, heldItem, empty.copy()); + return true; + } + // Off by one durability as the final use is handled by onItemUse, along with the use animation + if (painted) { + useItemDurability(player, hand, heldItem, empty.copy()); } + painted = true; } - } else { - break; } + } return painted; } diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java new file mode 100644 index 00000000000..7e30308020d --- /dev/null +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -0,0 +1,69 @@ +package gregtech.common.pipelike; + +import gregtech.api.pipenet.PipeNetWalker; +import gregtech.api.pipenet.tile.IPipeTile; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PipeCollectorWalker> extends PipeNetWalker { + + @NotNull + @SuppressWarnings("unchecked") + public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe, + int limit) { + PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( + world, sourcePipe, 0, pipe.getClass()); + walker.traversePipeNet(limit); + return walker.isFailed() ? Collections.EMPTY_LIST : Collections.unmodifiableList(walker.pipes); + } + + public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe) { + // Default limit for a pipenet walker + return collectPipeNet(world, sourcePipe, pipe, 32768); + } + + // I love type erasure + private final Class basePipeClass; + private List pipes = new ArrayList<>(); + private BlockPos sourcePipe; + + protected PipeCollectorWalker(World world, BlockPos sourcePipe, int walkedBlocks, Class basePipeClass) { + super(world, sourcePipe, walkedBlocks); + this.sourcePipe = sourcePipe; + this.basePipeClass = basePipeClass; + } + + @Override + protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, + int walkedBlocks) { + PipeCollectorWalker walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass); + walker.pipes = pipes; + walker.sourcePipe = sourcePipe; + return walker; + } + + @Override + protected void checkPipe(T pipeTile, BlockPos pos) { + this.pipes.add(pipeTile); + } + + @Override + protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, + @Nullable TileEntity neighbourTile) { + } + + @Override + protected Class getBasePipeClass() { + return basePipeClass; + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 3543ddadc92..da15884e776 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4717,7 +4717,7 @@ behaviour.paintspray.red.tooltip=Can paint things in Red behaviour.paintspray.black.tooltip=Can paint things in Black behaviour.paintspray.uses=Remaining Uses: %,d behaviour.paintspray.offhand=Hold in offhand to color while placing blocks -behaviour.paintspray.crouch=Crouch to spray a line of pipes +behaviour.paintspray.crouch=Crouch to spray a network of pipes behaviour.prospecting=Usable for Prospecting # Multiblock machine controllers From 738cecb3a4fff47b179a4b723288c95e40e2a0d9 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:12:30 +0100 Subject: [PATCH 08/11] spartless --- .../java/gregtech/common/pipelike/PipeCollectorWalker.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index 7e30308020d..ef3c9b4de83 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -59,8 +59,7 @@ protected void checkPipe(T pipeTile, BlockPos pos) { @Override protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, - @Nullable TileEntity neighbourTile) { - } + @Nullable TileEntity neighbourTile) {} @Override protected Class getBasePipeClass() { From 30072cbc7f7b981f82529c8cffbe3f9c14149520 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:14:26 +0100 Subject: [PATCH 09/11] review comments --- .../gregtech/api/pipenet/block/BlockPipe.java | 18 +++--------------- .../items/behaviors/ColorSprayBehavior.java | 5 +++-- .../common/pipelike/PipeCollectorWalker.java | 3 +-- .../resources/assets/gregtech/lang/en_us.lang | 2 +- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index e111abfc080..667b67fcf52 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -656,10 +656,8 @@ private List getCollisionBox(IBlockAccess world, BlockPos pos, @ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, Entity entity) { if (entity instanceof EntityPlayer) { - return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND), - entity) || - hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND), - entity) || + return hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.MAIN_HAND)) || + hasPipeCollisionChangingItem(world, pos, ((EntityPlayer) entity).getHeldItem(EnumHand.OFF_HAND)) || entity.isSneaking() && isHoldingPipe((EntityPlayer) entity); } return false; @@ -667,15 +665,9 @@ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, En public abstract boolean isHoldingPipe(EntityPlayer player); - public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack, - @Nullable Entity entity) { + public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack) { if (isPipeTool(stack)) return true; - if (entity != null && entity.isSneaking() && entity instanceof EntityPlayer player && - (GTUtility.isSprayCan(player.getHeldItem(EnumHand.MAIN_HAND)) || - GTUtility.isSprayCan(player.getHeldItem(EnumHand.OFF_HAND)))) - return true; - IPipeTile pipeTile = getPipeTileEntity(world, pos); if (pipeTile == null) return false; @@ -688,10 +680,6 @@ public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, It return GTUtility.isCoverBehaviorItem(stack, () -> hasAnyCover, coverDef -> acceptsCovers); } - public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack) { - return hasPipeCollisionChangingItem(world, pos, stack, null); - } - @Override public boolean canRenderInLayer(@NotNull IBlockState state, @NotNull BlockRenderLayer layer) { return true; diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java index aeb0883d9fa..fe2e16891dd 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java @@ -140,9 +140,10 @@ private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, B if (connectedTe instanceof IPipeTilestartPipe) { List> pipes = PipeCollectorWalker.collectPipeNet(world, startPos, startPipe, Math.min(MAX_PIPE_TRAVERSAL_LENGTH, getUsesLeft(heldItem))); + int colour = this.color == null ? -1 : this.color.colorValue; for (IPipeTile pipe : pipes) { - if (pipe.getPaintingColor() != (this.color == null ? -1 : this.color.colorValue)) { - pipe.setPaintingColor(this.color == null ? -1 : this.color.colorValue); + if (pipe.getPaintingColor() != colour) { + pipe.setPaintingColor(colour); pipe.scheduleRenderUpdate(); if (getUsesLeft(heldItem) == 1) { useItemDurability(player, hand, heldItem, empty.copy()); diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index ef3c9b4de83..32a27fcacb4 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -18,13 +18,12 @@ public class PipeCollectorWalker> extends PipeNetWalker { @NotNull - @SuppressWarnings("unchecked") public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe, int limit) { PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( world, sourcePipe, 0, pipe.getClass()); walker.traversePipeNet(limit); - return walker.isFailed() ? Collections.EMPTY_LIST : Collections.unmodifiableList(walker.pipes); + return walker.isFailed() ? Collections.emptyList() : Collections.unmodifiableList(walker.pipes); } public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe) { diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index da15884e776..3116c6c975f 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4717,7 +4717,7 @@ behaviour.paintspray.red.tooltip=Can paint things in Red behaviour.paintspray.black.tooltip=Can paint things in Black behaviour.paintspray.uses=Remaining Uses: %,d behaviour.paintspray.offhand=Hold in offhand to color while placing blocks -behaviour.paintspray.crouch=Crouch to spray a network of pipes +behaviour.paintspray.crouch=Crouch to spray connected pipes behaviour.prospecting=Usable for Prospecting # Multiblock machine controllers From 92e2391898f30b98509167f2ad17b69efcee213a Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:15:28 +0100 Subject: [PATCH 10/11] forgor --- .../java/gregtech/api/util/GTUtility.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 8beba99ae85..553279c72f4 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -18,7 +18,6 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.ore.OrePrefix; -import gregtech.common.items.behaviors.ColorSprayBehavior; import net.minecraft.block.BlockRedstoneWire; import net.minecraft.block.BlockSnow; @@ -568,25 +567,6 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack, @Nullable Boolean return false; } - /** - * Checks if an item is a spray can for rendering the machine grid - * - * @param itemStack itemStack to check - * @return If the itemStack has the behaviour of a spray can - */ - public static boolean isSprayCan(ItemStack itemStack) { - Item item = itemStack.getItem(); - if (item instanceof MetaItemmetaItem) { - MetaItem.MetaValueItem valueItem = metaItem.getItem(itemStack); - if (valueItem != null) { - for (IItemBehaviour behaviour : valueItem.getBehaviours()) { - return behaviour instanceof ColorSprayBehavior; - } - } - } - return false; - } - /** * Default function for tank sizes, takes a tier input and returns the corresponding size */ From 097b3b28835abf23c156ba8b65d3a78984a8df14 Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Sat, 6 Apr 2024 21:38:02 +0100 Subject: [PATCH 11/11] Migrate to using a Function for PipeCollectorWalker --- .../items/behaviors/ColorSprayBehavior.java | 84 ++++++------------- .../common/pipelike/PipeCollectorWalker.java | 31 ++++--- 2 files changed, 42 insertions(+), 73 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java index fe2e16891dd..44c977aea3c 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehavior.java @@ -1,6 +1,5 @@ package gregtech.common.items.behaviors; -import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -22,14 +21,16 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; -import codechicken.lib.raytracer.RayTracer; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; @@ -41,7 +42,6 @@ public class ColorSprayBehavior extends AbstractUsableBehaviour implements IItem private final ItemStack empty; private final EnumDyeColor color; private final Pair durabilityBarColors; - private static final int MAX_PIPE_TRAVERSAL_LENGTH = 256; public ColorSprayBehavior(ItemStack empty, int totalUses, int color) { super(totalUses); @@ -99,23 +99,8 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos return true; } TileEntity te = world.getTileEntity(pos); - if (player.isSneaking() && te instanceof IPipeTilemainPipe) { - RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); - if (hitResult != null) { - EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); - if (facing != null && mainPipe.isConnected(facing)) { - boolean paintedOthers = traversePipes(player, world, hand, pos, facing); - if (mainPipe.getPaintingColor() != this.color.colorValue) { - mainPipe.setPaintingColor(this.color.colorValue); - // Account for traversePipes having the durability used off by one - if (paintedOthers) { - ItemStack heldItem = player.getHeldItem(hand); - useItemDurability(player, hand, heldItem, empty.copy()); - } - return true; - } else return paintedOthers; - } - } + if (player.isSneaking() && te instanceof IPipeTile) { + return traversePipes(player, world, hand, pos); } if (Mods.AppliedEnergistics2.isModLoaded()) { if (te instanceof TileCableBus cable) { @@ -131,34 +116,38 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos // note: automatically uses durability from recolouring pipes, apart from the last use, as this allows for proper // animation of the item's use - private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos, - EnumFacing facing) { - startPos = startPos.offset(facing); + private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos) { TileEntity connectedTe = world.getTileEntity(startPos); - boolean painted = false; + // I LOVE LAMBDAS + final boolean[] painted = { false }; ItemStack heldItem = player.getHeldItem(hand); + int colour = this.color == null ? -1 : this.color.colorValue; if (connectedTe instanceof IPipeTilestartPipe) { - List> pipes = PipeCollectorWalker.collectPipeNet(world, startPos, startPipe, - Math.min(MAX_PIPE_TRAVERSAL_LENGTH, getUsesLeft(heldItem))); - int colour = this.color == null ? -1 : this.color.colorValue; - for (IPipeTile pipe : pipes) { + PipeCollectorWalker.collectPipeNet(world, startPos, startPipe, pipe -> { + if (getUsesLeft(heldItem) == 0) { + return false; + } if (pipe.getPaintingColor() != colour) { pipe.setPaintingColor(colour); pipe.scheduleRenderUpdate(); if (getUsesLeft(heldItem) == 1) { - useItemDurability(player, hand, heldItem, empty.copy()); - return true; + if (painted[0]) { + useItemDurability(player, hand, heldItem, empty.copy()); + } + painted[0] = true; + return false; } // Off by one durability as the final use is handled by onItemUse, along with the use animation - if (painted) { + if (painted[0]) { useItemDurability(player, hand, heldItem, empty.copy()); } - painted = true; + painted[0] = true; } - } + return true; + }); } - return painted; + return painted[0]; } @SuppressWarnings("unchecked, rawtypes") @@ -191,27 +180,8 @@ private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos po } // TileEntityPipeBase special case - if (te instanceof IPipeTilepipe) { - if (player.isSneaking()) { - RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); - if (hitResult != null) { - EnumFacing facing = CoverRayTracer.determineGridSideHit(hitResult); - if (facing != null && pipe.isConnected(facing)) { - boolean paintedOthers = traversePipes(player, world, hand, pos, facing); - if (pipe.isPainted()) { - pipe.setPaintingColor(-1); - if (paintedOthers) { - ItemStack heldItem = player.getHeldItem(hand); - useItemDurability(player, hand, heldItem, empty.copy()); - } - return true; - } else return paintedOthers; - } - } - } else if (pipe.isPainted()) { - pipe.setPaintingColor(-1); - return true; - } else return false; + if (player.isSneaking() && te instanceof IPipeTile) { + return traversePipes(player, world, hand, pos); } // AE2 cable special case diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index 32a27fcacb4..667c2c24705 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -11,29 +11,26 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.function.Function; public class PipeCollectorWalker> extends PipeNetWalker { - @NotNull - public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe, - int limit) { + public static void collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe, + Function, Boolean> pipeFunction) { PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( world, sourcePipe, 0, pipe.getClass()); - walker.traversePipeNet(limit); - return walker.isFailed() ? Collections.emptyList() : Collections.unmodifiableList(walker.pipes); - } - - public static List> collectPipeNet(World world, BlockPos sourcePipe, IPipeTile pipe) { - // Default limit for a pipenet walker - return collectPipeNet(world, sourcePipe, pipe, 32768); + walker.pipeFunction = pipeFunction; + walker.traversePipeNet(); } // I love type erasure private final Class basePipeClass; - private List pipes = new ArrayList<>(); + /** + * Function to run on every pipe + * If false is returned then halt the walker + */ + private Function, @NotNull Boolean> pipeFunction; + private BlockPos sourcePipe; protected PipeCollectorWalker(World world, BlockPos sourcePipe, int walkedBlocks, Class basePipeClass) { @@ -46,14 +43,16 @@ protected PipeCollectorWalker(World world, BlockPos sourcePipe, int walkedBlocks protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks) { PipeCollectorWalker walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass); - walker.pipes = pipes; + walker.pipeFunction = pipeFunction; walker.sourcePipe = sourcePipe; return walker; } @Override protected void checkPipe(T pipeTile, BlockPos pos) { - this.pipes.add(pipeTile); + if (this.pipeFunction != null && !this.pipeFunction.apply(pipeTile)) { + this.root.stop(); + } } @Override