From 5731a0e21f01bbf8e1d4b0a5d8ff1747ce93f6e3 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 15:10:06 -0400 Subject: [PATCH 001/109] Refactor spray can class for more modularity --- .../api/block/machines/BlockMachine.java | 13 +- .../api/items/toolitem/ItemGTToolbelt.java | 11 +- .../api/items/toolitem/ToolHelper.java | 4 +- .../gregtech/api/pipenet/block/BlockPipe.java | 13 +- .../java/gregtech/common/items/MetaItem1.java | 14 +- .../java/gregtech/common/items/MetaItems.java | 5 +- .../behaviors/AbstractUsableBehaviour.java | 52 ------ .../AbstractSprayBehavior.java} | 149 +++++++----------- .../spray/DurabilitySprayBehavior.java | 141 +++++++++++++++++ .../loaders/recipe/MachineRecipeLoader.java | 2 +- 10 files changed, 225 insertions(+), 179 deletions(-) delete mode 100644 src/main/java/gregtech/common/items/behaviors/AbstractUsableBehaviour.java rename src/main/java/gregtech/common/items/behaviors/{ColorSprayBehaviour.java => spray/AbstractSprayBehavior.java} (59%) create mode 100644 src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index 2a04cf5d441..e9e3b085ca0 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -19,7 +19,7 @@ import gregtech.api.util.Mods; import gregtech.client.renderer.handler.MetaTileEntityRenderer; import gregtech.common.creativetab.GTCreativeTabs; -import gregtech.common.items.MetaItems; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.integration.ctm.IFacadeWrapper; import net.minecraft.block.Block; @@ -326,15 +326,8 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc } // Color machines on place if holding spray can in off-hand - if (placer instanceof EntityPlayer) { - ItemStack offhand = placer.getHeldItemOffhand(); - for (int i = 0; i < EnumDyeColor.values().length; i++) { - if (offhand.isItemEqual(MetaItems.SPRAY_CAN_DYES[i].getStackForm())) { - MetaItems.SPRAY_CAN_DYES[i].getBehaviours().get(0).onItemUse((EntityPlayer) placer, worldIn, - pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); - break; - } - } + if (placer instanceof EntityPlayer player) { + AbstractSprayBehavior.handleAutomaticSpray(player, worldIn, pos); } metaTileEntity.onPlacement(placer); diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 6d28d550b2f..a58d290866a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -13,7 +13,7 @@ import gregtech.api.util.LocalizationUtils; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.TooltipHelper; -import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMaintenanceHatch; import gregtech.core.network.packets.PacketToolbeltSelectionChange; @@ -488,11 +488,12 @@ public void setSelectedTool(int slot, ItemStack stack) { ToolStackHandler handler = getHandler(player.getHeldItem(hand)); ItemStack selected = handler.getSelectedStack(); if (!selected.isEmpty()) { - ColorSprayBehaviour spray = ColorSprayBehaviour.getBehavior(selected); + AbstractSprayBehavior spray = AbstractSprayBehavior.getBehavior(selected); if (spray != null) { - EnumActionResult result = spray.useFromToolbelt(player, world, pos, hand, facing, hitX, hitY, hitZ, - selected); - if (result != EnumActionResult.PASS) return result; + EnumActionResult result = spray.useFromToolbelt(player, world, pos, hand, facing, selected); + if (result != EnumActionResult.PASS) { + return result; + } } } return super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index f696c1684e4..518a5ec642b 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -17,7 +17,7 @@ import gregtech.api.util.function.QuintFunction; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; -import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.spray.OldColorSprayBehaviour; import gregtech.tools.enchants.EnchantmentHardHammer; import net.minecraft.advancements.CriteriaTriggers; @@ -408,7 +408,7 @@ public static boolean isTool(ItemStack tool) { public static boolean isSpraycan(ItemStack spraycan) { if (spraycan.getItem() instanceof MetaItemmeta) { for (IItemBehaviour behaviour : meta.getBehaviours(spraycan)) { - if (behaviour instanceof ColorSprayBehaviour) return true; + if (behaviour instanceof OldColorSprayBehaviour) return true; } } return false; diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 667b67fcf52..ccc4614ffec 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -17,7 +17,7 @@ import gregtech.common.ConfigHolder; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.items.MetaItems; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.integration.ctm.IFacadeWrapper; import net.minecraft.block.Block; @@ -180,15 +180,8 @@ public void onBlockPlacedBy(@NotNull World worldIn, @NotNull BlockPos pos, @NotN setTileEntityData((TileEntityPipeBase) pipeTile, stack); // Color pipes/cables on place if holding spray can in off-hand - if (placer instanceof EntityPlayer) { - ItemStack offhand = placer.getHeldItemOffhand(); - for (int i = 0; i < EnumDyeColor.values().length; i++) { - if (offhand.isItemEqual(MetaItems.SPRAY_CAN_DYES[i].getStackForm())) { - MetaItems.SPRAY_CAN_DYES[i].getBehaviours().get(0).onItemUse((EntityPlayer) placer, worldIn, - pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); - break; - } - } + if (placer instanceof EntityPlayer player) { + AbstractSprayBehavior.handleAutomaticSpray(player, worldIn, pos); } } } diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index b528f3c1041..fae1640f4a2 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -34,7 +34,6 @@ 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.DataItemBehavior; import gregtech.common.items.behaviors.DoorBehavior; import gregtech.common.items.behaviors.DynamiteBehaviour; @@ -59,6 +58,7 @@ import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.TextPluginBehavior; +import gregtech.common.items.behaviors.spray.DurabilitySprayBehavior; import gregtech.core.sound.GTSoundEvents; import net.minecraft.client.resources.I18n; @@ -167,7 +167,7 @@ public void registerSubItems() { SHAPE_MOLDS[17] = SHAPE_MOLD_ROUND = addItem(29, "shape.mold.round") .setRecyclingData(new RecyclingData(new MaterialStack(Materials.Steel, M * 4))); - // Free ID: 30 + SPRAY_CREATIVE = addItem(30, "spray.creative"); // Extruder Shapes: ID 31-59 SHAPE_EXTRUDERS[0] = SHAPE_EXTRUDER_PLATE = addItem(31, "shape.extruder.plate") @@ -215,14 +215,14 @@ 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 DurabilitySprayBehavior(SPRAY_EMPTY.getStackForm(), 1024, null)) .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()) + for (EnumDyeColor color : EnumDyeColor.values()) { + SPRAY_CAN_DYES.put(color, addItem(62 + color.ordinal(), "spray.can.dyes." + color.getName()) .setMaxStackSize(1) - .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i)) - .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); + .addComponents(new DurabilitySprayBehavior(SPRAY_EMPTY.getStackForm(), 1024, color)) + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS)); } // Fluid Cells: ID 78-88 diff --git a/src/main/java/gregtech/common/items/MetaItems.java b/src/main/java/gregtech/common/items/MetaItems.java index 23c49bb279f..176a8eaa83a 100644 --- a/src/main/java/gregtech/common/items/MetaItems.java +++ b/src/main/java/gregtech/common/items/MetaItems.java @@ -104,6 +104,7 @@ private MetaItems() {} public static MetaItem.MetaValueItem SPRAY_SOLVENT; public static MetaItem.MetaValueItem SPRAY_EMPTY; + public static MetaItem.MetaValueItem SPRAY_CREATIVE; public static MetaItem.MetaValueItem FLUID_CELL; public static MetaItem.MetaValueItem FLUID_CELL_UNIVERSAL; @@ -515,8 +516,8 @@ private MetaItems() {} public static final MetaItem.MetaValueItem[] DYE_ONLY_ITEMS = new MetaItem.MetaValueItem[EnumDyeColor .values().length]; - public static final MetaItem.MetaValueItem[] SPRAY_CAN_DYES = new MetaItem.MetaValueItem[EnumDyeColor - .values().length]; + public static final EnumMap.MetaValueItem> SPRAY_CAN_DYES = new EnumMap<>( + EnumDyeColor.class); public static MetaItem.MetaValueItem TURBINE_ROTOR; diff --git a/src/main/java/gregtech/common/items/behaviors/AbstractUsableBehaviour.java b/src/main/java/gregtech/common/items/behaviors/AbstractUsableBehaviour.java deleted file mode 100644 index 1b7528c0c59..00000000000 --- a/src/main/java/gregtech/common/items/behaviors/AbstractUsableBehaviour.java +++ /dev/null @@ -1,52 +0,0 @@ -package gregtech.common.items.behaviors; - -import gregtech.api.items.metaitem.stats.IItemBehaviour; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; -import net.minecraftforge.common.util.Constants.NBT; - -public class AbstractUsableBehaviour implements IItemBehaviour { - - public final int totalUses; - - public AbstractUsableBehaviour(int totalUses) { - this.totalUses = totalUses; - } - - public boolean useItemDurability(EntityPlayer player, EnumHand hand, ItemStack stack, ItemStack replacementStack) { - int usesLeft = getUsesLeft(stack); - if (!player.capabilities.isCreativeMode) { - if (--usesLeft <= 0) { - if (replacementStack.isEmpty()) { - // if replacement stack is empty, just shrink resulting stack - stack.shrink(1); - } else { - // otherwise, update held item to replacement stack - player.setHeldItem(hand, replacementStack); - } - return true; - } - setUsesLeft(stack, usesLeft); - } - return true; - } - - public final int getUsesLeft(ItemStack stack) { - NBTTagCompound tagCompound = stack.getTagCompound(); - if (tagCompound == null || !tagCompound.hasKey("GT.UsesLeft", NBT.TAG_INT)) - return totalUses; - return tagCompound.getInteger("GT.UsesLeft"); - } - - public static void setUsesLeft(ItemStack itemStack, int usesLeft) { - NBTTagCompound tagCompound = itemStack.getTagCompound(); - if (tagCompound == null) { - tagCompound = new NBTTagCompound(); - itemStack.setTagCompound(tagCompound); - } - tagCompound.setInteger("GT.UsesLeft", usesLeft); - } -} diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java similarity index 59% rename from src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java rename to src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 72d164afd19..d51356d5151 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -1,12 +1,10 @@ -package gregtech.common.items.behaviors; +package gregtech.common.items.behaviors.spray; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; -import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.util.GradientUtil; import gregtech.api.util.Mods; import gregtech.core.sound.GTSoundEvents; @@ -16,7 +14,6 @@ import net.minecraft.block.BlockStainedGlassPane; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.EnumDyeColor; @@ -32,99 +29,103 @@ import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; -import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.*; -import java.util.List; +public abstract class AbstractSprayBehavior implements IItemBehaviour { -public class ColorSprayBehaviour extends AbstractUsableBehaviour implements IItemDurabilityManager { + public abstract @Nullable EnumDyeColor getColor(); - private final ItemStack empty; - private final EnumDyeColor color; - private final Pair durabilityBarColors; + public static @Nullable AbstractSprayBehavior getBehavior(@NotNull ItemStack stack) { + if (!(stack.getItem() instanceof MetaItemmetaItem)) return null; - public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) { - super(totalUses); - this.empty = empty; - EnumDyeColor[] colors = EnumDyeColor.values(); - this.color = color >= colors.length || color < 0 ? null : colors[color]; - // default to a gray color if this.color is null (like for solvent spray) - int colorValue = this.color == null ? 0x969696 : this.color.colorValue; - this.durabilityBarColors = GradientUtil.getGradient(colorValue, 10); + for (IItemBehaviour behaviour : metaItem.getBehaviours(stack)) { + if (behaviour instanceof AbstractSprayBehavior sprayBehavior) { + return sprayBehavior; + } + } + + return null; } @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); + if (!player.canPlayerEdit(pos, facing, stack)) { return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); } + if (!tryPaintBlock(player, world, pos, facing)) { return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); } - useItemDurability(player, hand, stack, empty.copy()); + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - @Nullable - public static ColorSprayBehaviour getBehavior(ItemStack spraycan) { - if (!(spraycan.getItem() instanceof MetaItemmeta)) return null; - for (IItemBehaviour behaviour : meta.getBehaviours(spraycan)) { - if (behaviour instanceof ColorSprayBehaviour spray) return spray; - } - return null; - } - - public EnumActionResult useFromToolbelt(EntityPlayer player, World world, BlockPos pos, EnumHand hand, - EnumFacing facing, float hitX, float hitY, float hitZ, ItemStack spraycan) { - if (!player.canPlayerEdit(pos, facing, spraycan)) { + public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumHand hand, @NotNull EnumFacing facing, + @NotNull ItemStack sprayCan) { + if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; } + if (!tryPaintBlock(player, world, pos, facing)) { return EnumActionResult.PASS; } - useItemDurability(player, hand, spraycan, empty.copy()); + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); return EnumActionResult.SUCCESS; } - private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, EnumFacing side) { + public static void handleAutomaticSpray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos) { + ItemStack offHand = player.getHeldItem(EnumHand.OFF_HAND); + AbstractSprayBehavior sprayBehavior = getBehavior(offHand); + if (sprayBehavior == null) return; + sprayBehavior.onItemUse(player, world, pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing side) { IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); + + EnumDyeColor color = getColor(); if (color == null) { return tryStripBlockColor(player, world, pos, block, side); } - return block.recolorBlock(world, pos, side, this.color) || tryPaintSpecialBlock(player, world, pos, block); + + return block.recolorBlock(world, pos, side, color) || tryPaintSpecialBlock(player, world, pos, block, color); } - private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block) { + private boolean tryPaintSpecialBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, + @NotNull Block block, @NotNull EnumDyeColor color) { if (block == Blocks.GLASS) { + // noinspection DataFlowIssue IBlockState newBlockState = Blocks.STAINED_GLASS.getDefaultState() - .withProperty(BlockStainedGlass.COLOR, this.color); + .withProperty(BlockStainedGlass.COLOR, color); world.setBlockState(pos, newBlockState); return true; - } - if (block == Blocks.GLASS_PANE) { + } else if (block == Blocks.GLASS_PANE) { + // noinspection DataFlowIssue IBlockState newBlockState = Blocks.STAINED_GLASS_PANE.getDefaultState() - .withProperty(BlockStainedGlassPane.COLOR, this.color); + .withProperty(BlockStainedGlassPane.COLOR, color); world.setBlockState(pos, newBlockState); return true; - } - if (block == Blocks.HARDENED_CLAY) { + } else if (block == Blocks.HARDENED_CLAY) { + // noinspection DataFlowIssue IBlockState newBlockState = Blocks.STAINED_HARDENED_CLAY.getDefaultState() - .withProperty(BlockColored.COLOR, this.color); + .withProperty(BlockColored.COLOR, color); world.setBlockState(pos, newBlockState); return true; - } - if (Mods.AppliedEnergistics2.isModLoaded()) { + } else 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); @@ -132,22 +133,20 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos } } } + return false; } - @SuppressWarnings("unchecked, rawtypes") - private static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, - EnumFacing side) { + protected static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, + EnumFacing side) { // MC special cases if (block == Blocks.STAINED_GLASS) { world.setBlockState(pos, Blocks.GLASS.getDefaultState()); return true; - } - if (block == Blocks.STAINED_GLASS_PANE) { + } else if (block == Blocks.STAINED_GLASS_PANE) { world.setBlockState(pos, Blocks.GLASS_PANE.getDefaultState()); return true; - } - if (block == Blocks.STAINED_HARDENED_CLAY) { + } else if (block == Blocks.STAINED_HARDENED_CLAY) { world.setBlockState(pos, Blocks.HARDENED_CLAY.getDefaultState()); return true; } @@ -165,18 +164,18 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // TileEntityPipeBase special case - if (te instanceof IPipeTile) { - IPipeTile pipe = (IPipeTile) te; + if (te instanceof IPipeTilepipe) { if (pipe.isPainted()) { pipe.setPaintingColor(-1); return true; - } else return false; + } else { + return false; + } } // 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); @@ -187,7 +186,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc // General case IBlockState state = world.getBlockState(pos); - for (IProperty prop : state.getProperties().keySet()) { + for (IProperty prop : state.getProperties().keySet()) { if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { IBlockState defaultState = block.getDefaultState(); EnumDyeColor defaultColor = EnumDyeColor.WHITE; @@ -207,34 +206,4 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc return false; } - - @Override - public void addInformation(ItemStack itemStack, List lines) { - int remainingUses = getUsesLeft(itemStack); - if (color != null) { - lines.add(I18n.format("behaviour.paintspray." + this.color.getTranslationKey() + ".tooltip")); - } else { - lines.add(I18n.format("behaviour.paintspray.solvent.tooltip")); - } - lines.add(I18n.format("behaviour.paintspray.uses", remainingUses)); - if (color != null) { - lines.add(I18n.format("behaviour.paintspray.offhand")); - } - } - - @Override - public double getDurabilityForDisplay(ItemStack itemStack) { - return (double) getUsesLeft(itemStack) / totalUses; - } - - @Nullable - @Override - public Pair getDurabilityColorsForDisplay(ItemStack itemStack) { - return durabilityBarColors; - } - - @Override - public boolean doDamagedStateColors(ItemStack itemStack) { - return false; - } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java new file mode 100644 index 00000000000..b0be747bcf6 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -0,0 +1,141 @@ +package gregtech.common.items.behaviors.spray; + +import gregtech.api.items.metaitem.stats.IItemDurabilityManager; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GradientUtil; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; + +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.List; + +public class DurabilitySprayBehavior extends AbstractSprayBehavior implements IItemDurabilityManager { + + public static final String NBT_KEY = "GT.UsesLeft"; + + @Nullable + private final EnumDyeColor color; + @NotNull + private final Pair durabilityBarColors; + @NotNull + private final ItemStack replacementStack; + public final int totalUses; + + public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int totalUses, @Nullable EnumDyeColor color) { + this.color = color; + this.replacementStack = replacementStack; + this.totalUses = totalUses; + this.durabilityBarColors = GradientUtil.getGradient(color == null ? 0x969696 : color.colorValue, 10); + } + + @Override + public @Nullable EnumDyeColor getColor() { + return this.color; + } + + @Override + public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, + EnumFacing facing, float hitX, float hitY, float hitZ) { + ActionResult result = super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); + + if (result.getType() == EnumActionResult.SUCCESS) { + useItemDurability(player, hand, player.getHeldItem(hand), replacementStack.copy()); + } + + return result; + } + + @Override + public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumHand hand, @NotNull EnumFacing facing, + @NotNull ItemStack sprayCan) { + EnumActionResult result = super.useFromToolbelt(player, world, pos, hand, facing, sprayCan); + + if (result == EnumActionResult.SUCCESS) { + useItemDurability(player, hand, sprayCan, replacementStack.copy()); + } + + return result; + } + + public void useItemDurability(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack stack, + @NotNull ItemStack replacementStack) { + int usesLeft = getUsesLeft(stack, totalUses); + if (!player.capabilities.isCreativeMode) { + if (--usesLeft <= 0) { + if (replacementStack.isEmpty()) { + // If replacement stack is empty, just shrink resulting stack + stack.shrink(1); + } else { + // Otherwise, update held item to replacement stack + player.setHeldItem(hand, replacementStack); + } + return; + } + + setUsesLeft(stack, usesLeft); + } + } + + protected static int getUsesLeft(@NotNull ItemStack stack, int defaultUsesLeft) { + NBTTagCompound tagCompound = stack.getTagCompound(); + if (tagCompound == null || !tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { + return defaultUsesLeft; + } + + return tagCompound.getInteger(NBT_KEY); + } + + protected static void setUsesLeft(@NotNull ItemStack itemStack, int usesLeft) { + GTUtility.getOrCreateNbtCompound(itemStack).setInteger(NBT_KEY, usesLeft); + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + int remainingUses = getUsesLeft(itemStack, totalUses); + EnumDyeColor color = getColor(); + + if (color != null) { + lines.add(I18n.format("behaviour.paintspray." + color.getTranslationKey() + ".tooltip")); + } else { + lines.add(I18n.format("behaviour.paintspray.solvent.tooltip")); + } + + lines.add(I18n.format("behaviour.paintspray.uses", remainingUses)); + + if (color != null) { + lines.add(I18n.format("behaviour.paintspray.offhand")); + } + } + + @Override + public double getDurabilityForDisplay(ItemStack itemStack) { + return (double) getUsesLeft(itemStack, totalUses) / totalUses; + } + + @Nullable + @Override + public Pair getDurabilityColorsForDisplay(ItemStack itemStack) { + return durabilityBarColors; + } + + @Override + public boolean doDamagedStateColors(ItemStack itemStack) { + return false; + } +} diff --git a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java index 065e864dfd0..c6fb33bc9dc 100644 --- a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java @@ -445,7 +445,7 @@ private static void registerAssemblerRecipes() { CANNER_RECIPES.recipeBuilder() .inputs(MetaItems.SPRAY_EMPTY.getStackForm()) .fluidInputs(Materials.CHEMICAL_DYES[i].getFluid(GTValues.L * 4)) - .outputs(MetaItems.SPRAY_CAN_DYES[i].getStackForm()) + .outputs(SPRAY_CAN_DYES.get(EnumDyeColor.values()[i]).getStackForm()) .EUt(VA[ULV]).duration(200) .buildAndRegister(); From c1e7048d8477e2f7f63c7fc8a229cb9259e13711 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 15:12:30 -0400 Subject: [PATCH 002/109] Fix toolbelt code I forgot to change --- .../api/items/toolitem/ItemGTToolbelt.java | 2 +- .../gregtech/api/items/toolitem/ToolHelper.java | 17 +++++------------ .../behaviors/spray/AbstractSprayBehavior.java | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index a58d290866a..9e1e4201109 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -488,7 +488,7 @@ public void setSelectedTool(int slot, ItemStack stack) { ToolStackHandler handler = getHandler(player.getHeldItem(hand)); ItemStack selected = handler.getSelectedStack(); if (!selected.isEmpty()) { - AbstractSprayBehavior spray = AbstractSprayBehavior.getBehavior(selected); + AbstractSprayBehavior spray = AbstractSprayBehavior.getSprayCanBehavior(selected); if (spray != null) { EnumActionResult result = spray.useFromToolbelt(player, world, pos, hand, facing, selected); if (result != EnumActionResult.PASS) { diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 518a5ec642b..6d5e3189d5c 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -3,8 +3,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IElectricItem; -import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.items.toolitem.aoe.AoESymmetrical; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; @@ -17,7 +15,7 @@ import gregtech.api.util.function.QuintFunction; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; -import gregtech.common.items.behaviors.spray.OldColorSprayBehaviour; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.tools.enchants.EnchantmentHardHammer; import net.minecraft.advancements.CriteriaTriggers; @@ -392,7 +390,7 @@ public static boolean isTool(ItemStack tool, String... toolClasses) { * @return if the itemstack should be considered a utility item and thus can be put into toolbelts. */ public static boolean isUtilityItem(ItemStack utility) { - return isTool(utility) || isSpraycan(utility); + return isTool(utility) || isSprayCan(utility); } /** @@ -403,15 +401,10 @@ public static boolean isTool(ItemStack tool) { } /** - * @return if the itemstack should be considered a spraycan + * @return if the itemstack should be considered a spray can */ - public static boolean isSpraycan(ItemStack spraycan) { - if (spraycan.getItem() instanceof MetaItemmeta) { - for (IItemBehaviour behaviour : meta.getBehaviours(spraycan)) { - if (behaviour instanceof OldColorSprayBehaviour) return true; - } - } - return false; + public static boolean isSprayCan(ItemStack sprayCan) { + return AbstractSprayBehavior.getSprayCanBehavior(sprayCan) != null; } /** diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index d51356d5151..d8806737579 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -36,7 +36,7 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { public abstract @Nullable EnumDyeColor getColor(); - public static @Nullable AbstractSprayBehavior getBehavior(@NotNull ItemStack stack) { + public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack stack) { if (!(stack.getItem() instanceof MetaItemmetaItem)) return null; for (IItemBehaviour behaviour : metaItem.getBehaviours(stack)) { @@ -84,7 +84,7 @@ public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull W public static void handleAutomaticSpray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos) { ItemStack offHand = player.getHeldItem(EnumHand.OFF_HAND); - AbstractSprayBehavior sprayBehavior = getBehavior(offHand); + AbstractSprayBehavior sprayBehavior = getSprayCanBehavior(offHand); if (sprayBehavior == null) return; sprayBehavior.onItemUse(player, world, pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); } From 3201860ef2d70f13caeb6f8d5508c3c814d95095 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 15:33:28 -0400 Subject: [PATCH 003/109] Accidentally doubled the durability of spray cans --- src/main/java/gregtech/common/items/MetaItem1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index fae1640f4a2..b0f7758956d 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -221,7 +221,7 @@ public void registerSubItems() { for (EnumDyeColor color : EnumDyeColor.values()) { SPRAY_CAN_DYES.put(color, addItem(62 + color.ordinal(), "spray.can.dyes." + color.getName()) .setMaxStackSize(1) - .addComponents(new DurabilitySprayBehavior(SPRAY_EMPTY.getStackForm(), 1024, color)) + .addComponents(new DurabilitySprayBehavior(SPRAY_EMPTY.getStackForm(), 512, color)) .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS)); } From 65da2088de0c2aeb1546ced846befbc3990b150d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:20:09 -0400 Subject: [PATCH 004/109] Fix oversight from PR #2712 where the non tool (wrenches, hammers, etc) but usable items (spray cans, lighters, etc) weren't accounted for --- .../stats/IItemDurabilityManager.java | 2 +- .../gregtech/api/items/toolitem/IGTTool.java | 2 +- .../java/gregtech/api/util/GTUtility.java | 22 +++++++++++++++++++ .../common/items/armor/PowerlessJetpack.java | 5 +++-- .../AbstractMaterialPartBehavior.java | 4 ++-- .../items/behaviors/FoamSprayerBehavior.java | 4 +++- .../items/behaviors/LighterBehaviour.java | 9 ++++---- .../spray/DurabilitySprayBehavior.java | 16 +++++++------- 8 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IItemDurabilityManager.java b/src/main/java/gregtech/api/items/metaitem/stats/IItemDurabilityManager.java index ad45a50dfee..e25676e6700 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IItemDurabilityManager.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IItemDurabilityManager.java @@ -9,7 +9,7 @@ public interface IItemDurabilityManager extends IItemComponent { - /** The durability remaining on this item (double from 0 to 1). */ + /** The durability remaining on this item (double from 0 to 1 as the durability is used up). */ double getDurabilityForDisplay(ItemStack itemStack); /** The first and last colors of a gradient. Default to Green durability gradient (null Pair). */ diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 679b22118b3..f9e737f88ef 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -649,7 +649,7 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) { default double definition$getDurabilityForDisplay(ItemStack stack) { int damage = stack.getItem().getDamage(stack); int maxDamage = stack.getItem().getMaxDamage(stack); - return (double) damage / (double) maxDamage; + return GTUtility.calculateDurabilityFromDamageTaken(damage, maxDamage); } @Nullable diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index a4f44bb2bce..a3db0b02f57 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -1023,4 +1023,26 @@ public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, } return map.get(key.toWildcard()); } + + /** + * Calculate the percentage of durability + * + * @param damageTaken how many points of durability damage the item has + * @param maxDurability the maximum durability the item can have + * @return 0 = full durability, 1 = zero durability + */ + public static double calculateDurabilityFromDamageTaken(int damageTaken, int maxDurability) { + return (double) damageTaken / maxDurability; + } + + /** + * Calculate the percentage of durability + * + * @param remainingDurability how much durability out of the maximum the item has left + * @param maxDurability the maximum durability the item can have + * @return 0 = full durability, 1 = zero durability + */ + public static double calculateDurabilityFromRemaining(int remainingDurability, int maxDurability) { + return (double) (maxDurability - remainingDurability) / maxDurability; + } } diff --git a/src/main/java/gregtech/common/items/armor/PowerlessJetpack.java b/src/main/java/gregtech/common/items/armor/PowerlessJetpack.java index 0f9e2867193..5c3e43495b3 100644 --- a/src/main/java/gregtech/common/items/armor/PowerlessJetpack.java +++ b/src/main/java/gregtech/common/items/armor/PowerlessJetpack.java @@ -283,10 +283,11 @@ public Behaviour(int internalCapacity) { public double getDurabilityForDisplay(@NotNull ItemStack itemStack) { IFluidHandlerItem fluidHandlerItem = itemStack .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); - if (fluidHandlerItem == null) return 0; + if (fluidHandlerItem == null) return 1.0d; IFluidTankProperties fluidTankProperties = fluidHandlerItem.getTankProperties()[0]; FluidStack fluidStack = fluidTankProperties.getContents(); - return fluidStack == null ? 0 : (double) fluidStack.amount / (double) fluidTankProperties.getCapacity(); + return fluidStack == null ? 1.0d : + GTUtility.calculateDurabilityFromRemaining(fluidStack.amount, fluidTankProperties.getCapacity()); } @Nullable diff --git a/src/main/java/gregtech/common/items/behaviors/AbstractMaterialPartBehavior.java b/src/main/java/gregtech/common/items/behaviors/AbstractMaterialPartBehavior.java index a4abe287529..67b4d671a18 100644 --- a/src/main/java/gregtech/common/items/behaviors/AbstractMaterialPartBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/AbstractMaterialPartBehavior.java @@ -8,6 +8,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; import net.minecraft.client.resources.I18n; @@ -89,7 +90,6 @@ public int getItemStackColor(ItemStack itemStack, int tintIndex) { @Override public double getDurabilityForDisplay(ItemStack itemStack) { - int maxDurability = getPartMaxDurability(itemStack); - return (double) (maxDurability - getPartDamage(itemStack)) / (double) maxDurability; + return GTUtility.calculateDurabilityFromDamageTaken(getPartDamage(itemStack), getPartMaxDurability(itemStack)); } } diff --git a/src/main/java/gregtech/common/items/behaviors/FoamSprayerBehavior.java b/src/main/java/gregtech/common/items/behaviors/FoamSprayerBehavior.java index 7a059220e34..2af2697c925 100644 --- a/src/main/java/gregtech/common/items/behaviors/FoamSprayerBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/FoamSprayerBehavior.java @@ -8,6 +8,7 @@ import gregtech.api.items.metaitem.stats.ISubItemHandler; import gregtech.api.recipes.ModHandler; import gregtech.api.unification.material.Materials; +import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -90,7 +91,8 @@ public double getDurabilityForDisplay(ItemStack itemStack) { if (fluidHandlerItem == null) return 0; IFluidTankProperties fluidTankProperties = fluidHandlerItem.getTankProperties()[0]; FluidStack fluidStack = fluidTankProperties.getContents(); - return fluidStack == null ? 0 : (double) fluidStack.amount / (double) fluidTankProperties.getCapacity(); + return fluidStack == null ? 0 : + GTUtility.calculateDurabilityFromRemaining(fluidStack.amount, fluidTankProperties.getCapacity()); } @Nullable diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index 66941091218..579c899e31b 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -227,13 +227,14 @@ public double getDurabilityForDisplay(ItemStack itemStack) { IFluidHandlerItem fluidHandlerItem = itemStack .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); if (fluidHandlerItem == null) return 0.0; - IFluidTankProperties properties = fluidHandlerItem.getTankProperties()[0]; - FluidStack fluidStack = properties.getContents(); - return fluidStack == null ? 0.0 : (double) fluidStack.amount / (double) properties.getCapacity(); + IFluidTankProperties fluidTankProperties = fluidHandlerItem.getTankProperties()[0]; + FluidStack fluidStack = fluidTankProperties.getContents(); + return fluidStack == null ? 0.0 : + GTUtility.calculateDurabilityFromRemaining(fluidStack.amount, fluidTankProperties.getCapacity()); } if (hasMultipleUses) { // Matchbox - return (double) getUsesLeft(itemStack) / (double) maxUses; + return GTUtility.calculateDurabilityFromRemaining(getUsesLeft(itemStack), maxUses); } // no durability for Match return 0.0; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index b0be747bcf6..97aa90a18cc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -34,12 +34,12 @@ public class DurabilitySprayBehavior extends AbstractSprayBehavior implements II private final Pair durabilityBarColors; @NotNull private final ItemStack replacementStack; - public final int totalUses; + public final int maxUses; - public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int totalUses, @Nullable EnumDyeColor color) { + public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int maxUses, @Nullable EnumDyeColor color) { this.color = color; this.replacementStack = replacementStack; - this.totalUses = totalUses; + this.maxUses = maxUses; this.durabilityBarColors = GradientUtil.getGradient(color == null ? 0x969696 : color.colorValue, 10); } @@ -75,7 +75,7 @@ public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull W public void useItemDurability(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack stack, @NotNull ItemStack replacementStack) { - int usesLeft = getUsesLeft(stack, totalUses); + int usesLeft = getUsesLeft(stack); if (!player.capabilities.isCreativeMode) { if (--usesLeft <= 0) { if (replacementStack.isEmpty()) { @@ -92,10 +92,10 @@ public void useItemDurability(@NotNull EntityPlayer player, @NotNull EnumHand ha } } - protected static int getUsesLeft(@NotNull ItemStack stack, int defaultUsesLeft) { + protected int getUsesLeft(@NotNull ItemStack stack) { NBTTagCompound tagCompound = stack.getTagCompound(); if (tagCompound == null || !tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { - return defaultUsesLeft; + return maxUses; } return tagCompound.getInteger(NBT_KEY); @@ -107,7 +107,7 @@ protected static void setUsesLeft(@NotNull ItemStack itemStack, int usesLeft) { @Override public void addInformation(ItemStack itemStack, List lines) { - int remainingUses = getUsesLeft(itemStack, totalUses); + int remainingUses = getUsesLeft(itemStack); EnumDyeColor color = getColor(); if (color != null) { @@ -125,7 +125,7 @@ public void addInformation(ItemStack itemStack, List lines) { @Override public double getDurabilityForDisplay(ItemStack itemStack) { - return (double) getUsesLeft(itemStack, totalUses) / totalUses; + return GTUtility.calculateDurabilityFromRemaining(getUsesLeft(itemStack), maxUses); } @Nullable From 3c28b0ca3afac815394c49e8b58786ec10f028c5 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:38:05 -0400 Subject: [PATCH 005/109] javadoc wording change --- src/main/java/gregtech/api/util/GTUtility.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index a3db0b02f57..434b4153905 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -1025,7 +1025,7 @@ public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, } /** - * Calculate the percentage of durability + * Calculate the durability percentage based on how much damage something has taken * * @param damageTaken how many points of durability damage the item has * @param maxDurability the maximum durability the item can have @@ -1036,7 +1036,7 @@ public static double calculateDurabilityFromDamageTaken(int damageTaken, int max } /** - * Calculate the percentage of durability + * Calculate the durability percentage based on how much durability out of the maximum is remaining * * @param remainingDurability how much durability out of the maximum the item has left * @param maxDurability the maximum durability the item can have From 2caa1045164094256b0fdbe4a91e16dd7ae46a2a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:41:45 -0400 Subject: [PATCH 006/109] add some NotNulls to ToolHelper --- .../java/gregtech/api/items/toolitem/ToolHelper.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 6d5e3189d5c..a6a69629282 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -372,7 +372,7 @@ public static void onActionDone(@NotNull EntityPlayer player, @NotNull World wor /** * @return if any of the specified tool classes exists in the tool */ - public static boolean isTool(ItemStack tool, String... toolClasses) { + public static boolean isTool(@NotNull ItemStack tool, String... toolClasses) { if (toolClasses.length == 1) { return tool.getItem().getToolClasses(tool).contains(toolClasses[0]); } @@ -389,28 +389,28 @@ public static boolean isTool(ItemStack tool, String... toolClasses) { /** * @return if the itemstack should be considered a utility item and thus can be put into toolbelts. */ - public static boolean isUtilityItem(ItemStack utility) { + public static boolean isUtilityItem(@NotNull ItemStack utility) { return isTool(utility) || isSprayCan(utility); } /** * @return if the itemstack should be considered a tool */ - public static boolean isTool(ItemStack tool) { + public static boolean isTool(@NotNull ItemStack tool) { return tool.getItem() instanceof ItemTool || tool.getItem() instanceof IGTTool; } /** * @return if the itemstack should be considered a spray can */ - public static boolean isSprayCan(ItemStack sprayCan) { + public static boolean isSprayCan(@NotNull ItemStack sprayCan) { return AbstractSprayBehavior.getSprayCanBehavior(sprayCan) != null; } /** * Return if all the specified tool classes exists in the tool */ - public static boolean areTools(ItemStack tool, String... toolClasses) { + public static boolean areTools(@NotNull ItemStack tool, String... toolClasses) { if (toolClasses.length == 1) { return tool.getItem().getToolClasses(tool).contains(toolClasses[0]); } From 718db87b2136503263351abec26e43f053ed38ec Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:43:14 -0400 Subject: [PATCH 007/109] add some ItemStack#isEmpty checks in ToolHelper --- .../java/gregtech/api/items/toolitem/ToolHelper.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index a6a69629282..26fe5de6a5c 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -373,9 +373,12 @@ public static void onActionDone(@NotNull EntityPlayer player, @NotNull World wor * @return if any of the specified tool classes exists in the tool */ public static boolean isTool(@NotNull ItemStack tool, String... toolClasses) { + if (tool.isEmpty()) return false; + if (toolClasses.length == 1) { return tool.getItem().getToolClasses(tool).contains(toolClasses[0]); } + for (String toolClass : tool.getItem().getToolClasses(tool)) { for (String specified : toolClasses) { if (toolClass.equals(specified)) { @@ -383,6 +386,7 @@ public static boolean isTool(@NotNull ItemStack tool, String... toolClasses) { } } } + return false; } @@ -397,6 +401,7 @@ public static boolean isUtilityItem(@NotNull ItemStack utility) { * @return if the itemstack should be considered a tool */ public static boolean isTool(@NotNull ItemStack tool) { + if (tool.isEmpty()) return false; return tool.getItem() instanceof ItemTool || tool.getItem() instanceof IGTTool; } @@ -404,6 +409,7 @@ public static boolean isTool(@NotNull ItemStack tool) { * @return if the itemstack should be considered a spray can */ public static boolean isSprayCan(@NotNull ItemStack sprayCan) { + if (sprayCan.isEmpty()) return false; return AbstractSprayBehavior.getSprayCanBehavior(sprayCan) != null; } @@ -411,9 +417,12 @@ public static boolean isSprayCan(@NotNull ItemStack sprayCan) { * Return if all the specified tool classes exists in the tool */ public static boolean areTools(@NotNull ItemStack tool, String... toolClasses) { + if (tool.isEmpty()) return false; + if (toolClasses.length == 1) { return tool.getItem().getToolClasses(tool).contains(toolClasses[0]); } + return tool.getItem().getToolClasses(tool).containsAll(new ObjectArraySet(toolClasses)); } From 01427d77c9bc945f2a0bc06e4594f04253d53c63 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:55:20 -0400 Subject: [PATCH 008/109] Add javadoc to AbstractSprayBehavior#getColor --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index d8806737579..585c907c3f0 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -34,6 +34,9 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { + /** + * Get the color of the spray can. {@code null} = solvent + */ public abstract @Nullable EnumDyeColor getColor(); public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack stack) { From 14196d8427e9533e3ea090531d8abddee385f8d7 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 18 Jul 2025 20:16:51 -0400 Subject: [PATCH 009/109] Working creative spray can prototype --- .../gregtech/api/items/gui/ItemUIFactory.java | 1 + .../java/gregtech/common/items/MetaItem1.java | 20 +++- .../spray/AbstractSprayBehavior.java | 22 ++++- .../spray/CreativeSprayBehavior.java | 94 +++++++++++++++++++ .../spray/DurabilitySprayBehavior.java | 2 +- 5 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java diff --git a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java index 6633e96bb8b..28fc2399cfb 100644 --- a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java +++ b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java @@ -38,6 +38,7 @@ default GTGuiTheme getUITheme() { return GTGuiTheme.STANDARD; } + // TODO: change to abstract once MUI2 port is complete @Override default ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { return null; diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index b0f7758956d..e10a06c201c 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -58,6 +58,7 @@ import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.TextPluginBehavior; +import gregtech.common.items.behaviors.spray.CreativeSprayBehavior; import gregtech.common.items.behaviors.spray.DurabilitySprayBehavior; import gregtech.core.sound.GTSoundEvents; @@ -89,17 +90,27 @@ public void getSubItems(@NotNull CreativeTabs tab, @NotNull NonNullList.MetaValueItem item : metaItems.values()) { if (!item.isInCreativeTab(tab)) continue; - int itemMetaData = item.getMetaValue(); - if (itemMetaData >= 1006 && itemMetaData <= 1010) continue; + int itemMeta = item.getMetaValue(); + // Skip extra molds, see below + if (itemMeta >= 1006 && itemMeta <= 1010) continue; + // Skip creative spray can, see below + if (itemMeta == 30) continue; item.getSubItemHandler().getSubItems(item.getStackForm(), tab, subItems); - if (itemMetaData == 29) { + // Add the extra molds after the last 'original' + if (itemMeta == 29) { for (MetaItem.MetaValueItem moldItem : SHAPE_MOLDS) { + // Skip the 'original' molds if (moldItem.getMetaValue() < 1006) continue; moldItem.getSubItemHandler().getSubItems(moldItem.getStackForm(), tab, subItems); } } + + // Add the creative spray can after the last normal spray can + if (itemMeta == 77) { + subItems.add(SPRAY_CREATIVE.getStackForm()); + } } } @@ -167,7 +178,8 @@ public void registerSubItems() { SHAPE_MOLDS[17] = SHAPE_MOLD_ROUND = addItem(29, "shape.mold.round") .setRecyclingData(new RecyclingData(new MaterialStack(Materials.Steel, M * 4))); - SPRAY_CREATIVE = addItem(30, "spray.creative"); + SPRAY_CREATIVE = addItem(30, "spray.creative") + .addComponents(new CreativeSprayBehavior()); // Extruder Shapes: ID 31-59 SHAPE_EXTRUDERS[0] = SHAPE_EXTRUDER_PLATE = addItem(31, "shape.extruder.plate") diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 585c907c3f0..e2a5134b659 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -37,7 +37,19 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { /** * Get the color of the spray can. {@code null} = solvent */ - public abstract @Nullable EnumDyeColor getColor(); + public @Nullable EnumDyeColor getColor() { + return getColor(ItemStack.EMPTY); + } + + /** + * Get the color of the spray can. {@code null} = solvent + */ + public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack stack); + + public int getColorOrdinal(@NotNull ItemStack stack) { + EnumDyeColor color = getColor(stack); + return color == null ? -1 : color.ordinal(); + } public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack stack) { if (!(stack.getItem() instanceof MetaItemmetaItem)) return null; @@ -60,7 +72,7 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block 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)); } @@ -76,7 +88,7 @@ public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull W return EnumActionResult.FAIL; } - if (!tryPaintBlock(player, world, pos, facing)) { + if (!tryPaintBlock(player, world, pos, facing, hand)) { return EnumActionResult.PASS; } @@ -94,11 +106,11 @@ public static void handleAutomaticSpray(@NotNull EntityPlayer player, @NotNull W @SuppressWarnings("BooleanMethodIsAlwaysInverted") protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing side) { + @NotNull EnumFacing side, @NotNull EnumHand hand) { IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - EnumDyeColor color = getColor(); + EnumDyeColor color = getColor(player.getHeldItem(hand)); if (color == null) { return tryStripBlockColor(player, world, pos, block, side); } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java new file mode 100644 index 00000000000..dbe2cb64528 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -0,0 +1,94 @@ +package gregtech.common.items.behaviors.spray; + +import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.factory.MetaItemGuiFactory; +import gregtech.api.util.GTUtility; +import gregtech.common.items.MetaItems; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; + +import com.cleanroommc.modularui.drawable.ItemDrawable; +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory { + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack heldItem = player.getHeldItem(hand); + + if (!world.isRemote) { + MetaItemGuiFactory.open(player, hand); + } + + return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); + } + + @Override + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + ItemStack usedStack = guiData.getUsedItemStack(); + IntSyncValue colorSync = new IntSyncValue(() -> getColorOrdinal(usedStack), + newColor -> setColor(usedStack, newColor)); + guiSyncManager.syncValue("color", 0, colorSync); + + return GTGuis.createPanel(usedStack, 176, 120) + .child(SlotGroupWidget.builder() + .matrix("SCCCCCCC", + "CCCCCCCC") + .key('S', new ButtonWidget<>() + .size(18) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm())) + .onMousePressed(mouse -> { + colorSync.setIntValue(-1); + return true; + })) + .key('C', index -> new ButtonWidget<>() + .size(18) + .overlay(new ItemDrawable( + MetaItems.SPRAY_CAN_DYES.get(EnumDyeColor.values()[index]).getStackForm())) + .onMousePressed(mouse -> { + colorSync.setIntValue(index); + return true; + })) + .build()); + } + + @Override + public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { + NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(stack); + if (tag.hasKey("color", Constants.NBT.TAG_INT)) { + int color = tag.getInteger("color"); + if (color < 0 || color > 15) return null; + return EnumDyeColor.values()[color]; + } + return null; + } + + public void setColor(@NotNull ItemStack stack, @Nullable EnumDyeColor color) { + GTUtility.getOrCreateNbtCompound(stack).setInteger("color", color == null ? -1 : color.ordinal()); + } + + public void setColor(@NotNull ItemStack stack, int color) { + if (color >= 0 && color <= 15) { + setColor(stack, EnumDyeColor.values()[color]); + } else { + setColor(stack, null); + } + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 97aa90a18cc..6f2e8aa8261 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -44,7 +44,7 @@ public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int maxUses, } @Override - public @Nullable EnumDyeColor getColor() { + public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { return this.color; } From a903f9089d434a73fccbabc8aab6b881fc50db85 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 19 Jul 2025 22:37:17 -0400 Subject: [PATCH 010/109] Shuffle/dedup some code --- .../api/block/machines/BlockMachine.java | 2 +- .../api/items/toolitem/ItemGTToolbelt.java | 10 ++-- .../gregtech/api/pipenet/block/BlockPipe.java | 2 +- .../spray/AbstractSprayBehavior.java | 57 +++++++++---------- .../spray/CreativeSprayBehavior.java | 1 - .../spray/DurabilitySprayBehavior.java | 26 ++------- 6 files changed, 37 insertions(+), 61 deletions(-) diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index e9e3b085ca0..5fd28ce1130 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -327,7 +327,7 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc // Color machines on place if holding spray can in off-hand if (placer instanceof EntityPlayer player) { - AbstractSprayBehavior.handleAutomaticSpray(player, worldIn, pos); + AbstractSprayBehavior.handleExternalSpray(player, EnumHand.OFF_HAND, worldIn, pos, EnumFacing.UP); } metaTileEntity.onPlacement(placer); diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 9e1e4201109..2215492949f 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -488,12 +488,10 @@ public void setSelectedTool(int slot, ItemStack stack) { ToolStackHandler handler = getHandler(player.getHeldItem(hand)); ItemStack selected = handler.getSelectedStack(); if (!selected.isEmpty()) { - AbstractSprayBehavior spray = AbstractSprayBehavior.getSprayCanBehavior(selected); - if (spray != null) { - EnumActionResult result = spray.useFromToolbelt(player, world, pos, hand, facing, selected); - if (result != EnumActionResult.PASS) { - return result; - } + EnumActionResult result = AbstractSprayBehavior.handleExternalSpray(player, hand, world, pos, facing, + selected); + if (result != EnumActionResult.PASS) { + return result; } } return super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index ccc4614ffec..abefdd68e10 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -181,7 +181,7 @@ public void onBlockPlacedBy(@NotNull World worldIn, @NotNull BlockPos pos, @NotN // Color pipes/cables on place if holding spray can in off-hand if (placer instanceof EntityPlayer player) { - AbstractSprayBehavior.handleAutomaticSpray(player, worldIn, pos); + AbstractSprayBehavior.handleExternalSpray(player, EnumHand.OFF_HAND, worldIn, pos, EnumFacing.UP); } } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index e2a5134b659..d30b51433f5 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -6,7 +6,6 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.Mods; -import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; import net.minecraft.block.BlockColored; @@ -23,7 +22,6 @@ 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.world.World; @@ -66,51 +64,48 @@ public int getColorOrdinal(@NotNull ItemStack stack) { @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 sprayCan = player.getHeldItem(hand); + EnumActionResult result = spray(player, hand, world, pos, facing, sprayCan); + return ActionResult.newResult(result, sprayCan); + } - if (!player.canPlayerEdit(pos, facing, stack)) { - return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); - } + @SuppressWarnings("UnusedReturnValue") + public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing) { + return handleExternalSpray(player, hand, world, pos, facing, player.getHeldItem(hand)); + } - if (!tryPaintBlock(player, world, pos, facing, hand)) { - return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull ItemStack sprayCan) { + AbstractSprayBehavior sprayBehavior = getSprayCanBehavior(sprayCan); + if (sprayBehavior == null) { + return EnumActionResult.PASS; + } else { + return sprayBehavior.spray(player, hand, world, pos, facing, sprayCan); } - - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); - return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumHand hand, @NotNull EnumFacing facing, - @NotNull ItemStack sprayCan) { + protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull ItemStack sprayCan) { if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; - } - - if (!tryPaintBlock(player, world, pos, facing, hand)) { + } else if (!tryPaintBlock(player, world, pos, facing, getColor(sprayCan))) { return EnumActionResult.PASS; + } else { + return EnumActionResult.SUCCESS; } - - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); - return EnumActionResult.SUCCESS; - } - - public static void handleAutomaticSpray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos) { - ItemStack offHand = player.getHeldItem(EnumHand.OFF_HAND); - AbstractSprayBehavior sprayBehavior = getSprayCanBehavior(offHand); - if (sprayBehavior == null) return; - sprayBehavior.onItemUse(player, world, pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing side, @NotNull EnumHand hand) { + @NotNull EnumFacing side, @Nullable EnumDyeColor color) { IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - EnumDyeColor color = getColor(player.getHeldItem(hand)); if (color == null) { return tryStripBlockColor(player, world, pos, block, side); } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index dbe2cb64528..7b5bb5df2bc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -8,7 +8,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ActionResult; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 6f2e8aa8261..ddf6bcc1426 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -9,7 +9,6 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; @@ -49,27 +48,13 @@ public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int maxUses, } @Override - public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, - EnumFacing facing, float hitX, float hitY, float hitZ) { - ActionResult result = super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); - - if (result.getType() == EnumActionResult.SUCCESS) { - useItemDurability(player, hand, player.getHeldItem(hand), replacementStack.copy()); - } - - return result; - } - - @Override - public EnumActionResult useFromToolbelt(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumHand hand, @NotNull EnumFacing facing, - @NotNull ItemStack sprayCan) { - EnumActionResult result = super.useFromToolbelt(player, world, pos, hand, facing, sprayCan); - + protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull ItemStack sprayCan) { + EnumActionResult result = super.spray(player, hand, world, pos, facing, sprayCan); if (result == EnumActionResult.SUCCESS) { - useItemDurability(player, hand, sprayCan, replacementStack.copy()); + useItemDurability(player, hand, player.getHeldItem(hand), replacementStack.copy()); } - return result; } @@ -97,7 +82,6 @@ protected int getUsesLeft(@NotNull ItemStack stack) { if (tagCompound == null || !tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { return maxUses; } - return tagCompound.getInteger(NBT_KEY); } From 4f0822b4bc168d14e0d8c698d6d98f57c8a9b00c Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:17:19 -0400 Subject: [PATCH 011/109] fogor sound --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index d30b51433f5..beb8e4ac79c 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -96,6 +96,8 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } else if (!tryPaintBlock(player, world, pos, facing, getColor(sprayCan))) { return EnumActionResult.PASS; } else { + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, + SoundCategory.PLAYERS, 1.0f, 1.0f); return EnumActionResult.SUCCESS; } } From e463e558f5416ec2aed3070e9ba36d6b77ba24d9 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:17:43 -0400 Subject: [PATCH 012/109] Add textures (ctrl c + v of the gtnh creative spray can) --- .../java/gregtech/common/items/MetaItem1.java | 2 ++ .../spray/AbstractSprayBehavior.java | 2 ++ .../spray/CreativeSprayBehavior.java | 17 +++++++++++++- .../models/item/metaitems/spray.creative.json | 21 ++++++++++++++++++ .../item/metaitems/spray.creative/locked.json | 8 +++++++ .../item/metaitems/spray.creative/normal.json | 7 ++++++ .../items/metaitems/spray.creative/base.png | Bin 0 -> 4583 bytes .../items/metaitems/spray.creative/lock.png | Bin 0 -> 4450 bytes .../metaitems/spray.creative/overlay.png | Bin 0 -> 4456 bytes 9 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json create mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json create mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json create mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/base.png create mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png create mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/overlay.png diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index e10a06c201c..1b9d3087187 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -180,6 +180,8 @@ public void registerSubItems() { SPRAY_CREATIVE = addItem(30, "spray.creative") .addComponents(new CreativeSprayBehavior()); + SPRAY_CREATIVE.getMetaItem().addPropertyOverride(GTUtility.gregtechId("spray.creative"), + (stack, worldIn, entityIn) -> CreativeSprayBehavior.isLocked(stack) ? 1.0f : 0.0f); // Extruder Shapes: ID 31-59 SHAPE_EXTRUDERS[0] = SHAPE_EXTRUDER_PLATE = addItem(31, "shape.extruder.plate") diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index beb8e4ac79c..a6fa0731178 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -6,6 +6,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.Mods; +import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; import net.minecraft.block.BlockColored; @@ -22,6 +23,7 @@ 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.world.World; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 7b5bb5df2bc..319cfd5bba4 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -1,6 +1,7 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; @@ -26,7 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory { +public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider { @Override public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { @@ -90,4 +91,18 @@ public void setColor(@NotNull ItemStack stack, int color) { setColor(stack, null); } } + + @Override + public int getItemStackColor(ItemStack itemStack, int tintIndex) { + EnumDyeColor color = getColor(itemStack); + return color != null && tintIndex == 1 ? color.colorValue : 0xFFFFFF; + } + + public static boolean isLocked(@NotNull ItemStack stack) { + return GTUtility.getOrCreateNbtCompound(stack).getBoolean("Locked"); + } + + public static void setLocked(@NotNull ItemStack stack, boolean locked) { + GTUtility.getOrCreateNbtCompound(stack).setBoolean("Locked", locked); + } } diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json new file mode 100644 index 00000000000..18784119b80 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json @@ -0,0 +1,21 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/metaitems/spray.creative/base", + "layer1": "gregtech:items/metaitems/spray.creative/overlay" + }, + "overrides": [ + { + "predicate": { + "gregtech:spray.creative": 0.0 + }, + "model": "gregtech:item/metaitems/spray.creative/normal" + }, + { + "predicate": { + "gregtech:spray.creative": 1.0 + }, + "model": "gregtech:item/metaitems/spray.creative/locked" + } + ] +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json new file mode 100644 index 00000000000..2c431a94d35 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json @@ -0,0 +1,8 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/metaitems/spray.creative/base", + "layer1": "gregtech:items/metaitems/spray.creative/overlay", + "layer2": "gregtech:items/metaitems/spray.creative/lock" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json new file mode 100644 index 00000000000..bbc05432e18 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/metaitems/spray.creative/base", + "layer1": "gregtech:items/metaitems/spray.creative/overlay" + } +} diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/base.png b/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/base.png new file mode 100644 index 0000000000000000000000000000000000000000..31101e7fa3bd9ea2fddeb7151a9bcd042e3f8af7 GIT binary patch literal 4583 zcmeHKdr(x@8NY%kY(vD>A~7h}#nh;|yLa#2ecU@N23dr)tZo)ego%OsIJ?}!KD_tB zE@ewdaqp>3P++Cj2%ygKE z|FN@o&pqdS-|u|i@B5uIdukl3Gh7u9KZi z0QHMLmrw#wx!ey>5ENVp68zNTXo+pbqX#$D?%rBq#&>recABnyW9j&F?IHC&(SP|B zTgT@QR_%#DV7PiB|E4qg*NvS&Z2NttMYp#hAtsjid)J!6`soE%kL$oW{bl z?H@EOENSYUH&mvt-F4XBhHgqIPlyRD+>zG*@o)N0zI5=|d~(Ovd*{7zu!(GH>=xG_ zZ{E^kd2e%8d_--1PjY`zovQEMXTJHPp`t0l0kSK%4PNNlc{}RgNFLUd^mYM)Osf{s z(;c?-^pT8U9tXC(YRPJSHnF`Rr+rpF{m-Z8LRj|JwLtL-RtMS7?t*AWZU@`+b0>T1`C`;voE!5Sl-jU>9gj@YS+Fat~HN2 z3}>?z_pzFHmfmS*k+kaGjyKw}E&KC6d{5fk-P&>P^wS@Im3sH{=%rD6r=`AXeqU}? z_n-~kZ^@na+nDEHo6{%t*{U>IgCCTh|Cg!rsU1-bPZ&>JE$_pRue-*c+Ld?SQRCj3 zTzmAnGe4K|F23EK_vSzH?l%l>tEfC#cai?+xkbmS7dhh=9@?!sdMxg@Ym?ipzqoU0 z!O-lEgX-6_8&wHZyrW9>*PB%jTW)wi>bqV4%Q-tEo3$q&=pMh_AMxgP&&x>{%C1lU za(Uzn`5gtt5z@iKCOZFebhIaO?z#E)o=8n#>&3yD@@ z_WJs_97sj-uKncR46}Lqk5<(;58NCW8t56abPe2?S*{n4G{0=yiXe}#6`;b_*|TZR z=g}~{j|G~b#}B24ASug(eugUsGRgwC;I*i4oPI}*3cN-Ag29g4{pp}c$l54^oQZvL4%$WuS5qe>JTms-<4sl8V#Aq#TNBCy8})4i2x-vqz1<_ zftx%E{v)cy83+Un-V_(&0HRC;=X5D#2BC6PC=h z*&U-E3I%S#;}3a3vL{%|f@_Sd39%_Np>)Ov0^LV(Cs>c<9x{ejb~|nLaivOlHmgOg ztWWbkPT=X#D*%+i2y`UIFo45I7ML)zUg_$LX2t|49c!Y-LD{^L%y>DVKtXVg0C6aw zXLtj}V+Ny+#Ym&xg_)r*#u#8@1_Z8mG2Tr!dJfjqbhUq|R z8AYiOAmjnFq0>dc$UZUG=PR+Om7q|?b9CAcHx$pvjFpiA1jPxG#wl8-&(+~HVWvqE z!wob(&fdohuJZq9t!y7OC0z6@L4xa-hlav?DhF%`_rl#0A+(uLG_);fh6|@4F=c=c z#R;*(Q(O__bpv>Q3=4K-T=*6-xOhEj#!WaznF$;t6)Blb1_1SBrU0QM4Zsj4X%t=Z zx#R#Nf;2be5po3u8sZ9ldbm_eCPot|0!keqWf)FjxG@(u(|QVi)!Ij&9v~QCQnb!9 zW)dR}oE}Qmz+x`mz>zr5xF|AQwC^arF-4e0(o4}Q2jWOEQ?&n6?y$kQ6BN=C9)l+{ zJm|HfC;c#AFxE%;8J5|jTmnU>7MT>kQ*=$yH7N!rWjv*>DY_=bz@&_))b*Xwr5d{{ z0x$f77l1dx1^ZSmhquTX?2j|8$V2#c$9-?vr?8FjXXQx<^1bgX&$PdF|8x)z&XjHT zjG0$rVrM04_oO!}cE@ejv|RJqKh+(dU5(DMzW$^XaiU;*Y+=ldJ8aCNcrL~fSyK~J z!LiS-_>cDV{#(5(J5R+v94P3Geb-)7_sLz$j<`6k?Jte(pB>^qyfv6#=M+oRE}Tr{ z2K!?=Pkm97e|^tpX~7rwJ1?0lcmArr^6r8qPd#%sq8JOTUwkGWL1wok+=@@!Ua>9i zT*BqbwQ>9Jy_EK|qbkw#2iE@t8(Z}|KD(=}V?*HuDFai0JH literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png b/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf38a228f46b6c553a8e6cbfff8384670f80d09 GIT binary patch literal 4450 zcmeHKYitx%6dqa%ZIP!HP_c|t1O;a2v9Fo2TP(Y!yU60wE(f7V4edKBI|gqW+Y2a%OIunA5OzZnPug$Gh5zqh7VG?pk$C@vb9#YqsRsPb_Pg z(RIz2HDz7hrrK$|#5b8XW{ryGjd@@GD34b@oPYlD>~9XvZ4RvcVC81z@`ch>AhmL=I_t9VTem|c+J8kQTye-T@tr0to?r7el z9qDZ1AKaeRqPDoI49>34q9@N;kKFZS+KyW-yDwCo zrhwY$Lc2-6}aphvKSXm~r z5;iX{GdIpbfFRI#G#(6uR4#7A61W_E*3ATlCS0^K8@Al-LG4NepeBRKK;i{)xtzxG zGSS?K?h@hYxgtVN25R%vzAC5)>iE<>7009t$t}0xW8nk4g%kAll&?)fC z!Eho9l0C>%lYRYU4a!ZQNt81%5g6WwJIK4Y_JlL^a=ST)B1ZM}Tn-ziug^(}C`(-8 z5dhX~0h9^nc_88@0a$Uys1GR%!&?DM308Ihlq;lad`JX36a+WO5XUD`60iyuTo45a z!BA$L5lk#@CIw0qC8L$~`368d5RsuO`M|)ebSMczNrJ%BRuh8@RwIp@D1pLRz_K_` z3p8yNEg~z52`EYA7ATP*58EjRc|Rb+A%9{*C!EXoxNI10Ap0$z0I&IA0Nev|NK#^I z|CCn_f?|!=`J}A0g*H(%%~BM_Sj_!S4}ypawWy;~q`_!O%;=5bU^$RlURNpvNZ4UD zoIL_~O^J9FC1At!q)iVxPC>#l-yIrU|n*Q90ugXWDZ@z?CoNu*;fyT&V#NPY9_` z(ju5C)@Vrz^j|8kUlD!fK(IP;_{aA@Ms**Dzf}Vqi$l!|EEQYe)5Qz04QlnyG13Q`_3wx}JQ`Znt-D1x^6Yb$4{cKY8Wl1&x(iBuOI3@2wfLvp3dt Q!Z^fLu-Ng={52c?1iKF{uK)l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/overlay.png b/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..ab642f8605021c6422e786987c3a7e986d84105d GIT binary patch literal 4456 zcmeHLYj6|S6<%=sK*0eg46mB7$h0KT)jqV6c6TfrBN!ZBn_eI0}3;toe50HB!py|Nets!)MV0-QaYuiF$1Qwgbol=Nx?p*Y|9vTWR*}eNk z{yUbHpI3ujxzF7=y{qQCDd~j)c}>Zx63Zh0{KLuF>regr^Ui}8is$F&y}01D>974E z`sPbVx;I~c{5LyKq%IxbxNmD;(Ye2;inrZ9dUDo>HFes(^~aAoe>tW8Vpnik`<9MX z7&fI-ak>0nmusXRRK@Pi&pJK5%ZrcIuRS(ngYcJ%)S`x#L)*K!=a<_J(?zg?`Su!A6jxN2~En*d&=lXt@s&@W7`1{{#-|O$~JN?!J?|)ME=|2jV<~}#2 z>{;%2dawB`zNi1Ne&UN1SpWR20d2tBVet$eZ#i?(apId>bN9@%ANr_mfO@s=viRoq z;2Hn6@KYsS2WpP|SPPzi`&jVcpMziQ8T`SMTi)1lUU;u&@hhE+YiBOn_q6H2D>Hw+ zuH=~e7dJ25f2XK#ulc9dFPrA_v;7^WcdmB~^<0a-H*jO;u31mzbdzt~rti6NW$M8n zMxI#s*VcdD^>KO5!yEeQo2F`ef8`K1{H>rMk~8P@0^ivjOQQY!l1G@uRiB)i)m3@! z_K%J{IAePM)Q+a8dS&zOGAwxc(OY>Och|Qb+Sz^e`qevE&)#vKx_T|Y%^Kg|{e-t2 z!|qw9Abr*Oss%}nSb(gG(2|VAknk|9v^*IDQWMm15r&nh(|ql%qh?%@o#uyaKFSw! z!A8ZiDGt|eS{;x!HA%c|E-y2cCIti#fjYpGk>;o-B%S6ou7I8mGik=tE_##GT<7!S zE;SBu*1}pSqB5zpGUhT9UK*D}Lalq{Fa&Bj&5gPq6G$?VNLUh9iy9A;G|%%S#gGg` zAP+)oi|QarM70tFB7@+k z+Cq_$2$>zB>6NVrWH_NOjnD#UnUb|oQ(NK^tZao*y(Ak#mPX@aE%D}bIkH5;W*9-P z8XA=zH)NI9=O2wQC{f#1MVSC1#}ZZ<*dgGhkPU{iAlAecq)O17os|J4BPdxE0pnmf zLUdRef~7^8;33ZwfDswSA=xEflG0GJB&<~95rC#siGVO9W6^NB!ysI!@OzzR#zKu* z{LMfQp#Zc7l&GvGw6U&$5`k-VVDL#h7(2sKEW_~*nx-9NPU~S@Ls~RYY06@?r+bWv z5l}gZT3{#@0i^Ay8o?EZKv&}dRc&^fjihiRaj%1Ws1e|a0r2QSS`x<}E__-$!ZW=*Yyk7Zh!X0wuBOgNri76OnmC1{`( z%IQ22R;Ej81ko@=`^T_gN9@X%h#@3fS&nj01kW)P!5UKH95#sb#PN`!SsS!vNE$`g z)R3M4aaa*XJR+`;K+{~|4-8M$gX6PFG(uw@5M>0#6O=tbae|dcKQsA%D37*_REV_^ z9H5XuZB|H#5M=^s2gQUq2pKt}ny;w5EJcizS4tWi;>cu{lK(Z`8HcPL6w#8gp`96R z^yKJHKg<`(_3J!_W%hLrf#Z{dOo-n}x+dwG5Cao(o>bQ)T@zwpLe7)w`pW1sjeRS^ zD0;z5pfADdYcuXcUy*s@swy`&gr07OZ!P-(-KWJoK@G$1zSlUX{IUQ0gUFb#dwrGp zm!=iYD5Pq3w3j0j>vdNIxOb(7xrfgUp<~|4yoS`Ay!ZDwrO!UQUeeq5%))u!CWu!L kz!(0MyD!h*(~kZyaq>l`TQ{jQC?4}xu6Dn?qG8K_0O*l182|tP literal 0 HcmV?d00001 From 924357711da288f3abbb78b0bb033c76fdbba737 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:26:10 -0400 Subject: [PATCH 013/109] Basic lang --- src/main/resources/assets/gregtech/lang/en_us.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 79b97d5b382..5e704a36039 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -362,6 +362,7 @@ metaitem.spray.can.dyes.brown.name=Spray Can (Brown) metaitem.spray.can.dyes.green.name=Spray Can (Green) metaitem.spray.can.dyes.red.name=Spray Can (Red) metaitem.spray.can.dyes.black.name=Spray Can (Black) +metaitem.spray.creative.name=Creative Spray Can metaitem.tool.matches.name=Match metaitem.tool.matchbox.name=Match Box From b7040b18f069bf949a4abc4cff867d60ed7ee7bb Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:55:03 -0400 Subject: [PATCH 014/109] Lang but good --- .../spray/CreativeSprayBehavior.java | 38 +++++++++++++------ .../resources/assets/gregtech/lang/en_us.lang | 20 +++++++++- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 319cfd5bba4..725d2990501 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -2,11 +2,13 @@ import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; +import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; @@ -17,6 +19,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; +import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; @@ -27,7 +30,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider { +public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, + IItemNameProvider { @Override public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { @@ -53,19 +57,23 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager "CCCCCCCC") .key('S', new ButtonWidget<>() .size(18) - .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm())) .onMousePressed(mouse -> { colorSync.setIntValue(-1); return true; - })) - .key('C', index -> new ButtonWidget<>() - .size(18) - .overlay(new ItemDrawable( - MetaItems.SPRAY_CAN_DYES.get(EnumDyeColor.values()[index]).getStackForm())) - .onMousePressed(mouse -> { - colorSync.setIntValue(index); - return true; - })) + }) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm())) + .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) + .key('C', index -> { + EnumDyeColor color = EnumDyeColor.values()[index]; + return new ButtonWidget<>() + .size(18) + .onMousePressed(mouse -> { + colorSync.setIntValue(index); + return true; + }) + .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm())) + .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); + }) .build()); } @@ -105,4 +113,12 @@ public static boolean isLocked(@NotNull ItemStack stack) { public static void setLocked(@NotNull ItemStack stack, boolean locked) { GTUtility.getOrCreateNbtCompound(stack).setBoolean("Locked", locked); } + + @Override + public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedName) { + EnumDyeColor color = getColor(itemStack); + String colorString = color == null ? I18n.format("metaitem.spray.creative.solvent") : + I18n.format("metaitem.spray.creative." + color); + return I18n.format(unlocalizedName, colorString); + } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 5e704a36039..ac48a38e5b7 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -362,7 +362,25 @@ metaitem.spray.can.dyes.brown.name=Spray Can (Brown) metaitem.spray.can.dyes.green.name=Spray Can (Green) metaitem.spray.can.dyes.red.name=Spray Can (Red) metaitem.spray.can.dyes.black.name=Spray Can (Black) -metaitem.spray.creative.name=Creative Spray Can +metaitem.spray.creative.name=Creative Spray Can (%s) +metaitem.spray.creative.solvent=Solvent +metaitem.spray.creative.white=White +metaitem.spray.creative.orange=Orange +metaitem.spray.creative.magenta=Magenta +metaitem.spray.creative.light_blue=Blue +metaitem.spray.creative.yellow=Yellow +metaitem.spray.creative.lime=Lime +metaitem.spray.creative.pink=Pink +metaitem.spray.creative.gray=Gray +metaitem.spray.creative.silver=Gray +metaitem.spray.creative.cyan=Cyan +metaitem.spray.creative.purple=Purple +metaitem.spray.creative.blue=Blue +metaitem.spray.creative.brown=Brown +metaitem.spray.creative.green=Green +metaitem.spray.creative.red=Red +metaitem.spray.creative.black=Black + metaitem.tool.matches.name=Match metaitem.tool.matchbox.name=Match Box From ea13f6ec37c0fe024ed3eaaceb20cbc22f665089 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:10:58 -0400 Subject: [PATCH 015/109] Add a way for MetaItems to handle MouseEvents and add some pattern matching to sooth my soul --- .../gregtech/api/items/metaitem/MetaItem.java | 72 ++++++++++++------- .../items/metaitem/stats/IFoodBehavior.java | 8 +++ .../metaitem/stats/IMouseEventHandler.java | 22 ++++++ .../api/items/toolitem/ItemGTToolbelt.java | 26 +++++-- .../java/gregtech/client/ClientProxy.java | 23 +++--- 5 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index 52b94672421..1180b274646 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -23,6 +23,7 @@ import gregtech.api.items.metaitem.stats.IItemMaxStackSizeProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.items.metaitem.stats.IItemUseManager; +import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.items.metaitem.stats.ISubItemHandler; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.unification.OreDictUnifier; @@ -641,7 +642,7 @@ public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn fluid == null ? "" : fluid.getLocalizedName())); if (fluidHandler instanceof IFilteredFluidContainer filtered && - filtered.getFilter() instanceof IPropertyFluidFilter propertyFilter) { + filtered.getFilter() instanceof IPropertyFluidFilterpropertyFilter) { propertyFilter.appendTooltips(lines, false, true); } } @@ -751,6 +752,15 @@ public void getSubItems(@NotNull CreativeTabs tab, @NotNull NonNullList getMetaItem() { private IItemColorProvider colorProvider; private IItemDurabilityManager durabilityManager; private IEnchantabilityHelper enchantabilityHelper; + private IMouseEventHandler mouseEventHandler; private EnumRarity rarity; private int burnValue = 0; @@ -890,42 +901,46 @@ public MetaValueItem addComponents(IItemComponent... stats) { protected void addItemComponentsInternal(IItemComponent... stats) { for (IItemComponent itemComponent : stats) { - if (itemComponent instanceof IItemNameProvider) { - this.nameProvider = (IItemNameProvider) itemComponent; + if (itemComponent instanceof IItemNameProvider iItemNameProvider) { + this.nameProvider = iItemNameProvider; } - if (itemComponent instanceof IItemMaxStackSizeProvider) { - this.stackSizeProvider = (IItemMaxStackSizeProvider) itemComponent; + if (itemComponent instanceof IItemMaxStackSizeProvider iItemMaxStackSizeProvider) { + this.stackSizeProvider = iItemMaxStackSizeProvider; } - if (itemComponent instanceof ISubItemHandler) { - this.subItemHandler = (ISubItemHandler) itemComponent; + if (itemComponent instanceof ISubItemHandler iSubItemHandler) { + this.subItemHandler = iSubItemHandler; } - if (itemComponent instanceof IItemContainerItemProvider) { - this.containerItemProvider = (IItemContainerItemProvider) itemComponent; + if (itemComponent instanceof IItemContainerItemProvider iItemContainerItemProvider) { + this.containerItemProvider = iItemContainerItemProvider; } - if (itemComponent instanceof IItemDurabilityManager) { - this.durabilityManager = (IItemDurabilityManager) itemComponent; + if (itemComponent instanceof IItemDurabilityManager iItemDurabilityManager) { + this.durabilityManager = iItemDurabilityManager; } - if (itemComponent instanceof IItemUseManager) { - this.useManager = (IItemUseManager) itemComponent; + if (itemComponent instanceof IItemUseManager iItemUseManager) { + this.useManager = iItemUseManager; } - if (itemComponent instanceof IFoodBehavior) { - this.useManager = new FoodUseManager((IFoodBehavior) itemComponent); + if (itemComponent instanceof IFoodBehavior iFoodBehavior) { + this.useManager = iFoodBehavior.createFoodUseManager(); } - if (itemComponent instanceof ItemUIFactory) { - this.uiManager = (ItemUIFactory) itemComponent; + if (itemComponent instanceof ItemUIFactory itemUIFactory) { + this.uiManager = itemUIFactory; } - if (itemComponent instanceof IFilter.Factory) { - this.filterBehavior = (IFilter.Factory) itemComponent; + if (itemComponent instanceof IFilter.Factory filterFactory) { + this.filterBehavior = filterFactory; } - if (itemComponent instanceof IItemColorProvider) { - this.colorProvider = (IItemColorProvider) itemComponent; + if (itemComponent instanceof IItemColorProvider iItemColorProvider) { + this.colorProvider = iItemColorProvider; } - if (itemComponent instanceof IItemBehaviour) { - this.behaviours.add((IItemBehaviour) itemComponent); - ((IItemBehaviour) itemComponent).addPropertyOverride(getMetaItem()); + if (itemComponent instanceof IItemBehaviour iItemBehaviour) { + this.behaviours.add(iItemBehaviour); + iItemBehaviour.addPropertyOverride(getMetaItem()); } - if (itemComponent instanceof IEnchantabilityHelper) { - this.enchantabilityHelper = (IEnchantabilityHelper) itemComponent; + if (itemComponent instanceof IEnchantabilityHelper iEnchantabilityHelper) { + this.enchantabilityHelper = iEnchantabilityHelper; + } + // noinspection PatternVariableHidesField + if (itemComponent instanceof IMouseEventHandler mouseEventHandler) { + this.mouseEventHandler = mouseEventHandler; } this.allStats.add(itemComponent); } @@ -987,6 +1002,11 @@ public IEnchantabilityHelper getEnchantabilityHelper() { return enchantabilityHelper; } + @Nullable + public IMouseEventHandler getMouseEventHandler() { + return mouseEventHandler; + } + public int getBurnValue() { return burnValue; } diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IFoodBehavior.java b/src/main/java/gregtech/api/items/metaitem/stats/IFoodBehavior.java index 2fc74c6d9a1..b36a96cdac0 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IFoodBehavior.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IFoodBehavior.java @@ -1,9 +1,12 @@ package gregtech.api.items.metaitem.stats; +import gregtech.api.items.metaitem.FoodUseManager; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -23,4 +26,9 @@ default ItemStack onFoodEaten(ItemStack stack, EntityPlayer player) { } void addInformation(ItemStack itemStack, List lines); + + @NotNull + default FoodUseManager createFoodUseManager() { + return new FoodUseManager(this); + } } diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java new file mode 100644 index 00000000000..660286f0454 --- /dev/null +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -0,0 +1,22 @@ +package gregtech.api.items.metaitem.stats; + +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.event.MouseEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public interface IMouseEventHandler extends IItemComponent { + + /** + * Handle a mouse event + * + * @param event the event + * @param playerClient the player object on the client side + * @param stack the {@link ItemStack} the player is holding in their main hand + */ + @SideOnly(Side.CLIENT) + void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack); +} diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 2215492949f..e209c21459a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -13,17 +13,21 @@ import gregtech.api.util.LocalizationUtils; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.TooltipHelper; +import gregtech.common.ConfigHolder; import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMaintenanceHatch; import gregtech.core.network.packets.PacketToolbeltSelectionChange; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -37,6 +41,7 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.INBTSerializable; @@ -422,11 +427,22 @@ public ICapabilityProvider initCapabilities(@NotNull ItemStack stack, NBTTagComp } @SideOnly(Side.CLIENT) - public void changeSelectedToolMousewheel(int direction, ItemStack stack) { - ToolStackHandler handler = getHandler(stack); - if (direction < 0) handler.incrementSelectedSlot(); - else handler.decrementSelectedSlot(); - PacketToolbeltSelectionChange.toServer(handler.selectedSlot); + public void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull ItemStack stack) { + if (!ConfigHolder.client.toolbeltConfig.enableToolbeltScrollingCapture) return; + if (event.getDwheel() != 0 && playerClient.isSneaking()) { + ItemStack copy = stack.copy(); + ToolStackHandler handler = getHandler(copy); + if (event.getDwheel() < 0) { + handler.incrementSelectedSlot(); + } else { + handler.decrementSelectedSlot(); + } + PacketToolbeltSelectionChange.toServer(handler.selectedSlot); + InventoryPlayer inv = Minecraft.getMinecraft().player.inventory; + inv.mainInventory.set(inv.currentItem, stack); + event.setCanceled(true); + } } @SideOnly(Side.CLIENT) diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index f9b712309a2..3477811e296 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -2,7 +2,9 @@ import gregtech.api.GTValues; import gregtech.api.fluids.GTFluidRegistration; +import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.MetaOreDictItem; +import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.items.toolitem.IGTTool; import gregtech.api.items.toolitem.ItemGTToolbelt; import gregtech.api.unification.OreDictUnifier; @@ -46,12 +48,12 @@ import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.SimpleReloadableResourceManager; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -352,19 +354,16 @@ public boolean isFancyGraphics() { @SubscribeEvent(priority = EventPriority.HIGH) public static void onMouseEvent(@NotNull MouseEvent event) { - if (!ConfigHolder.client.toolbeltConfig.enableToolbeltScrollingCapture) return; EntityPlayerSP player = Minecraft.getMinecraft().player; - if (event.getDwheel() != 0 && player.isSneaking()) { - ItemStack stack = player.getHeldItemMainhand(); - if (stack.getItem() instanceof ItemGTToolbelt toolbelt) { - // vanilla code in GuiIngame line 1235 does not copy the stack before storing it in the highlighting - // item stack, so unless we copy the stack the tool highlight will not refresh. - stack = stack.copy(); - toolbelt.changeSelectedToolMousewheel(event.getDwheel(), stack); - InventoryPlayer inv = Minecraft.getMinecraft().player.inventory; - inv.mainInventory.set(inv.currentItem, stack); - event.setCanceled(true); + ItemStack stack = player.getHeldItemMainhand(); + Item item = stack.getItem(); + if (item instanceof MetaItemmetaItem) { + IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); + if (mouseEventHandler != null) { + mouseEventHandler.handleMouseEvent(event, player, stack); } + } else if (item instanceof ItemGTToolbelt toolbelt) { + toolbelt.handleMouseEvent(event, player, stack); } } From f445deb4f91738f2d913404914edd5ea1039cb32 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:51:05 -0400 Subject: [PATCH 016/109] Implement generic mouse event packet handling for meta items --- .../metaitem/stats/IMouseEventHandler.java | 21 +++- .../java/gregtech/client/ClientProxy.java | 2 +- .../spray/CreativeSprayBehavior.java | 12 +- src/main/java/gregtech/core/CoreModule.java | 16 +-- .../network/packets/PacketItemMouseEvent.java | 106 ++++++++++++++++++ 5 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 660286f0454..f55715422d0 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -1,6 +1,9 @@ package gregtech.api.items.metaitem.stats; +import gregtech.core.network.packets.PacketItemMouseEvent; + import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.fml.relauncher.Side; @@ -11,12 +14,26 @@ public interface IMouseEventHandler extends IItemComponent { /** - * Handle a mouse event + * Handle a mouse event on the client side * * @param event the event * @param playerClient the player object on the client side * @param stack the {@link ItemStack} the player is holding in their main hand */ @SideOnly(Side.CLIENT) - void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack); + default void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull ItemStack stack) { + PacketItemMouseEvent.toServer(event); + } + + /** + * Handle a mouse event on the server side + * + * @param packet the packet containing the data from the client event + * @param playerServer the server side counterpart of the client player + * @param stack the stack the player was holding upon receiving the packet + */ + @SideOnly(Side.SERVER) + void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, + @NotNull ItemStack stack); } diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 3477811e296..74018757e42 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -360,7 +360,7 @@ public static void onMouseEvent(@NotNull MouseEvent event) { if (item instanceof MetaItemmetaItem) { IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); if (mouseEventHandler != null) { - mouseEventHandler.handleMouseEvent(event, player, stack); + mouseEventHandler.handleMouseEventClient(event, player, stack); } } else if (item instanceof ItemGTToolbelt toolbelt) { toolbelt.handleMouseEvent(event, player, stack); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 725d2990501..d346eaed2d0 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -3,13 +3,17 @@ import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; +import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; +import gregtech.core.network.packets.PacketItemMouseEvent; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -31,7 +35,7 @@ import org.jetbrains.annotations.Nullable; public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, - IItemNameProvider { + IItemNameProvider, IMouseEventHandler { @Override public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { @@ -121,4 +125,10 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam I18n.format("metaitem.spray.creative." + color); return I18n.format(unlocalizedName, colorString); } + + @Override + public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, + @NotNull ItemStack stack) { + GTLog.logger.info("Received packet %s on item %s for player \"%s\"", packet, stack, playerServer.getName()); + } } diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 6ea9f2a3d94..c386877749c 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -60,6 +60,7 @@ import gregtech.core.network.packets.PacketClipboardNBTUpdate; import gregtech.core.network.packets.PacketClipboardUIWidgetUpdate; import gregtech.core.network.packets.PacketFluidVeinList; +import gregtech.core.network.packets.PacketItemMouseEvent; import gregtech.core.network.packets.PacketKeysPressed; import gregtech.core.network.packets.PacketNotifyCapeChange; import gregtech.core.network.packets.PacketPluginSynced; @@ -132,7 +133,7 @@ public Logger getLogger() { } @Override - public void preInit(FMLPreInitializationEvent event) { + public void preInit(@NotNull FMLPreInitializationEvent event) { GregTechAPIInternal.preInit(); GregTechAPI.advancementManager = AdvancementManager.getInstance(); AdvancementTriggers.register(); @@ -246,10 +247,11 @@ public void registerPackets() { GregTechAPI.networkHandler.registerPacket(PacketClipboardNBTUpdate.class); GregTechAPI.networkHandler.registerPacket(PacketToolbeltSelectionChange.Server.class); GregTechAPI.networkHandler.registerPacket(PacketToolbeltSelectionChange.Client.class); + GregTechAPI.networkHandler.registerPacket(PacketItemMouseEvent.class); } @Override - public void init(FMLInitializationEvent event) { + public void init(@NotNull FMLInitializationEvent event) { // freeze once addon preInit is finished for (MTERegistry registry : mteManager.getRegistries()) { registry.freeze(); @@ -288,7 +290,7 @@ public void init(FMLInitializationEvent event) { } @Override - public void postInit(FMLPostInitializationEvent event) { + public void postInit(@NotNull FMLPostInitializationEvent event) { proxy.onPostLoad(); BedrockFluidVeinHandler.recalculateChances(true); // registers coil types for the BlastTemperatureProperty used in Blast Furnace Recipes @@ -306,12 +308,12 @@ public void postInit(FMLPostInitializationEvent event) { } @Override - public void loadComplete(FMLLoadCompleteEvent event) { + public void loadComplete(@NotNull FMLLoadCompleteEvent event) { proxy.onLoadComplete(); } @Override - public void serverStarting(FMLServerStartingEvent event) { + public void serverStarting(@NotNull FMLServerStartingEvent event) { CommandManager commandManager = CommandManager.getInstance(); GregTechAPI.commandManager = commandManager; commandManager.registerServerCommand(event); @@ -329,7 +331,7 @@ public void serverStarting(FMLServerStartingEvent event) { } @Override - public void serverStarted(FMLServerStartedEvent event) { + public void serverStarted(@NotNull FMLServerStartedEvent event) { if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { World world = FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld(); if (!world.isRemote) { @@ -347,7 +349,7 @@ public void serverStarted(FMLServerStartedEvent event) { } @Override - public void serverStopped(FMLServerStoppedEvent event) { + public void serverStopped(@NotNull FMLServerStoppedEvent event) { VirtualEnderRegistry.clearMaps(); CapesRegistry.clearMaps(); } diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java new file mode 100644 index 00000000000..3b6f9d6c2c5 --- /dev/null +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -0,0 +1,106 @@ +package gregtech.core.network.packets; + +import gregtech.api.GregTechAPI; +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.stats.IMouseEventHandler; +import gregtech.api.network.IPacket; +import gregtech.api.network.IServerExecutor; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.client.event.MouseEvent; + +import org.jetbrains.annotations.NotNull; + +public class PacketItemMouseEvent implements IPacket, IServerExecutor { + + private int x; + private int y; + private int dx; + private int dy; + private int dwheel; + private int button; + private boolean buttonstate; + + @Override + public void encode(PacketBuffer buf) { + buf.writeVarInt(x); + buf.writeVarInt(y); + buf.writeVarInt(dx); + buf.writeVarInt(dy); + buf.writeVarInt(dwheel); + buf.writeVarInt(button); + buf.writeBoolean(buttonstate); + } + + @Override + public void decode(PacketBuffer buf) { + x = buf.readVarInt(); + y = buf.readVarInt(); + dx = buf.readVarInt(); + dy = buf.readVarInt(); + dwheel = buf.readVarInt(); + button = buf.readVarInt(); + buttonstate = buf.readBoolean(); + } + + public static void toServer(@NotNull MouseEvent event) { + PacketItemMouseEvent packet = new PacketItemMouseEvent(); + packet.x = event.getX(); + packet.y = event.getY(); + packet.dx = event.getDx(); + packet.dy = event.getDy(); + packet.dwheel = event.getDwheel(); + packet.button = event.getButton(); + packet.buttonstate = event.isButtonstate(); + GregTechAPI.networkHandler.sendToServer(packet); + } + + @Override + public void executeServer(NetHandlerPlayServer handler) { + EntityPlayerMP player = handler.player; + ItemStack stack = player.getHeldItemMainhand(); + if (stack.getItem() instanceof MetaItemmetaItem) { + IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); + if (mouseEventHandler != null) { + mouseEventHandler.handleMouseEventServer(this, player, stack); + } + } + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getDx() { + return dx; + } + + public int getDy() { + return dy; + } + + public int getDwheel() { + return dwheel; + } + + public int getButton() { + return button; + } + + public boolean buttonState() { + return buttonstate; + } + + @Override + public String toString() { + return String.format("X: %d, Y: %d, Dx: %d, Dy: %d, DWheel: %d, Button: %d, Button State: %b", + x, y, dx, dy, dwheel, button, buttonstate); + } +} From 5de34452ad1101f5531511f7df5dada2fb1b1269 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 23:05:00 -0400 Subject: [PATCH 017/109] Add javadocs to PacketItemMouseEvent describing what each value means. --- .../network/packets/PacketItemMouseEvent.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java index 3b6f9d6c2c5..d540d1794ae 100644 --- a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; +@SuppressWarnings("unused") public class PacketItemMouseEvent implements IPacket, IServerExecutor { private int x; @@ -70,30 +71,59 @@ public void executeServer(NetHandlerPlayServer handler) { } } + /** + * The absolute X position of the cursor. + */ public int getX() { return x; } + /** + * The absolute Y position of the cursor. + */ public int getY() { return y; } + /** + * The delta of cursor movement on the X axis. + */ public int getDx() { return dx; } + /** + * The delta of cursor movement on the Y axis. + */ public int getDy() { return dy; } + /** + * The scroll wheel delta.
+ * {@code -120} = scrolling down
+ * {@code 0} = no scrolling
+ * {@code 120} = scrolling up + */ public int getDwheel() { return dwheel; } + /** + * Which mouse button is being reported.
+ * {@code 0} = left click
+ * {@code 1} = right click
+ * {@code 2} = middle click + */ public int getButton() { return button; } + /** + * If the reported mouse button has been pressed down or released.
+ * {@code true} = pressed
+ * {@code false} = unpressed + */ public boolean buttonState() { return buttonstate; } From 34628ca27a3f91189af94c56caf12c8c966e6bdc Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 23:29:46 -0400 Subject: [PATCH 018/109] Add line about -1 = no click --- .../java/gregtech/core/network/packets/PacketItemMouseEvent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java index d540d1794ae..43df7f248e3 100644 --- a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -111,6 +111,7 @@ public int getDwheel() { /** * Which mouse button is being reported.
+ * {@code -1} = no click
* {@code 0} = left click
* {@code 1} = right click
* {@code 2} = middle click From d674ebccca3e538ccf38402f93648673b8d094bb Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 23:30:14 -0400 Subject: [PATCH 019/109] Precheck if there is no held item in onMouseEvent --- src/main/java/gregtech/client/ClientProxy.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 74018757e42..afac2ecb6c3 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -356,6 +356,8 @@ public boolean isFancyGraphics() { public static void onMouseEvent(@NotNull MouseEvent event) { EntityPlayerSP player = Minecraft.getMinecraft().player; ItemStack stack = player.getHeldItemMainhand(); + if (stack.isEmpty()) return; + Item item = stack.getItem(); if (item instanceof MetaItemmetaItem) { IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); From f94aaf4b91526e74785b5651c441f86acdc53aab Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 23:32:49 -0400 Subject: [PATCH 020/109] Have the default handleMouseEventClient impl send the packet if only a mouse button or scroll event happened (looking around emits an event per tick, too many packets!) --- .../metaitem/stats/IMouseEventHandler.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index f55715422d0..803286c7ed9 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -11,10 +11,15 @@ import org.jetbrains.annotations.NotNull; +/** + * Implement on your {@link IItemComponent} to handle mouse event while the corresponding item is selected on the main + * hotbar.
+ * By default, it will only send events to the server when a mouse button was pressed or the mouse wheel was scrolled. + */ public interface IMouseEventHandler extends IItemComponent { /** - * Handle a mouse event on the client side + * Handle a mouse event on the client side. * * @param event the event * @param playerClient the player object on the client side @@ -23,17 +28,29 @@ public interface IMouseEventHandler extends IItemComponent { @SideOnly(Side.CLIENT) default void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack) { - PacketItemMouseEvent.toServer(event); + if (event.getButton() != -1 || event.getDwheel() != 0) { + PacketItemMouseEvent.toServer(event); + if (defaultCancel()) { + event.setCanceled(true); + } + } } /** - * Handle a mouse event on the server side - * + * If the default {@link #handleMouseEventClient(MouseEvent, EntityPlayerSP, ItemStack)} method should cancel the + * event after sending the packet. + */ + default boolean defaultCancel() { + return true; + } + + /** + * Handle the mouse event on the server side. + * * @param packet the packet containing the data from the client event * @param playerServer the server side counterpart of the client player * @param stack the stack the player was holding upon receiving the packet */ - @SideOnly(Side.SERVER) void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, @NotNull ItemStack stack); } From fca8000bf5a9bed95dc65ff9a6825149a0818784 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 20 Jul 2025 23:48:51 -0400 Subject: [PATCH 021/109] Make handleMouseEventClient not have a default --- .../metaitem/stats/IMouseEventHandler.java | 21 +++---------------- .../spray/CreativeSprayBehavior.java | 12 ++++++++++- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 803286c7ed9..4c540b5946d 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -26,26 +26,11 @@ public interface IMouseEventHandler extends IItemComponent { * @param stack the {@link ItemStack} the player is holding in their main hand */ @SideOnly(Side.CLIENT) - default void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, - @NotNull ItemStack stack) { - if (event.getButton() != -1 || event.getDwheel() != 0) { - PacketItemMouseEvent.toServer(event); - if (defaultCancel()) { - event.setCanceled(true); - } - } - } - - /** - * If the default {@link #handleMouseEventClient(MouseEvent, EntityPlayerSP, ItemStack)} method should cancel the - * event after sending the packet. - */ - default boolean defaultCancel() { - return true; - } + void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull ItemStack stack); /** - * Handle the mouse event on the server side. + * Handle the received mouse event on the server side. * * @param packet the packet containing the data from the client event * @param playerServer the server side counterpart of the client player diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index d346eaed2d0..ac128a61395 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -11,6 +11,7 @@ import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -21,6 +22,7 @@ import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.world.World; +import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; import com.cleanroommc.modularui.api.drawable.IKey; @@ -126,9 +128,17 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam return I18n.format(unlocalizedName, colorString); } + @Override + public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull ItemStack stack) { + if (event.getButton() != -1 || (event.getDwheel() != 0 && playerClient.isSneaking())) { + PacketItemMouseEvent.toServer(event); + } + } + @Override public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, @NotNull ItemStack stack) { - GTLog.logger.info("Received packet %s on item %s for player \"%s\"", packet, stack, playerServer.getName()); + GTLog.logger.info("Received packet {} on item {} for player \"{}\"", packet, stack, playerServer.getName()); } } From 7133c239811603c071312f22aa4a4d59266321f7 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:37:47 -0400 Subject: [PATCH 022/109] Forgot to remove comment after removing default impl --- .../gregtech/api/items/metaitem/stats/IMouseEventHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 4c540b5946d..9a6161b1e19 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -13,8 +13,7 @@ /** * Implement on your {@link IItemComponent} to handle mouse event while the corresponding item is selected on the main - * hotbar.
- * By default, it will only send events to the server when a mouse button was pressed or the mouse wheel was scrolled. + * hotbar. */ public interface IMouseEventHandler extends IItemComponent { From 5ff6d73f4a082e5ed615f93f76b9608dc7867b52 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:41:47 -0400 Subject: [PATCH 023/109] Mention how MouseEvents are spammed when looking around --- .../gregtech/api/items/metaitem/stats/IMouseEventHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 9a6161b1e19..207f8eaa988 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -18,7 +18,9 @@ public interface IMouseEventHandler extends IItemComponent { /** - * Handle a mouse event on the client side. + * Handle a mouse event on the client side.
+ * Use {@link PacketItemMouseEvent#toServer(MouseEvent)} to send the event to the server.
+ * Try to only act on mouse clicks or scrolls as looking around spams this event. * * @param event the event * @param playerClient the player object on the client side From 113d9559e0bb6e1d4ce04f8b8c62d773a9cbf753 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 10:04:29 -0400 Subject: [PATCH 024/109] lang error --- src/main/resources/assets/gregtech/lang/en_us.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index ac48a38e5b7..5399a45de4d 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -367,7 +367,7 @@ metaitem.spray.creative.solvent=Solvent metaitem.spray.creative.white=White metaitem.spray.creative.orange=Orange metaitem.spray.creative.magenta=Magenta -metaitem.spray.creative.light_blue=Blue +metaitem.spray.creative.lightBlue=Light Blue metaitem.spray.creative.yellow=Yellow metaitem.spray.creative.lime=Lime metaitem.spray.creative.pink=Pink From 1b1619d80a8ddd766eae087e43a8e5e842f4cbc5 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:01:09 -0400 Subject: [PATCH 025/109] Make the packet handling not bad --- .../metaitem/stats/IMouseEventHandler.java | 28 ++++- .../spray/CreativeSprayBehavior.java | 45 +++++++- .../network/packets/PacketItemMouseEvent.java | 108 +++--------------- 3 files changed, 77 insertions(+), 104 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 207f8eaa988..8c16e50e619 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -5,21 +5,39 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; +import java.util.function.Consumer; + /** - * Implement on your {@link IItemComponent} to handle mouse event while the corresponding item is selected on the main - * hotbar. + * Implement on your {@link IItemComponent} to handle mouse events while the corresponding item is selected on the main + * hotbar.
+ * {@link MouseEvent#getX()}: The absolute position of the cursor on the X axis
+ * {@link MouseEvent#getY()}: The absolute position of the cursor on the Y axis
+ * {@link MouseEvent#getDx()}: The delta of cursor movement on the X axis
+ * {@link MouseEvent#getDy()}: The delta of cursor movement on the Y axis
+ * {@link MouseEvent#getDwheel()}: The scroll wheel delta:
+ * {@code -120} = scrolling down
+ * {@code 0} = no scrolling
+ * {@code 120} = scrolling up
+ * {@link MouseEvent#getButton()}: Which mouse button is being reported
+ * {@code -1} = no click
+ * {@code 0} = left click
+ * {@code 1} = right click
+ * {@code 2} = middle click
+ * {@link MouseEvent#isButtonstate()}: If the reported mouse button has been pressed down or released:
+ * {@code true} = pressed
+ * {@code false} = unpressed */ public interface IMouseEventHandler extends IItemComponent { /** * Handle a mouse event on the client side.
- * Use {@link PacketItemMouseEvent#toServer(MouseEvent)} to send the event to the server.
* Try to only act on mouse clicks or scrolls as looking around spams this event. * * @param event the event @@ -30,6 +48,10 @@ public interface IMouseEventHandler extends IItemComponent { void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack); + default void sendToServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { + PacketItemMouseEvent.toServer(bufferWriter); + } + /** * Handle the received mouse event on the server side. * diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index ac128a61395..84fcb9405a1 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -6,7 +6,6 @@ import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; -import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; @@ -18,9 +17,11 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; +import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; @@ -94,11 +95,11 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager return null; } - public void setColor(@NotNull ItemStack stack, @Nullable EnumDyeColor color) { + public static void setColor(@NotNull ItemStack stack, @Nullable EnumDyeColor color) { GTUtility.getOrCreateNbtCompound(stack).setInteger("color", color == null ? -1 : color.ordinal()); } - public void setColor(@NotNull ItemStack stack, int color) { + public static void setColor(@NotNull ItemStack stack, int color) { if (color >= 0 && color <= 15) { setColor(stack, EnumDyeColor.values()[color]); } else { @@ -120,6 +121,10 @@ public static void setLocked(@NotNull ItemStack stack, boolean locked) { GTUtility.getOrCreateNbtCompound(stack).setBoolean("Locked", locked); } + public static void toggleLocked(@NotNull ItemStack stack) { + setLocked(stack, !isLocked(stack)); + } + @Override public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedName) { EnumDyeColor color = getColor(itemStack); @@ -131,14 +136,42 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam @Override public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack) { - if (event.getButton() != -1 || (event.getDwheel() != 0 && playerClient.isSneaking())) { - PacketItemMouseEvent.toServer(event); + if ((event.getButton() != -1 && event.isButtonstate()) || event.getDwheel() != 0) { + int button = event.getButton(); + int scroll = event.getDwheel(); + + if (button == 0) { + setColor(stack, getColorOrdinal(stack) + 1); + event.setCanceled(true); + // TODO: sneak click rotates colors the other way + } else if (button == 2) { + toggleLocked(stack); + event.setCanceled(true); + } + + sendToServer(buf -> buf + .writeVarInt(button) + .writeVarInt(scroll)); } } @Override public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, @NotNull ItemStack stack) { - GTLog.logger.info("Received packet {} on item {} for player \"{}\"", packet, stack, playerServer.getName()); + PacketBuffer buf = packet.getBuffer(); + int button = buf.readVarInt(); + int scroll = buf.readVarInt(); + + if (button == 0) { + setColor(stack, getColorOrdinal(stack) + 1); + // TODO: sneak click rotates colors the other way + } else if (button == 2) { + toggleLocked(stack); + EnumDyeColor color = getColor(stack); + // TODO: lang + playerServer.sendStatusMessage(new TextComponentString( + isLocked(stack) ? String.format("Locked to %s", color == null ? "solvent" : color) : "Unlocked"), + true); + } } } diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java index 43df7f248e3..563b5fdde16 100644 --- a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -10,52 +10,34 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; -import net.minecraftforge.client.event.MouseEvent; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.jetbrains.annotations.NotNull; -@SuppressWarnings("unused") +import java.util.function.Consumer; + public class PacketItemMouseEvent implements IPacket, IServerExecutor { - private int x; - private int y; - private int dx; - private int dy; - private int dwheel; - private int button; - private boolean buttonstate; + private final ByteBuf internalBuffer = Unpooled.buffer(); + + public @NotNull PacketBuffer getBuffer() { + return new PacketBuffer(internalBuffer.asReadOnly()); + } @Override public void encode(PacketBuffer buf) { - buf.writeVarInt(x); - buf.writeVarInt(y); - buf.writeVarInt(dx); - buf.writeVarInt(dy); - buf.writeVarInt(dwheel); - buf.writeVarInt(button); - buf.writeBoolean(buttonstate); + buf.writeBytes(internalBuffer.array()); } @Override public void decode(PacketBuffer buf) { - x = buf.readVarInt(); - y = buf.readVarInt(); - dx = buf.readVarInt(); - dy = buf.readVarInt(); - dwheel = buf.readVarInt(); - button = buf.readVarInt(); - buttonstate = buf.readBoolean(); + internalBuffer.writeBytes(buf.array()); } - public static void toServer(@NotNull MouseEvent event) { + public static void toServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { PacketItemMouseEvent packet = new PacketItemMouseEvent(); - packet.x = event.getX(); - packet.y = event.getY(); - packet.dx = event.getDx(); - packet.dy = event.getDy(); - packet.dwheel = event.getDwheel(); - packet.button = event.getButton(); - packet.buttonstate = event.isButtonstate(); + bufferWriter.accept(new PacketBuffer(packet.internalBuffer)); GregTechAPI.networkHandler.sendToServer(packet); } @@ -70,68 +52,4 @@ public void executeServer(NetHandlerPlayServer handler) { } } } - - /** - * The absolute X position of the cursor. - */ - public int getX() { - return x; - } - - /** - * The absolute Y position of the cursor. - */ - public int getY() { - return y; - } - - /** - * The delta of cursor movement on the X axis. - */ - public int getDx() { - return dx; - } - - /** - * The delta of cursor movement on the Y axis. - */ - public int getDy() { - return dy; - } - - /** - * The scroll wheel delta.
- * {@code -120} = scrolling down
- * {@code 0} = no scrolling
- * {@code 120} = scrolling up - */ - public int getDwheel() { - return dwheel; - } - - /** - * Which mouse button is being reported.
- * {@code -1} = no click
- * {@code 0} = left click
- * {@code 1} = right click
- * {@code 2} = middle click - */ - public int getButton() { - return button; - } - - /** - * If the reported mouse button has been pressed down or released.
- * {@code true} = pressed
- * {@code false} = unpressed - */ - public boolean buttonState() { - return buttonstate; - } - - @Override - public String toString() { - return String.format("X: %d, Y: %d, Dx: %d, Dy: %d, DWheel: %d, Button: %d, Button State: %b", - x, y, dx, dy, dwheel, button, buttonstate); - } } From c8b59eca8e710695d8223d6ba8674495c3147546 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:09:12 -0400 Subject: [PATCH 026/109] un bork the packet copying --- .../gregtech/core/network/packets/PacketItemMouseEvent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java index 563b5fdde16..d30d81d8a05 100644 --- a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -27,12 +27,12 @@ public class PacketItemMouseEvent implements IPacket, IServerExecutor { @Override public void encode(PacketBuffer buf) { - buf.writeBytes(internalBuffer.array()); + buf.writeBytes(internalBuffer); } @Override public void decode(PacketBuffer buf) { - internalBuffer.writeBytes(buf.array()); + internalBuffer.writeBytes(buf); } public static void toServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { From 851cb25e2a779ae6ceaba077e8fb02101f779348 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:17:07 -0400 Subject: [PATCH 027/109] Don't allow changing the color if it's locked --- .../items/behaviors/spray/CreativeSprayBehavior.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 84fcb9405a1..4bc9ad343ad 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -45,7 +45,13 @@ public ActionResult onItemRightClick(World world, EntityPlayer player ItemStack heldItem = player.getHeldItem(hand); if (!world.isRemote) { - MetaItemGuiFactory.open(player, hand); + if (isLocked(heldItem)) { + // TODO: lang + player.sendStatusMessage( + new TextComponentString("Cannot open selector UI because the spray can is locked"), true); + } else { + MetaItemGuiFactory.open(player, hand); + } } return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); @@ -162,9 +168,9 @@ public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNul int button = buf.readVarInt(); int scroll = buf.readVarInt(); - if (button == 0) { - setColor(stack, getColorOrdinal(stack) + 1); + if (button == 0 && !isLocked(stack)) { // TODO: sneak click rotates colors the other way + setColor(stack, getColorOrdinal(stack) + 1); } else if (button == 2) { toggleLocked(stack); EnumDyeColor color = getColor(stack); From a6abf2088aa295d49d0225ceb04c728de84ec0d2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:14:42 -0400 Subject: [PATCH 028/109] Re-add comment I accidentally deleted when moving code around --- src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index e209c21459a..84220893888 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -431,6 +431,8 @@ public void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP @NotNull ItemStack stack) { if (!ConfigHolder.client.toolbeltConfig.enableToolbeltScrollingCapture) return; if (event.getDwheel() != 0 && playerClient.isSneaking()) { + // vanilla code in GuiIngame line 1235 does not copy the stack before storing it in the highlighting + // item stack, so unless we copy the stack the tool highlight will not refresh. ItemStack copy = stack.copy(); ToolStackHandler handler = getHandler(copy); if (event.getDwheel() < 0) { From bdfe101a592ce54b6f06a0e5ee1d07d2c273d3ec Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 2 Aug 2025 13:10:27 -0400 Subject: [PATCH 029/109] Add overload to MTE#setPaintingColor with EnumFacing --- src/main/java/gregtech/api/block/machines/BlockMachine.java | 5 +++-- .../java/gregtech/api/metatileentity/MetaTileEntity.java | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index 5fd28ce1130..37336005839 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -257,9 +257,10 @@ public EnumFacing[] getValidRotations(@NotNull World world, @NotNull BlockPos po public boolean recolorBlock(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing side, @NotNull EnumDyeColor color) { MetaTileEntity metaTileEntity = getMetaTileEntity(world, pos); - if (metaTileEntity == null || metaTileEntity.getPaintingColor() == color.colorValue) + if (metaTileEntity == null || metaTileEntity.getPaintingColor() == color.colorValue) { return false; - metaTileEntity.setPaintingColor(color.colorValue); + } + metaTileEntity.setPaintingColor(color.colorValue, side); return true; } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index c39b082e68a..97fe11fb64e 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -1278,6 +1278,10 @@ public void setFrontFacing(EnumFacing frontFacing) { } public void setPaintingColor(int paintingColor) { + setPaintingColor(paintingColor, null); + } + + public void setPaintingColor(int paintingColor, @Nullable EnumFacing side) { this.paintingColor = paintingColor; if (getWorld() != null && !getWorld().isRemote) { notifyBlockUpdate(); From dd4fd04c178d19b96b18b3c0ac57ccad70ab814c Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 2 Aug 2025 13:44:32 -0400 Subject: [PATCH 030/109] Support all AE2 tiles instead of only cables and redo mouse logic --- .../metaitem/stats/IMouseEventHandler.java | 1 + .../java/gregtech/client/ClientProxy.java | 2 +- .../spray/AbstractSprayBehavior.java | 36 ++--- .../spray/CreativeSprayBehavior.java | 136 ++++++++++++------ 4 files changed, 112 insertions(+), 63 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 8c16e50e619..033f1195f0f 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -14,6 +14,7 @@ import java.util.function.Consumer; +// TODO: add EnumHand to the methods/support for offhand items /** * Implement on your {@link IItemComponent} to handle mouse events while the corresponding item is selected on the main * hotbar.
diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index afac2ecb6c3..e7486d6c994 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -355,7 +355,7 @@ public boolean isFancyGraphics() { @SubscribeEvent(priority = EventPriority.HIGH) public static void onMouseEvent(@NotNull MouseEvent event) { EntityPlayerSP player = Minecraft.getMinecraft().player; - ItemStack stack = player.getHeldItemMainhand(); + ItemStack stack = player.getHeldItemMainhand(); // Todo main hand first, then try offhand if (stack.isEmpty()) return; Item item = stack.getItem(); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index a6fa0731178..4cf5c033925 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -27,10 +27,11 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import appeng.api.implementations.tiles.IColorableTile; import appeng.api.util.AEColor; -import appeng.tile.networking.TileCableBus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; public abstract class AbstractSprayBehavior implements IItemBehaviour { @@ -46,7 +47,7 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { */ public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack stack); - public int getColorOrdinal(@NotNull ItemStack stack) { + public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack stack) { EnumDyeColor color = getColor(stack); return color == null ? -1 : color.ordinal(); } @@ -114,11 +115,12 @@ protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World wor return tryStripBlockColor(player, world, pos, block, side); } - return block.recolorBlock(world, pos, side, color) || tryPaintSpecialBlock(player, world, pos, block, color); + return block.recolorBlock(world, pos, side, color) || + tryPaintSpecialBlock(player, world, pos, block, side, color); } private boolean tryPaintSpecialBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull Block block, @NotNull EnumDyeColor color) { + @NotNull Block block, @NotNull EnumFacing side, @NotNull EnumDyeColor color) { if (block == Blocks.GLASS) { // noinspection DataFlowIssue IBlockState newBlockState = Blocks.STAINED_GLASS.getDefaultState() @@ -139,10 +141,10 @@ private boolean tryPaintSpecialBlock(@NotNull EntityPlayer player, @NotNull Worl return true; } else if (Mods.AppliedEnergistics2.isModLoaded()) { TileEntity te = world.getTileEntity(pos); - 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); + if (te instanceof IColorableTile colorableTE) { + // Do not try to recolor if it already is this color + if (colorableTE.getColor().ordinal() != color.ordinal()) { + colorableTE.recolourBlock(side, AEColor.values()[color.ordinal()], player); return true; } } @@ -151,8 +153,8 @@ private boolean tryPaintSpecialBlock(@NotNull EntityPlayer player, @NotNull Worl return false; } - protected static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block, - EnumFacing side) { + protected static boolean tryStripBlockColor(@NotNull EntityPlayer player, @NotNull World world, + @NotNull BlockPos pos, @NotNull Block block, @NotNull EnumFacing side) { // MC special cases if (block == Blocks.STAINED_GLASS) { world.setBlockState(pos, Blocks.GLASS.getDefaultState()); @@ -167,8 +169,8 @@ protected static boolean tryStripBlockColor(EntityPlayer player, World world, Bl // MTE special case TileEntity te = world.getTileEntity(pos); - if (te instanceof IGregTechTileEntity) { - MetaTileEntity mte = ((IGregTechTileEntity) te).getMetaTileEntity(); + if (te instanceof IGregTechTileEntity gtte) { + MetaTileEntity mte = gtte.getMetaTileEntity(); if (mte != null) { if (mte.isPainted()) { mte.setPaintingColor(-1); @@ -189,10 +191,10 @@ protected static boolean tryStripBlockColor(EntityPlayer player, World world, Bl // AE2 cable special case if (Mods.AppliedEnergistics2.isModLoaded()) { - 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); + if (te instanceof IColorableTile colorableTE) { + // Do not try to strip color if it is already colorless + if (colorableTE.getColor() != AEColor.TRANSPARENT) { + colorableTE.recolourBlock(side, AEColor.TRANSPARENT, player); return true; } else return false; } @@ -200,7 +202,7 @@ protected static boolean tryStripBlockColor(EntityPlayer player, World world, Bl // General case IBlockState state = world.getBlockState(pos); - for (IProperty prop : state.getProperties().keySet()) { + for (IProperty prop : state.getPropertyKeys()) { if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { IBlockState defaultState = block.getDefaultState(); EnumDyeColor defaultColor = EnumDyeColor.WHITE; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 4bc9ad343ad..2abfd9fc52a 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -4,12 +4,17 @@ import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.items.metaitem.stats.IMouseEventHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; @@ -18,14 +23,15 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; -import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; +import appeng.tile.networking.TileCableBus; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; @@ -40,23 +46,6 @@ public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, IItemNameProvider, IMouseEventHandler { - @Override - public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { - ItemStack heldItem = player.getHeldItem(hand); - - if (!world.isRemote) { - if (isLocked(heldItem)) { - // TODO: lang - player.sendStatusMessage( - new TextComponentString("Cannot open selector UI because the spray can is locked"), true); - } else { - MetaItemGuiFactory.open(player, hand); - } - } - - return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); - } - @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { ItemStack usedStack = guiData.getUsedItemStack(); @@ -142,22 +131,53 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam @Override public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack) { - if ((event.getButton() != -1 && event.isButtonstate()) || event.getDwheel() != 0) { + if (event.getButton() != -1 && event.isButtonstate()) { int button = event.getButton(); - int scroll = event.getDwheel(); - - if (button == 0) { - setColor(stack, getColorOrdinal(stack) + 1); + boolean sneaking = playerClient.isSneaking(); + + if (button == 0) { // Left click + int color; + if (sneaking) { + color = getColorOrdinal(stack) - 1; + if (color == -2) color = 15; + } else { + color = getColorOrdinal(stack) + 1; + } + + setColor(stack, color); event.setCanceled(true); - // TODO: sneak click rotates colors the other way - } else if (button == 2) { - toggleLocked(stack); + + final int finalColor = color; // grr java + sendToServer(buf -> buf + .writeByte(0) + .writeByte(finalColor)); + } else if (button == 2) { // Middle click + if (sneaking) { + toggleLocked(stack); + } else if (!isLocked(stack)) { + double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); + + if (!playerClient.capabilities.isCreativeMode) { + reach -= 0.5d; + } + + RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); + if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { + EnumDyeColor hitColor = getBlockColor(playerClient.world, rayTrace.getBlockPos()); + if (hitColor != null) { + setColor(stack, hitColor); + sendToServer(buf -> buf + .writeByte(0) + .writeByte(hitColor.ordinal())); + } else { + // If the player isn't sneaking and also not looking at a colored block, open gui + sendToServer(buf -> buf.writeByte(1)); + } + } + } + event.setCanceled(true); } - - sendToServer(buf -> buf - .writeVarInt(button) - .writeVarInt(scroll)); } } @@ -165,19 +185,45 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, @NotNull ItemStack stack) { PacketBuffer buf = packet.getBuffer(); - int button = buf.readVarInt(); - int scroll = buf.readVarInt(); - - if (button == 0 && !isLocked(stack)) { - // TODO: sneak click rotates colors the other way - setColor(stack, getColorOrdinal(stack) + 1); - } else if (button == 2) { - toggleLocked(stack); - EnumDyeColor color = getColor(stack); - // TODO: lang - playerServer.sendStatusMessage(new TextComponentString( - isLocked(stack) ? String.format("Locked to %s", color == null ? "solvent" : color) : "Unlocked"), - true); + switch (buf.readByte()) { + case 0 -> setColor(stack, buf.readByte()); + case 1 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); + } + } + + public static @Nullable EnumDyeColor getBlockColor(@NotNull World world, @NotNull BlockPos pos) { + if (world.isAirBlock(pos)) return null; + + IBlockState state = world.getBlockState(pos); + for (IProperty prop : state.getPropertyKeys()) { + if (prop.getValueClass() == EnumDyeColor.class) { + // noinspection unchecked + return state.getValue((IProperty) prop); + } } + + TileEntity te = world.getTileEntity(pos); + if (te != null) { + if (te instanceof IGregTechTileEntity gtte) { + MetaTileEntity mte = gtte.getMetaTileEntity(); + // Unfortunately MTEs store their color as an ARGB int instead of just an EnumDyeColor. Thus, this has + // to be done because changing MTEs to store/be limited to EnumDyeColor is API breaking and would limit + // the colors an MTE could be to 16. + int mteColor = mte.getPaintingColor(); + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (mteColor == dyeColor.colorValue) { + return dyeColor; + } + } + } + + if (Mods.AppliedEnergistics2.isModLoaded()) { + if (te instanceof TileCableBus cable) { + return cable.getColor().dye; + } + } + } + + return null; } } From 8c19545e32e2b249768f9c03317b24670ee45184 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 2 Aug 2025 18:51:38 -0400 Subject: [PATCH 031/109] shrink color button icon a smidge. Fix gui not opening when looking at an uncolored block --- .../spray/CreativeSprayBehavior.java | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 2abfd9fc52a..745132cf05f 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -36,10 +36,11 @@ import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,25 +56,25 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager return GTGuis.createPanel(usedStack, 176, 120) .child(SlotGroupWidget.builder() - .matrix("SCCCCCCC", + .matrix("SCCCCCCCC", "CCCCCCCC") - .key('S', new ButtonWidget<>() + .key('S', new ToggleButton() .size(18) - .onMousePressed(mouse -> { - colorSync.setIntValue(-1); - return true; - }) - .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm())) + .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == -1, + $ -> colorSync.setIntValue(-1))) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) + .asIcon() + .margin(2)) .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) .key('C', index -> { EnumDyeColor color = EnumDyeColor.values()[index]; - return new ButtonWidget<>() + return new ToggleButton() .size(18) - .onMousePressed(mouse -> { - colorSync.setIntValue(index); - return true; - }) - .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm())) + .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == index, + $ -> colorSync.setIntValue(index))) + .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) + .asIcon() + .margin(2)) .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); }) .build()); @@ -136,6 +137,8 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla boolean sneaking = playerClient.isSneaking(); if (button == 0) { // Left click + if (isLocked(stack)) return; + int color; if (sneaking) { color = getColorOrdinal(stack) - 1; @@ -169,11 +172,12 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla sendToServer(buf -> buf .writeByte(0) .writeByte(hitColor.ordinal())); - } else { - // If the player isn't sneaking and also not looking at a colored block, open gui - sendToServer(buf -> buf.writeByte(1)); + return; } } + + // If the player isn't sneaking and wasn't looking at a colored block, open gui + sendToServer(buf -> buf.writeByte(1)); } event.setCanceled(true); From c30c3dd8fd3805b20efcb70c1e0a1b000bd89160 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 15:26:43 -0400 Subject: [PATCH 032/109] Fix spray cans being able to spray with no durability left --- src/main/java/gregtech/api/util/GTUtility.java | 2 +- .../behaviors/spray/AbstractSprayBehavior.java | 14 +++++++++----- .../behaviors/spray/CreativeSprayBehavior.java | 10 +++++++--- .../behaviors/spray/DurabilitySprayBehavior.java | 9 +++++++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 434b4153905..cc37ddd641c 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -460,7 +460,7 @@ public int size() { }; } - public static NBTTagCompound getOrCreateNbtCompound(ItemStack stack) { + public static @NotNull NBTTagCompound getOrCreateNbtCompound(@NotNull ItemStack stack) { NBTTagCompound compound = stack.getTagCompound(); if (compound == null) { compound = new NBTTagCompound(); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 4cf5c033925..ada397d21c6 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -35,6 +35,8 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { + public abstract boolean canSpray(@NotNull ItemStack stack); + /** * Get the color of the spray can. {@code null} = solvent */ @@ -94,15 +96,17 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull ItemStack sprayCan) { - if (!player.canPlayerEdit(pos, facing, sprayCan)) { + if (!canSpray(sprayCan)) { + return EnumActionResult.PASS; + } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; } else if (!tryPaintBlock(player, world, pos, facing, getColor(sprayCan))) { return EnumActionResult.PASS; - } else { - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); - return EnumActionResult.SUCCESS; } + + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, + SoundCategory.PLAYERS, 1.0f, 1.0f); + return EnumActionResult.SUCCESS; } @SuppressWarnings("BooleanMethodIsAlwaysInverted") diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 745132cf05f..06169f57ab6 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -80,6 +80,11 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .build()); } + @Override + public boolean canSpray(@NotNull ItemStack stack) { + return true; + } + @Override public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(stack); @@ -158,8 +163,9 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla if (sneaking) { toggleLocked(stack); } else if (!isLocked(stack)) { - double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); + event.setCanceled(true); + double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); if (!playerClient.capabilities.isCreativeMode) { reach -= 0.5d; } @@ -179,8 +185,6 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla // If the player isn't sneaking and wasn't looking at a colored block, open gui sendToServer(buf -> buf.writeByte(1)); } - - event.setCanceled(true); } } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index ddf6bcc1426..a75630cf121 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -42,6 +42,11 @@ public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int maxUses, this.durabilityBarColors = GradientUtil.getGradient(color == null ? 0x969696 : color.colorValue, 10); } + @Override + public boolean canSpray(@NotNull ItemStack stack) { + return getUsesLeft(stack) > 0; + } + @Override public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { return this.color; @@ -78,8 +83,8 @@ public void useItemDurability(@NotNull EntityPlayer player, @NotNull EnumHand ha } protected int getUsesLeft(@NotNull ItemStack stack) { - NBTTagCompound tagCompound = stack.getTagCompound(); - if (tagCompound == null || !tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { + NBTTagCompound tagCompound = GTUtility.getOrCreateNbtCompound(stack); + if (!tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { return maxUses; } return tagCompound.getInteger(NBT_KEY); From accbb274b5f44fd4819255be65bb9a74da8b3860 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 18:53:20 -0400 Subject: [PATCH 033/109] Refactor how coloring is done based on GT5u's method --- .../api/util/color/ColoredBlockContainer.java | 63 ++++++++ .../util/color/containers/NullContainer.java | 32 ++++ .../containers/VanillaBlockContainer.java | 140 ++++++++++++++++ .../api/util/function/BooleanFunction.java | 14 ++ .../spray/AbstractSprayBehavior.java | 150 ++---------------- .../spray/CreativeSprayBehavior.java | 10 -- .../spray/DurabilitySprayBehavior.java | 9 +- src/main/java/gregtech/core/CoreModule.java | 4 + 8 files changed, 272 insertions(+), 150 deletions(-) create mode 100644 src/main/java/gregtech/api/util/color/ColoredBlockContainer.java create mode 100644 src/main/java/gregtech/api/util/color/containers/NullContainer.java create mode 100644 src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java create mode 100644 src/main/java/gregtech/api/util/function/BooleanFunction.java diff --git a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java new file mode 100644 index 00000000000..fb5556cb264 --- /dev/null +++ b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java @@ -0,0 +1,63 @@ +package gregtech.api.util.color; + +import gregtech.api.util.color.containers.NullContainer; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import it.unimi.dsi.fastutil.objects.ObjectArraySet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; +import java.util.Set; + +/** + * Used to provide a consistent interface for dealing with colored blocks, whether vanilla or modded.
+ * Inspired by GT5u's ColoredBlockContainer + */ +public abstract class ColoredBlockContainer { + + private static final Set MANAGERS = new ObjectArraySet<>(3); + + public static void registerContainerManager(@NotNull ContainerManager manager) { + Objects.requireNonNull(manager); + MANAGERS.add(manager); + } + + public abstract boolean setColor(@Nullable EnumDyeColor newColor); + + public abstract boolean removeColor(); + + public abstract @Nullable EnumDyeColor getColor(); + + public boolean isValid() { + return true; + } + + public static @NotNull ColoredBlockContainer getInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + for (ContainerManager manager : MANAGERS) { + if (manager.blockMatches(world, pos, facing, player)) { + return manager.createInstance(world, pos, facing, player); + } + } + + return NullContainer.NULL_CONTAINER; + } + + public static abstract class ContainerManager { + + protected abstract @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player); + + protected abstract boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, @NotNull EntityPlayer player); + } +} diff --git a/src/main/java/gregtech/api/util/color/containers/NullContainer.java b/src/main/java/gregtech/api/util/color/containers/NullContainer.java new file mode 100644 index 00000000000..db25ecf2b95 --- /dev/null +++ b/src/main/java/gregtech/api/util/color/containers/NullContainer.java @@ -0,0 +1,32 @@ +package gregtech.api.util.color.containers; + +import gregtech.api.util.color.ColoredBlockContainer; + +import net.minecraft.item.EnumDyeColor; + +import org.jetbrains.annotations.Nullable; + +public class NullContainer extends ColoredBlockContainer { + + public static final NullContainer NULL_CONTAINER = new NullContainer(); + + @Override + public boolean setColor(@Nullable EnumDyeColor newColor) { + return false; + } + + @Override + public boolean removeColor() { + return false; + } + + @Override + public @Nullable EnumDyeColor getColor() { + return null; + } + + @Override + public boolean isValid() { + return false; + } +} diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java b/src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java new file mode 100644 index 00000000000..285b5c3da00 --- /dev/null +++ b/src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java @@ -0,0 +1,140 @@ +package gregtech.api.util.color.containers; + +import gregtech.api.util.color.ColoredBlockContainer; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockColored; +import net.minecraft.block.BlockStainedGlass; +import net.minecraft.block.BlockStainedGlassPane; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public class VanillaBlockContainer extends ColoredBlockContainer { + + private static final BiMap TRANSFORMATIONS = ImmutableBiMap.of( + Blocks.GLASS, Blocks.STAINED_GLASS, + Blocks.GLASS_PANE, Blocks.STAINED_GLASS_PANE, + Blocks.HARDENED_CLAY, Blocks.STAINED_HARDENED_CLAY); + + private static final Map> PROPERTY_MAP = ImmutableMap.of( + Blocks.GLASS, BlockStainedGlass.COLOR, + Blocks.GLASS_PANE, BlockStainedGlassPane.COLOR, + Blocks.HARDENED_CLAY, BlockColored.COLOR); + + @NotNull + private final World world; + @NotNull + private final BlockPos pos; + @NotNull + private final EnumFacing facing; + + private VanillaBlockContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing) { + this.world = world; + this.pos = pos; + this.facing = facing; + } + + @Override + public boolean setColor(@Nullable EnumDyeColor newColor) { + if (newColor == null) { + return removeColor(); + } + + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (TRANSFORMATIONS.containsKey(block)) { + IBlockState newBlockState = TRANSFORMATIONS.get(block) + .getDefaultState() + .withProperty(PROPERTY_MAP.get(block), newColor); + world.setBlockState(pos, newBlockState); + } + + return block.recolorBlock(world, pos, facing, newColor); + } + + @Override + public boolean removeColor() { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (TRANSFORMATIONS.containsValue(block)) { + IBlockState newBlockState = TRANSFORMATIONS.inverse() + .get(block) + .getDefaultState(); + world.setBlockState(pos, newBlockState); + } else { + for (IProperty prop : state.getPropertyKeys()) { + if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { + IBlockState defaultState = block.getDefaultState(); + EnumDyeColor defaultColor = EnumDyeColor.WHITE; + try { + // try to read the default color value from the default state instead of just + // blindly setting it to default state, and potentially resetting other values + defaultColor = (EnumDyeColor) defaultState.getValue(prop); + } catch (IllegalArgumentException ignored) { + // no default color, we may have to fallback to WHITE here + // other mods that have custom behavior can be done as + // special cases above on a case-by-case basis + } + block.recolorBlock(world, pos, facing, defaultColor); + return true; + } + } + } + + return false; + } + + @Override + public @Nullable EnumDyeColor getColor() { + IBlockState state = world.getBlockState(pos); + for (IProperty prop : state.getPropertyKeys()) { + if (prop.getValueClass() == EnumDyeColor.class) { + // noinspection unchecked <- grr, shakes fist + return state.getValue((IProperty) prop); + } + } + + return null; + } + + @Override + public boolean isValid() { + return !world.isAirBlock(pos); + } + + public static class VanillaBlockManager extends ColoredBlockContainer.ContainerManager { + + @Override + protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + IBlockState blockState = world.getBlockState(pos); + Block block = blockState.getBlock(); + + return TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block) || + block instanceof BlockColored; + } + + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new VanillaBlockContainer(world, pos, facing); + } + } +} diff --git a/src/main/java/gregtech/api/util/function/BooleanFunction.java b/src/main/java/gregtech/api/util/function/BooleanFunction.java new file mode 100644 index 00000000000..f92ff8f0573 --- /dev/null +++ b/src/main/java/gregtech/api/util/function/BooleanFunction.java @@ -0,0 +1,14 @@ +package gregtech.api.util.function; + +import java.util.function.Function; + +@FunctionalInterface +public interface BooleanFunction extends Function { + + @Override + default Boolean apply(T t) { + return applyAsBoolean(t); + } + + boolean applyAsBoolean(T t); +} diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index ada397d21c6..4130a7f143d 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -2,23 +2,12 @@ import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.util.Mods; +import gregtech.api.util.color.ColoredBlockContainer; import gregtech.core.sound.GTSoundEvents; -import net.minecraft.block.Block; -import net.minecraft.block.BlockColored; -import net.minecraft.block.BlockStainedGlass; -import net.minecraft.block.BlockStainedGlassPane; -import net.minecraft.block.properties.IProperty; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -27,28 +16,24 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import appeng.api.implementations.tiles.IColorableTile; -import appeng.api.util.AEColor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; public abstract class AbstractSprayBehavior implements IItemBehaviour { - public abstract boolean canSpray(@NotNull ItemStack stack); - - /** - * Get the color of the spray can. {@code null} = solvent - */ - public @Nullable EnumDyeColor getColor() { - return getColor(ItemStack.EMPTY); - } - /** * Get the color of the spray can. {@code null} = solvent */ public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack stack); + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public abstract boolean canSpray(@NotNull ItemStack stack); + + public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { + // + } + public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack stack) { EnumDyeColor color = getColor(stack); return color == null ? -1 : color.ordinal(); @@ -100,7 +85,7 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block return EnumActionResult.PASS; } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; - } else if (!tryPaintBlock(player, world, pos, facing, getColor(sprayCan))) { + } else if (!tryPaintBlock(player, world, pos, facing, sprayCan)) { return EnumActionResult.PASS; } @@ -111,119 +96,8 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block @SuppressWarnings("BooleanMethodIsAlwaysInverted") protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing side, @Nullable EnumDyeColor color) { - 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, color) || - tryPaintSpecialBlock(player, world, pos, block, side, color); - } - - private boolean tryPaintSpecialBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull Block block, @NotNull EnumFacing side, @NotNull EnumDyeColor color) { - if (block == Blocks.GLASS) { - // noinspection DataFlowIssue - IBlockState newBlockState = Blocks.STAINED_GLASS.getDefaultState() - .withProperty(BlockStainedGlass.COLOR, color); - world.setBlockState(pos, newBlockState); - return true; - } else if (block == Blocks.GLASS_PANE) { - // noinspection DataFlowIssue - IBlockState newBlockState = Blocks.STAINED_GLASS_PANE.getDefaultState() - .withProperty(BlockStainedGlassPane.COLOR, color); - world.setBlockState(pos, newBlockState); - return true; - } else if (block == Blocks.HARDENED_CLAY) { - // noinspection DataFlowIssue - IBlockState newBlockState = Blocks.STAINED_HARDENED_CLAY.getDefaultState() - .withProperty(BlockColored.COLOR, color); - world.setBlockState(pos, newBlockState); - return true; - } else if (Mods.AppliedEnergistics2.isModLoaded()) { - TileEntity te = world.getTileEntity(pos); - if (te instanceof IColorableTile colorableTE) { - // Do not try to recolor if it already is this color - if (colorableTE.getColor().ordinal() != color.ordinal()) { - colorableTE.recolourBlock(side, AEColor.values()[color.ordinal()], player); - return true; - } - } - } - - return false; - } - - protected static boolean tryStripBlockColor(@NotNull EntityPlayer player, @NotNull World world, - @NotNull BlockPos pos, @NotNull Block block, @NotNull EnumFacing side) { - // MC special cases - if (block == Blocks.STAINED_GLASS) { - world.setBlockState(pos, Blocks.GLASS.getDefaultState()); - return true; - } else if (block == Blocks.STAINED_GLASS_PANE) { - world.setBlockState(pos, Blocks.GLASS_PANE.getDefaultState()); - return true; - } else if (block == Blocks.STAINED_HARDENED_CLAY) { - world.setBlockState(pos, Blocks.HARDENED_CLAY.getDefaultState()); - return true; - } - - // MTE special case - TileEntity te = world.getTileEntity(pos); - if (te instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - if (mte != null) { - if (mte.isPainted()) { - mte.setPaintingColor(-1); - return true; - } else return false; - } - } - - // TileEntityPipeBase special case - if (te instanceof IPipeTilepipe) { - if (pipe.isPainted()) { - pipe.setPaintingColor(-1); - return true; - } else { - return false; - } - } - - // AE2 cable special case - if (Mods.AppliedEnergistics2.isModLoaded()) { - if (te instanceof IColorableTile colorableTE) { - // Do not try to strip color if it is already colorless - if (colorableTE.getColor() != AEColor.TRANSPARENT) { - colorableTE.recolourBlock(side, AEColor.TRANSPARENT, player); - return true; - } else return false; - } - } - - // General case - IBlockState state = world.getBlockState(pos); - for (IProperty prop : state.getPropertyKeys()) { - if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { - IBlockState defaultState = block.getDefaultState(); - EnumDyeColor defaultColor = EnumDyeColor.WHITE; - try { - // try to read the default color value from the default state instead of just - // blindly setting it to default state, and potentially resetting other values - defaultColor = (EnumDyeColor) defaultState.getValue(prop); - } catch (IllegalArgumentException ignored) { - // no default color, we may have to fallback to WHITE here - // other mods that have custom behavior can be done as - // special cases above on a case-by-case basis - } - block.recolorBlock(world, pos, side, defaultColor); - return true; - } - } - - return false; + @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { + ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, side, player); + return blockContainer.setColor(getColor(sprayCan)); } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 06169f57ab6..1838ec5ddae 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -13,8 +13,6 @@ import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; -import net.minecraft.block.properties.IProperty; -import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; @@ -202,14 +200,6 @@ public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNul public static @Nullable EnumDyeColor getBlockColor(@NotNull World world, @NotNull BlockPos pos) { if (world.isAirBlock(pos)) return null; - IBlockState state = world.getBlockState(pos); - for (IProperty prop : state.getPropertyKeys()) { - if (prop.getValueClass() == EnumDyeColor.class) { - // noinspection unchecked - return state.getValue((IProperty) prop); - } - } - TileEntity te = world.getTileEntity(pos); if (te != null) { if (te instanceof IGregTechTileEntity gtte) { diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index a75630cf121..64ba701c28f 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -47,6 +47,11 @@ public boolean canSpray(@NotNull ItemStack stack) { return getUsesLeft(stack) > 0; } + @Override + public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { + useItemDurability(player, hand, sprayCan, replacementStack.copy()); + } + @Override public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { return this.color; @@ -58,7 +63,7 @@ public boolean canSpray(@NotNull ItemStack stack) { @NotNull ItemStack sprayCan) { EnumActionResult result = super.spray(player, hand, world, pos, facing, sprayCan); if (result == EnumActionResult.SUCCESS) { - useItemDurability(player, hand, player.getHeldItem(hand), replacementStack.copy()); + onSpray(player, hand, sprayCan); } return result; } @@ -97,7 +102,7 @@ protected static void setUsesLeft(@NotNull ItemStack itemStack, int usesLeft) { @Override public void addInformation(ItemStack itemStack, List lines) { int remainingUses = getUsesLeft(itemStack); - EnumDyeColor color = getColor(); + EnumDyeColor color = getColor(itemStack); if (color != null) { lines.add(I18n.format("behaviour.paintspray." + color.getTranslationKey() + ".tooltip")); diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index c386877749c..20d9addc98e 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -29,6 +29,8 @@ import gregtech.api.unification.material.registry.MarkerMaterialRegistry; import gregtech.api.util.CapesRegistry; import gregtech.api.util.Mods; +import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.util.color.containers.VanillaBlockContainer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler; @@ -305,6 +307,8 @@ public void postInit(@NotNull FMLPostInitializationEvent event) { } ModHandler.postInit(); + + ColoredBlockContainer.registerContainerManager(new VanillaBlockContainer.VanillaBlockManager()); } @Override From a6678e925e96552fc9fe31afc8e9a142079a50ac Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 18:55:27 -0400 Subject: [PATCH 034/109] Use the new coloring method to get the color when middle-clicking with the creative spray can --- .../spray/CreativeSprayBehavior.java | 41 +++---------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 1838ec5ddae..638c730c2b7 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -4,12 +4,10 @@ import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.items.metaitem.stats.IMouseEventHandler; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; -import gregtech.api.util.Mods; +import gregtech.api.util.color.ColoredBlockContainer; import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; @@ -21,15 +19,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; -import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; -import appeng.tile.networking.TileCableBus; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; @@ -139,6 +133,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla int button = event.getButton(); boolean sneaking = playerClient.isSneaking(); + // TODO make changing it in the hand shift scrolling. if (button == 0) { // Left click if (isLocked(stack)) return; @@ -170,7 +165,9 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { - EnumDyeColor hitColor = getBlockColor(playerClient.world, rayTrace.getBlockPos()); + ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, + rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); + EnumDyeColor hitColor = colorContainer.getColor(); if (hitColor != null) { setColor(stack, hitColor); sendToServer(buf -> buf @@ -196,32 +193,4 @@ public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNul case 1 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); } } - - public static @Nullable EnumDyeColor getBlockColor(@NotNull World world, @NotNull BlockPos pos) { - if (world.isAirBlock(pos)) return null; - - TileEntity te = world.getTileEntity(pos); - if (te != null) { - if (te instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - // Unfortunately MTEs store their color as an ARGB int instead of just an EnumDyeColor. Thus, this has - // to be done because changing MTEs to store/be limited to EnumDyeColor is API breaking and would limit - // the colors an MTE could be to 16. - int mteColor = mte.getPaintingColor(); - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { - if (mteColor == dyeColor.colorValue) { - return dyeColor; - } - } - } - - if (Mods.AppliedEnergistics2.isModLoaded()) { - if (te instanceof TileCableBus cable) { - return cable.getColor().dye; - } - } - } - - return null; - } } From ce7574ec0fca4fe81d8ff48889c385c0776b58a0 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:07:07 -0400 Subject: [PATCH 035/109] Implement AE2 color container --- .../api/util/color/ColoredBlockContainer.java | 4 +- .../color/containers/AE2ColorContainer.java | 91 +++++++++++++++++++ ...Container.java => NullColorContainer.java} | 4 +- ...tainer.java => VanillaColorContainer.java} | 6 +- src/main/java/gregtech/core/CoreModule.java | 8 +- 5 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java rename src/main/java/gregtech/api/util/color/containers/{NullContainer.java => NullColorContainer.java} (78%) rename src/main/java/gregtech/api/util/color/containers/{VanillaBlockContainer.java => VanillaColorContainer.java} (96%) diff --git a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java index fb5556cb264..17ec1333afd 100644 --- a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java @@ -1,6 +1,6 @@ package gregtech.api.util.color; -import gregtech.api.util.color.containers.NullContainer; +import gregtech.api.util.color.containers.NullColorContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -48,7 +48,7 @@ public boolean isValid() { } } - return NullContainer.NULL_CONTAINER; + return NullColorContainer.NULL_CONTAINER; } public static abstract class ContainerManager { diff --git a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java new file mode 100644 index 00000000000..736139d6adc --- /dev/null +++ b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java @@ -0,0 +1,91 @@ +package gregtech.api.util.color.containers; + +import gregtech.api.util.Mods; +import gregtech.api.util.color.ColoredBlockContainer; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import appeng.api.implementations.tiles.IColorableTile; +import appeng.api.util.AEColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class AE2ColorContainer extends ColoredBlockContainer { + + @NotNull + private final World world; + @NotNull + private final BlockPos pos; + @NotNull + private final EnumFacing facing; + @NotNull + private final EntityPlayer player; + + private AE2ColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + this.world = world; + this.pos = pos; + this.facing = facing; + this.player = player; + } + + @Override + public boolean setColor(@Nullable EnumDyeColor newColor) { + if (newColor == null) { + return removeColor(); + } + + TileEntity te = world.getTileEntity(pos); + if (te instanceof IColorableTile colorableTile) { + if (colorableTile.getColor().dye != newColor) { + colorableTile.recolourBlock(facing, AEColor.values()[newColor.ordinal()], player); + return true; + } + } + + return false; + } + + @Override + public boolean removeColor() { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IColorableTile colorableTile) { + colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player); + } + + return false; + } + + @Override + public @Nullable EnumDyeColor getColor() { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IColorableTile colorableTile) { + return colorableTile.getColor().dye; + } + + return null; + } + + public static class AE2BlockManager extends ColoredBlockContainer.ContainerManager { + + @Override + protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + if (!Mods.AppliedEnergistics2.isModLoaded()) return false; + TileEntity te = world.getTileEntity(pos); + return te instanceof IColorableTile; + } + + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new AE2ColorContainer(world, pos, facing, player); + } + } +} diff --git a/src/main/java/gregtech/api/util/color/containers/NullContainer.java b/src/main/java/gregtech/api/util/color/containers/NullColorContainer.java similarity index 78% rename from src/main/java/gregtech/api/util/color/containers/NullContainer.java rename to src/main/java/gregtech/api/util/color/containers/NullColorContainer.java index db25ecf2b95..b2f640c8d59 100644 --- a/src/main/java/gregtech/api/util/color/containers/NullContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/NullColorContainer.java @@ -6,9 +6,9 @@ import org.jetbrains.annotations.Nullable; -public class NullContainer extends ColoredBlockContainer { +public class NullColorContainer extends ColoredBlockContainer { - public static final NullContainer NULL_CONTAINER = new NullContainer(); + public static final NullColorContainer NULL_CONTAINER = new NullColorContainer(); @Override public boolean setColor(@Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java similarity index 96% rename from src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java rename to src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java index 285b5c3da00..b20eed90541 100644 --- a/src/main/java/gregtech/api/util/color/containers/VanillaBlockContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java @@ -23,7 +23,7 @@ import java.util.Map; -public class VanillaBlockContainer extends ColoredBlockContainer { +public class VanillaColorContainer extends ColoredBlockContainer { private static final BiMap TRANSFORMATIONS = ImmutableBiMap.of( Blocks.GLASS, Blocks.STAINED_GLASS, @@ -42,7 +42,7 @@ public class VanillaBlockContainer extends ColoredBlockContainer { @NotNull private final EnumFacing facing; - private VanillaBlockContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing) { + private VanillaColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing) { this.world = world; this.pos = pos; this.facing = facing; @@ -134,7 +134,7 @@ protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @Not protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return new VanillaBlockContainer(world, pos, facing); + return new VanillaColorContainer(world, pos, facing); } } } diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 20d9addc98e..dec577fa41b 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -30,7 +30,8 @@ import gregtech.api.util.CapesRegistry; import gregtech.api.util.Mods; import gregtech.api.util.color.ColoredBlockContainer; -import gregtech.api.util.color.containers.VanillaBlockContainer; +import gregtech.api.util.color.containers.AE2ColorContainer; +import gregtech.api.util.color.containers.VanillaColorContainer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler; @@ -308,7 +309,10 @@ public void postInit(@NotNull FMLPostInitializationEvent event) { ModHandler.postInit(); - ColoredBlockContainer.registerContainerManager(new VanillaBlockContainer.VanillaBlockManager()); + ColoredBlockContainer.registerContainerManager(new VanillaColorContainer.VanillaBlockManager()); + if (Mods.AppliedEnergistics2.isModLoaded()) { + ColoredBlockContainer.registerContainerManager(new AE2ColorContainer.AE2BlockManager()); + } } @Override From 6a4c5b5f7cad55c5c156657b539f0824b5386b22 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:13:14 -0400 Subject: [PATCH 036/109] Match the order of methods, because uh yea --- .../util/color/containers/AE2ColorContainer.java | 14 +++++++------- .../color/containers/VanillaColorContainer.java | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java index 736139d6adc..b3c9d1e97f1 100644 --- a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java @@ -73,6 +73,13 @@ public boolean removeColor() { public static class AE2BlockManager extends ColoredBlockContainer.ContainerManager { + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new AE2ColorContainer(world, pos, facing, player); + } + @Override protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { @@ -80,12 +87,5 @@ protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @Not TileEntity te = world.getTileEntity(pos); return te instanceof IColorableTile; } - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new AE2ColorContainer(world, pos, facing, player); - } } } diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java index b20eed90541..3a2c992229d 100644 --- a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java @@ -120,6 +120,13 @@ public boolean isValid() { public static class VanillaBlockManager extends ColoredBlockContainer.ContainerManager { + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new VanillaColorContainer(world, pos, facing); + } + @Override protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { @@ -129,12 +136,5 @@ protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @Not return TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block) || block instanceof BlockColored; } - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new VanillaColorContainer(world, pos, facing); - } } } From 58db4c787a0a7ad32fbab39b326022b8be4a6eff Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:46:48 -0400 Subject: [PATCH 037/109] Add missing some missing `true` early returns --- .../gregtech/api/util/color/containers/AE2ColorContainer.java | 1 + .../api/util/color/containers/VanillaColorContainer.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java index b3c9d1e97f1..de95925ac42 100644 --- a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java @@ -56,6 +56,7 @@ public boolean removeColor() { TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile) { colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player); + return true; } return false; diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java index 3a2c992229d..7ab8ef41be4 100644 --- a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java @@ -62,6 +62,7 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { .getDefaultState() .withProperty(PROPERTY_MAP.get(block), newColor); world.setBlockState(pos, newBlockState); + return true; } return block.recolorBlock(world, pos, facing, newColor); @@ -77,6 +78,7 @@ public boolean removeColor() { .get(block) .getDefaultState(); world.setBlockState(pos, newBlockState); + return true; } else { for (IProperty prop : state.getPropertyKeys()) { if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { From 8d852ddc7a05f5747b256d004551170194589a6d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:06:46 -0400 Subject: [PATCH 038/109] Implement GT color container --- .../api/metatileentity/MetaTileEntity.java | 12 ++ .../java/gregtech/api/util/GTUtility.java | 11 +- .../api/util/color/ColoredBlockContainer.java | 5 + .../color/containers/GTColorContainer.java | 136 ++++++++++++++++++ src/main/java/gregtech/core/CoreModule.java | 2 + 5 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 src/main/java/gregtech/api/util/color/containers/GTColorContainer.java diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 97fe11fb64e..b01a0814eb0 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -46,11 +46,13 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.Items; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -1281,6 +1283,10 @@ public void setPaintingColor(int paintingColor) { setPaintingColor(paintingColor, null); } + public void setPaintingColor(@Nullable EnumDyeColor color, @Nullable EnumFacing side) { + setPaintingColor(color == null ? -1 : color.colorValue, side); + } + public void setPaintingColor(int paintingColor, @Nullable EnumFacing side) { this.paintingColor = paintingColor; if (getWorld() != null && !getWorld().isRemote) { @@ -1523,6 +1529,12 @@ public UUID getOwner() { return owner; } + public boolean canBeModifiedBy(@NotNull Entity entity) { + UUID owner = getOwner(); + if (owner == null) return true; + return owner.equals(entity.getUniqueID()); + } + public final void toggleMuffled() { muffled = !muffled; if (!getWorld().isRemote) { diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index cc37ddd641c..d0c20c3e28e 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -756,10 +756,17 @@ public static String lowerUnderscoreToUpperCamel(String string) { return result.toString(); } - public static MetaTileEntity getMetaTileEntity(IBlockAccess world, BlockPos pos) { + /** + * Get the {@link MetaTileEntity} at the position in the given world. + * + * @param world the world to check + * @param pos the position of the mte + * @return the mte if there is one at the position, otherwise null + */ + public static @Nullable MetaTileEntity getMetaTileEntity(@Nullable IBlockAccess world, @Nullable BlockPos pos) { if (world == null || pos == null) return null; TileEntity te = world.getTileEntity(pos); - return te instanceof IGregTechTileEntity ? ((IGregTechTileEntity) te).getMetaTileEntity() : null; + return te instanceof IGregTechTileEntity gtte ? gtte.getMetaTileEntity() : null; } public static MetaTileEntity getMetaTileEntity(ItemStack stack) { diff --git a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java index 17ec1333afd..65204740830 100644 --- a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java @@ -35,6 +35,11 @@ public static void registerContainerManager(@NotNull ContainerManager manager) { public abstract @Nullable EnumDyeColor getColor(); + public int getColorInt() { + EnumDyeColor dyeColor = getColor(); + return dyeColor == null ? -1 : dyeColor.colorValue; + } + public boolean isValid() { return true; } diff --git a/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java b/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java new file mode 100644 index 00000000000..0ba6832b57b --- /dev/null +++ b/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java @@ -0,0 +1,136 @@ +package gregtech.api.util.color.containers; + +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.pipenet.tile.IPipeTile; +import gregtech.api.util.color.ColoredBlockContainer; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +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; + +public class GTColorContainer extends ColoredBlockContainer { + + @NotNull + private final World world; + @NotNull + private final BlockPos pos; + @NotNull + private final EnumFacing facing; + @NotNull + private final EntityPlayer player; + + private GTColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + this.world = world; + this.pos = pos; + this.facing = facing; + this.player = player; + } + + @Override + public boolean setColor(@Nullable EnumDyeColor newColor) { + if (newColor == null) { + return removeColor(); + } + + TileEntity te = world.getTileEntity(pos); + if (te instanceof IPipeTilepipeTile) { + pipeTile.setPaintingColor(newColor.colorValue); + return true; + } else { + MetaTileEntity mte = getMetaTileEntity(te); + if (mte != null && mte.canBeModifiedBy(player)) { + mte.setPaintingColor(newColor, facing); + return true; + } + } + + return false; + } + + @Override + public boolean removeColor() { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IPipeTilepipeTile) { + pipeTile.setPaintingColor(-1); + return true; + } else { + MetaTileEntity mte = getMetaTileEntity(te); + if (mte != null && mte.canBeModifiedBy(player)) { + mte.setPaintingColor(-1, facing); + return true; + } + } + + return false; + } + + @Override + public @Nullable EnumDyeColor getColor() { + int mteColor = getColorInt(); + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (mteColor == dyeColor.colorValue) { + return dyeColor; + } + } + + return null; + } + + @Override + public int getColorInt() { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IPipeTilepipeTile) { + return pipeTile.getPaintingColor(); + } else { + MetaTileEntity mte = getMetaTileEntity(te); + if (mte != null) { + return mte.getPaintingColor(); + } + } + + return -1; + } + + public static class GTColorManager extends ColoredBlockContainer.ContainerManager { + + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new GTColorContainer(world, pos, facing, player); + } + + @Override + protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IPipeTile) { + return true; + } else if (te instanceof IGregTechTileEntity gtte) { + MetaTileEntity mte = gtte.getMetaTileEntity(); + if (mte == null || !mte.isValid()) return false; + return mte.canBeModifiedBy(player); + } + + return false; + } + } + + private static @Nullable MetaTileEntity getMetaTileEntity(@Nullable TileEntity te) { + if (te instanceof IGregTechTileEntity gtte) { + MetaTileEntity mte = gtte.getMetaTileEntity(); + if (mte == null || !mte.isValid()) return null; + return mte; + } + + return null; + } +} diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index dec577fa41b..2904318bba7 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -31,6 +31,7 @@ import gregtech.api.util.Mods; import gregtech.api.util.color.ColoredBlockContainer; import gregtech.api.util.color.containers.AE2ColorContainer; +import gregtech.api.util.color.containers.GTColorContainer; import gregtech.api.util.color.containers.VanillaColorContainer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; @@ -310,6 +311,7 @@ public void postInit(@NotNull FMLPostInitializationEvent event) { ModHandler.postInit(); ColoredBlockContainer.registerContainerManager(new VanillaColorContainer.VanillaBlockManager()); + ColoredBlockContainer.registerContainerManager(new GTColorContainer.GTColorManager()); if (Mods.AppliedEnergistics2.isModLoaded()) { ColoredBlockContainer.registerContainerManager(new AE2ColorContainer.AE2BlockManager()); } From 0f524844caa960e8aa6abe0c4697f924b4e3b840 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:15:20 -0400 Subject: [PATCH 039/109] Don't color stuff if it's already that color --- .../api/util/color/containers/AE2ColorContainer.java | 6 +++++- .../api/util/color/containers/GTColorContainer.java | 8 ++++++-- .../api/util/color/containers/VanillaColorContainer.java | 8 ++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java index de95925ac42..c36572b215f 100644 --- a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java @@ -40,6 +40,10 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return removeColor(); } + if (getColor() == newColor) { + return false; + } + TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile) { if (colorableTile.getColor().dye != newColor) { @@ -54,7 +58,7 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { @Override public boolean removeColor() { TileEntity te = world.getTileEntity(pos); - if (te instanceof IColorableTile colorableTile) { + if (te instanceof IColorableTile colorableTile && colorableTile.getColor() != AEColor.TRANSPARENT) { colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player); return true; } diff --git a/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java b/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java index 0ba6832b57b..f3206db77ac 100644 --- a/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java @@ -40,6 +40,10 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return removeColor(); } + if (getColorInt() == newColor.colorValue) { + return false; + } + TileEntity te = world.getTileEntity(pos); if (te instanceof IPipeTilepipeTile) { pipeTile.setPaintingColor(newColor.colorValue); @@ -58,12 +62,12 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { @Override public boolean removeColor() { TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile) { + if (te instanceof IPipeTilepipeTile && pipeTile.isPainted()) { pipeTile.setPaintingColor(-1); return true; } else { MetaTileEntity mte = getMetaTileEntity(te); - if (mte != null && mte.canBeModifiedBy(player)) { + if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { mte.setPaintingColor(-1, facing); return true; } diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java index 7ab8ef41be4..4f6421c684f 100644 --- a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java @@ -54,6 +54,10 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return removeColor(); } + if (getColor() == newColor) { + return false; + } + IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); @@ -93,8 +97,8 @@ public boolean removeColor() { // other mods that have custom behavior can be done as // special cases above on a case-by-case basis } - block.recolorBlock(world, pos, facing, defaultColor); - return true; + + return block.recolorBlock(world, pos, facing, defaultColor); } } } From e6891ee27243c190e05120d386117831537318c2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:21:17 -0400 Subject: [PATCH 040/109] Use ColoredBlockContainer#isValid in the spray method --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 4130a7f143d..f9165bd9bc5 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -98,6 +98,6 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, side, player); - return blockContainer.setColor(getColor(sprayCan)); + return blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan)); } } From a70654595cebf65a8e4bddf3fec911d26c04c200 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:33:05 -0400 Subject: [PATCH 041/109] Add DurabilitySprayBehavior constructor shortcut --- .../spray/DurabilitySprayBehavior.java | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 64ba701c28f..77713fbf302 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -42,6 +42,10 @@ public DurabilitySprayBehavior(@NotNull ItemStack replacementStack, int maxUses, this.durabilityBarColors = GradientUtil.getGradient(color == null ? 0x969696 : color.colorValue, 10); } + public DurabilitySprayBehavior(int maxUses, @Nullable EnumDyeColor color) { + this(ItemStack.EMPTY, maxUses, color); + } + @Override public boolean canSpray(@NotNull ItemStack stack) { return getUsesLeft(stack) > 0; @@ -49,44 +53,28 @@ public boolean canSpray(@NotNull ItemStack stack) { @Override public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { - useItemDurability(player, hand, sprayCan, replacementStack.copy()); - } - - @Override - public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { - return this.color; - } - - @Override - protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, - @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull ItemStack sprayCan) { - EnumActionResult result = super.spray(player, hand, world, pos, facing, sprayCan); - if (result == EnumActionResult.SUCCESS) { - onSpray(player, hand, sprayCan); - } - return result; - } - - public void useItemDurability(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack stack, - @NotNull ItemStack replacementStack) { - int usesLeft = getUsesLeft(stack); + int usesLeft = getUsesLeft(sprayCan); if (!player.capabilities.isCreativeMode) { if (--usesLeft <= 0) { if (replacementStack.isEmpty()) { // If replacement stack is empty, just shrink resulting stack - stack.shrink(1); + sprayCan.shrink(1); } else { // Otherwise, update held item to replacement stack - player.setHeldItem(hand, replacementStack); + player.setHeldItem(hand, replacementStack.copy()); } return; } - setUsesLeft(stack, usesLeft); + setUsesLeft(sprayCan, usesLeft); } } + @Override + public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { + return this.color; + } + protected int getUsesLeft(@NotNull ItemStack stack) { NBTTagCompound tagCompound = GTUtility.getOrCreateNbtCompound(stack); if (!tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { From 23155aeaea260b3f61902d29036e3ea336154224 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:42:54 -0400 Subject: [PATCH 042/109] Move the color stuff out of the util package --- .../api/{util => }/color/ColoredBlockContainer.java | 4 ++-- .../{util => }/color/containers/AE2ColorContainer.java | 4 ++-- .../api/{util => }/color/containers/GTColorContainer.java | 4 ++-- .../{util => }/color/containers/NullColorContainer.java | 4 ++-- .../color/containers/VanillaColorContainer.java | 4 ++-- .../items/behaviors/spray/AbstractSprayBehavior.java | 1 + .../items/behaviors/spray/CreativeSprayBehavior.java | 2 +- src/main/java/gregtech/core/CoreModule.java | 8 ++++---- 8 files changed, 16 insertions(+), 15 deletions(-) rename src/main/java/gregtech/api/{util => }/color/ColoredBlockContainer.java (96%) rename src/main/java/gregtech/api/{util => }/color/containers/AE2ColorContainer.java (96%) rename src/main/java/gregtech/api/{util => }/color/containers/GTColorContainer.java (97%) rename src/main/java/gregtech/api/{util => }/color/containers/NullColorContainer.java (85%) rename src/main/java/gregtech/api/{util => }/color/containers/VanillaColorContainer.java (98%) diff --git a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java similarity index 96% rename from src/main/java/gregtech/api/util/color/ColoredBlockContainer.java rename to src/main/java/gregtech/api/color/ColoredBlockContainer.java index 65204740830..9389c315b07 100644 --- a/src/main/java/gregtech/api/util/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -1,6 +1,6 @@ -package gregtech.api.util.color; +package gregtech.api.color; -import gregtech.api.util.color.containers.NullColorContainer; +import gregtech.api.color.containers.NullColorContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java similarity index 96% rename from src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java rename to src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index c36572b215f..c7fddaa6ec2 100644 --- a/src/main/java/gregtech/api/util/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -1,7 +1,7 @@ -package gregtech.api.util.color.containers; +package gregtech.api.color.containers; import gregtech.api.util.Mods; -import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java b/src/main/java/gregtech/api/color/containers/GTColorContainer.java similarity index 97% rename from src/main/java/gregtech/api/util/color/containers/GTColorContainer.java rename to src/main/java/gregtech/api/color/containers/GTColorContainer.java index f3206db77ac..c805cf97208 100644 --- a/src/main/java/gregtech/api/util/color/containers/GTColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTColorContainer.java @@ -1,9 +1,9 @@ -package gregtech.api.util.color.containers; +package gregtech.api.color.containers; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/api/util/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java similarity index 85% rename from src/main/java/gregtech/api/util/color/containers/NullColorContainer.java rename to src/main/java/gregtech/api/color/containers/NullColorContainer.java index b2f640c8d59..def240be4f8 100644 --- a/src/main/java/gregtech/api/util/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -1,6 +1,6 @@ -package gregtech.api.util.color.containers; +package gregtech.api.color.containers; -import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java similarity index 98% rename from src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java rename to src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 4f6421c684f..b848972adff 100644 --- a/src/main/java/gregtech/api/util/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -1,6 +1,6 @@ -package gregtech.api.util.color.containers; +package gregtech.api.color.containers; -import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import net.minecraft.block.Block; import net.minecraft.block.BlockColored; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index f9165bd9bc5..26ad4f3ba88 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -3,6 +3,7 @@ import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import gregtech.core.sound.GTSoundEvents; import net.minecraft.entity.player.EntityPlayer; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 638c730c2b7..ba2d4d248b3 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -7,7 +7,7 @@ import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; -import gregtech.api.util.color.ColoredBlockContainer; +import gregtech.api.color.ColoredBlockContainer; import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 2904318bba7..e7f6f772241 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -29,10 +29,10 @@ import gregtech.api.unification.material.registry.MarkerMaterialRegistry; import gregtech.api.util.CapesRegistry; import gregtech.api.util.Mods; -import gregtech.api.util.color.ColoredBlockContainer; -import gregtech.api.util.color.containers.AE2ColorContainer; -import gregtech.api.util.color.containers.GTColorContainer; -import gregtech.api.util.color.containers.VanillaColorContainer; +import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.color.containers.AE2ColorContainer; +import gregtech.api.color.containers.GTColorContainer; +import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler; From 7e564222d274920f836788aa4c80e2506d14538a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:43:48 -0400 Subject: [PATCH 043/109] Make durability cans take durability again --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 26ad4f3ba88..9820f39efea 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -87,6 +87,7 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; } else if (!tryPaintBlock(player, world, pos, facing, sprayCan)) { + onSpray(player, hand, sprayCan); return EnumActionResult.PASS; } From 78a2af0ff8152f7095899c180f0aafe0c198ffb2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:44:33 -0400 Subject: [PATCH 044/109] Not there!!! --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 9820f39efea..b5f8c3578e4 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -87,10 +87,10 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; } else if (!tryPaintBlock(player, world, pos, facing, sprayCan)) { - onSpray(player, hand, sprayCan); return EnumActionResult.PASS; } + onSpray(player, hand, sprayCan); world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); return EnumActionResult.SUCCESS; From 9a81375a5798b5d48c5f949eaa53f70c69e157d5 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:57:40 -0400 Subject: [PATCH 045/109] spoble --- .../gregtech/api/color/containers/AE2ColorContainer.java | 2 +- .../gregtech/api/color/containers/GTColorContainer.java | 2 +- .../items/behaviors/spray/CreativeSprayBehavior.java | 2 +- .../items/behaviors/spray/DurabilitySprayBehavior.java | 4 ---- src/main/java/gregtech/core/CoreModule.java | 8 ++++---- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index c7fddaa6ec2..407e9ec2203 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -1,7 +1,7 @@ package gregtech.api.color.containers; -import gregtech.api.util.Mods; import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.util.Mods; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/api/color/containers/GTColorContainer.java b/src/main/java/gregtech/api/color/containers/GTColorContainer.java index c805cf97208..f1825d671e4 100644 --- a/src/main/java/gregtech/api/color/containers/GTColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTColorContainer.java @@ -1,9 +1,9 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.color.ColoredBlockContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index ba2d4d248b3..bdad96fb72e 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -1,5 +1,6 @@ package gregtech.common.items.behaviors.spray; +import gregtech.api.color.ColoredBlockContainer; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; @@ -7,7 +8,6 @@ import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; -import gregtech.api.color.ColoredBlockContainer; import gregtech.common.items.MetaItems; import gregtech.core.network.packets.PacketItemMouseEvent; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 77713fbf302..ca4026148be 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -9,11 +9,7 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import org.apache.commons.lang3.tuple.Pair; diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index e7f6f772241..169769824e3 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -5,6 +5,10 @@ import gregtech.api.GregTechAPIInternal; import gregtech.api.block.IHeatingCoilBlockStats; import gregtech.api.capability.SimpleCapabilityManager; +import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.color.containers.AE2ColorContainer; +import gregtech.api.color.containers.GTColorContainer; +import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverUIFactory; import gregtech.api.fluids.GTFluidRegistration; @@ -29,10 +33,6 @@ import gregtech.api.unification.material.registry.MarkerMaterialRegistry; import gregtech.api.util.CapesRegistry; import gregtech.api.util.Mods; -import gregtech.api.color.ColoredBlockContainer; -import gregtech.api.color.containers.AE2ColorContainer; -import gregtech.api.color.containers.GTColorContainer; -import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler; From e33bf949476e885db42b724c5c188d21bc4f86c7 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:00:21 -0400 Subject: [PATCH 046/109] Absorb #2368 pt1 --- .../spray/AbstractSprayBehavior.java | 62 +++++++++++++++--- .../common/pipelike/PipeCollectorWalker.java | 65 +++++++++++++++++++ 2 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index b5f8c3578e4..807fcd21b70 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -1,14 +1,16 @@ package gregtech.common.items.behaviors.spray; +import gregtech.api.color.ColoredBlockContainer; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; -import gregtech.api.util.color.ColoredBlockContainer; -import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.pipenet.tile.IPipeTile; +import gregtech.common.pipelike.PipeCollectorWalker; import gregtech.core.sound.GTSoundEvents; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -86,20 +88,64 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block return EnumActionResult.PASS; } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { return EnumActionResult.FAIL; - } else if (!tryPaintBlock(player, world, pos, facing, sprayCan)) { + } + + int returnCode = tryPaintBlock(world, pos, player, hand, facing, sprayCan); + if (returnCode == 0) { return EnumActionResult.PASS; + } else if (returnCode == 1) { + onSpray(player, hand, sprayCan); } - onSpray(player, hand, sprayCan); world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); return EnumActionResult.SUCCESS; } - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - protected boolean tryPaintBlock(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { + /** + * Return codes:
+ * {@code -1}: didn't paint any block(s)
+ * {@code 0}: colored 1 block
+ * {@code 1+}: colored multiple blocks and {@link #onSpray(EntityPlayer, EnumHand, ItemStack)} was handled already + */ + protected int tryPaintBlock(@NotNull World world, @NotNull BlockPos pos, @NotNull EntityPlayer player, + @NotNull EnumHand hand, @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { + if (player.isSneaking()) { + TileEntity te = world.getTileEntity(pos); + if (te instanceof IPipeTilepipeTile) { + return traversePipes(world, player, hand, pos, pipeTile, sprayCan); + } + } + ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, side, player); - return blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan)); + if (blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan))) { + return 0; + } + + return -1; + } + + protected int traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull BlockPos startPos, @NotNull IPipeTile startingPipe, + @NotNull ItemStack sprayCan) { + EnumDyeColor dyeColor = getColor(sprayCan); + int color = dyeColor == null ? -1 : dyeColor.colorValue; + int[] paintedCountHolder = { 0 }; + PipeCollectorWalker.collectPipeNet(world, startPos, startingPipe, pipe -> { + if (!canSpray(sprayCan)) { + return false; + } + + if (pipe.getPaintingColor() != color) { + pipe.setPaintingColor(color); + pipe.scheduleRenderUpdate(); + onSpray(player, hand, sprayCan); + paintedCountHolder[0]++; + } + + return true; + }); + + return paintedCountHolder[0]; } } 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..963d811beef --- /dev/null +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -0,0 +1,65 @@ +package gregtech.common.pipelike; + +import gregtech.api.pipenet.PipeNetWalker; +import gregtech.api.pipenet.tile.IPipeTile; +import gregtech.api.util.function.BooleanFunction; + +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; + +public class PipeCollectorWalker> extends PipeNetWalker { + + public static void collectPipeNet(@NotNull World world, @NotNull BlockPos sourcePipe, @NotNull IPipeTile pipe, + @NotNull BooleanFunction> pipeFunction) { + PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( + world, sourcePipe, 0, pipe.getClass()); + walker.pipeFunction = pipeFunction; + walker.traversePipeNet(); + } + + // I love type erasure - htmlcsjs + private final Class basePipeClass; + /** + * Function to run on every pipe + * If false is returned then halt the walker + */ + private BooleanFunction> pipeFunction; + + 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.pipeFunction = pipeFunction; + walker.sourcePipe = sourcePipe; + return walker; + } + + @Override + protected void checkPipe(T pipeTile, BlockPos pos) { + if (this.pipeFunction != null && !this.pipeFunction.apply(pipeTile)) { + this.root.stop(); + } + } + + @Override + protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, + @Nullable TileEntity neighbourTile) {} + + @Override + protected Class getBasePipeClass() { + return basePipeClass; + } +} From 9664e91bba85c98c9c53690b2afdb979b9063b21 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:01:43 -0400 Subject: [PATCH 047/109] Change some values in case the pipe walker doesn't hit any pipes --- .../behaviors/spray/AbstractSprayBehavior.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 807fcd21b70..97883f24b37 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -91,9 +91,9 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } int returnCode = tryPaintBlock(world, pos, player, hand, facing, sprayCan); - if (returnCode == 0) { + if (returnCode == -2) { return EnumActionResult.PASS; - } else if (returnCode == 1) { + } else if (returnCode == -1) { onSpray(player, hand, sprayCan); } @@ -104,9 +104,9 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block /** * Return codes:
- * {@code -1}: didn't paint any block(s)
- * {@code 0}: colored 1 block
- * {@code 1+}: colored multiple blocks and {@link #onSpray(EntityPlayer, EnumHand, ItemStack)} was handled already + * {@code -2}: didn't paint any block(s)
+ * {@code -1}: colored 1 block
+ * {@code 0+}: colored multiple blocks and {@link #onSpray(EntityPlayer, EnumHand, ItemStack)} was handled already */ protected int tryPaintBlock(@NotNull World world, @NotNull BlockPos pos, @NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { @@ -119,10 +119,10 @@ protected int tryPaintBlock(@NotNull World world, @NotNull BlockPos pos, @NotNul ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, side, player); if (blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan))) { - return 0; + return -1; } - return -1; + return -2; } protected int traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull EnumHand hand, From d23c871206706c790332ef21f90de37a321bc22f Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:05:51 -0400 Subject: [PATCH 048/109] Ignore copying the color if the hit color is the same as the can already --- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index bdad96fb72e..a5d38900573 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -168,7 +168,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); EnumDyeColor hitColor = colorContainer.getColor(); - if (hitColor != null) { + if (hitColor != null && hitColor != getColor(stack)) { setColor(stack, hitColor); sendToServer(buf -> buf .writeByte(0) From f68089440f71e2a038cd596df1c0278788d1d55e Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 22:05:01 -0400 Subject: [PATCH 049/109] ugh stuffffff :((, it isn't breaking at 0?????????? --- .../containers/GTPipeColorContainer.java | 91 +++++++++++++++++++ ...rContainer.java => MTEColorContainer.java} | 51 +++-------- .../spray/AbstractSprayBehavior.java | 10 +- .../spray/CreativeSprayBehavior.java | 5 - .../spray/DurabilitySprayBehavior.java | 40 +++++--- .../common/pipelike/PipeCollectorWalker.java | 2 +- src/main/java/gregtech/core/CoreModule.java | 6 +- 7 files changed, 147 insertions(+), 58 deletions(-) create mode 100644 src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java rename src/main/java/gregtech/api/color/containers/{GTColorContainer.java => MTEColorContainer.java} (61%) diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java new file mode 100644 index 00000000000..8fa8f080c6b --- /dev/null +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -0,0 +1,91 @@ +package gregtech.api.color.containers; + +import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.pipenet.tile.IPipeTile; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +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; + +public class GTPipeColorContainer extends ColoredBlockContainer { + + @NotNull + private final World world; + @NotNull + private final BlockPos pos; + + private GTPipeColorContainer(@NotNull World world, @NotNull BlockPos pos) { + this.world = world; + this.pos = pos; + } + + @Override + public boolean setColor(@Nullable EnumDyeColor newColor) { + if (newColor == null) { + return removeColor(); + } + + if (getColorInt() == newColor.colorValue) { + return false; + } + + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { + pipeTile.setPaintingColor(newColor.colorValue); + return true; + } + + return false; + } + + @Override + public boolean removeColor() { + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { + pipeTile.setPaintingColor(-1); + return true; + } + + return false; + } + + @Override + public @Nullable EnumDyeColor getColor() { + int mteColor = getColorInt(); + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (mteColor == dyeColor.colorValue) { + return dyeColor; + } + } + + return null; + } + + @Override + public int getColorInt() { + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { + return pipeTile.getPaintingColor(); + } + + return -1; + } + + public static class GTPipeColorManager extends ContainerManager { + + @Override + protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return new GTPipeColorContainer(world, pos); + } + + @Override + protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return world.getTileEntity(pos) instanceof IPipeTile; + } + } +} diff --git a/src/main/java/gregtech/api/color/containers/GTColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java similarity index 61% rename from src/main/java/gregtech/api/color/containers/GTColorContainer.java rename to src/main/java/gregtech/api/color/containers/MTEColorContainer.java index f1825d671e4..ac86582f1c1 100644 --- a/src/main/java/gregtech/api/color/containers/GTColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -3,7 +3,6 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.pipenet.tile.IPipeTile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -15,7 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class GTColorContainer extends ColoredBlockContainer { +public class MTEColorContainer extends ColoredBlockContainer { @NotNull private final World world; @@ -26,8 +25,8 @@ public class GTColorContainer extends ColoredBlockContainer { @NotNull private final EntityPlayer player; - private GTColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + private MTEColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { this.world = world; this.pos = pos; this.facing = facing; @@ -44,16 +43,10 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return false; } - TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile) { - pipeTile.setPaintingColor(newColor.colorValue); + MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + if (mte != null && mte.canBeModifiedBy(player)) { + mte.setPaintingColor(newColor, facing); return true; - } else { - MetaTileEntity mte = getMetaTileEntity(te); - if (mte != null && mte.canBeModifiedBy(player)) { - mte.setPaintingColor(newColor, facing); - return true; - } } return false; @@ -61,16 +54,10 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { @Override public boolean removeColor() { - TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile && pipeTile.isPainted()) { - pipeTile.setPaintingColor(-1); + MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { + mte.setPaintingColor(-1, facing); return true; - } else { - MetaTileEntity mte = getMetaTileEntity(te); - if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { - mte.setPaintingColor(-1, facing); - return true; - } } return false; @@ -90,35 +77,27 @@ public boolean removeColor() { @Override public int getColorInt() { - TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile) { - return pipeTile.getPaintingColor(); - } else { - MetaTileEntity mte = getMetaTileEntity(te); - if (mte != null) { - return mte.getPaintingColor(); - } + MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + if (mte != null) { + return mte.getPaintingColor(); } return -1; } - public static class GTColorManager extends ColoredBlockContainer.ContainerManager { + public static class MTEColorManager extends ColoredBlockContainer.ContainerManager { @Override protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return new GTColorContainer(world, pos, facing, player); + return new MTEColorContainer(world, pos, facing, player); } @Override protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTile) { - return true; - } else if (te instanceof IGregTechTileEntity gtte) { + if (world.getTileEntity(pos) instanceof IGregTechTileEntity gtte) { MetaTileEntity mte = gtte.getMetaTileEntity(); if (mte == null || !mte.isValid()) return false; return mte.canBeModifiedBy(player); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 97883f24b37..1c0d32742dc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -30,8 +30,15 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { */ public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack stack); + public int getColorInt(@NotNull ItemStack stack) { + EnumDyeColor color = getColor(stack); + return color == null ? -1 : color.colorValue; + } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public abstract boolean canSpray(@NotNull ItemStack stack); + public boolean canSpray(@NotNull ItemStack stack) { + return true; + } public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { // @@ -113,6 +120,7 @@ protected int tryPaintBlock(@NotNull World world, @NotNull BlockPos pos, @NotNul if (player.isSneaking()) { TileEntity te = world.getTileEntity(pos); if (te instanceof IPipeTilepipeTile) { + if (pipeTile.getPaintingColor() == getColorInt(sprayCan)) return -2; return traversePipes(world, player, hand, pos, pipeTile, sprayCan); } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index a5d38900573..f6446d972a6 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -72,11 +72,6 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .build()); } - @Override - public boolean canSpray(@NotNull ItemStack stack) { - return true; - } - @Override public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(stack); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index ca4026148be..958eeef7cc5 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -1,6 +1,7 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; @@ -49,20 +50,17 @@ public boolean canSpray(@NotNull ItemStack stack) { @Override public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { - int usesLeft = getUsesLeft(sprayCan); - if (!player.capabilities.isCreativeMode) { - if (--usesLeft <= 0) { - if (replacementStack.isEmpty()) { - // If replacement stack is empty, just shrink resulting stack - sprayCan.shrink(1); - } else { - // Otherwise, update held item to replacement stack - player.setHeldItem(hand, replacementStack.copy()); - } - return; + if (player.capabilities.isCreativeMode) return; + + if (doDamage(sprayCan)) { + GTLog.logger.info("Spray can broke, replacing with replacement stack"); + if (replacementStack.isEmpty()) { + // If replacement stack is empty, just shrink resulting stack + sprayCan.shrink(1); + } else { + // Otherwise, update held item to replacement stack + player.setHeldItem(hand, replacementStack.copy()); } - - setUsesLeft(sprayCan, usesLeft); } } @@ -72,10 +70,14 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu } protected int getUsesLeft(@NotNull ItemStack stack) { + if (stack.isItemEqual(replacementStack)) return 0; + NBTTagCompound tagCompound = GTUtility.getOrCreateNbtCompound(stack); if (!tagCompound.hasKey(NBT_KEY, Constants.NBT.TAG_INT)) { + tagCompound.setInteger(NBT_KEY, maxUses); return maxUses; } + return tagCompound.getInteger(NBT_KEY); } @@ -83,6 +85,18 @@ protected static void setUsesLeft(@NotNull ItemStack itemStack, int usesLeft) { GTUtility.getOrCreateNbtCompound(itemStack).setInteger(NBT_KEY, usesLeft); } + /** + * Decrement 1 point of durability from a spray can + * + * @param stack the stack to damage + * @return if it ran out + */ + protected boolean doDamage(@NotNull ItemStack stack) { + int usesLeft = getUsesLeft(stack) - 1; + setUsesLeft(stack, usesLeft); + return usesLeft == 0; + } + @Override public void addInformation(ItemStack itemStack, List lines) { int remainingUses = getUsesLeft(itemStack); diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index 963d811beef..d1f9b314684 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -49,7 +49,7 @@ protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextP @Override protected void checkPipe(T pipeTile, BlockPos pos) { - if (this.pipeFunction != null && !this.pipeFunction.apply(pipeTile)) { + if (this.pipeFunction != null && !this.pipeFunction.applyAsBoolean(pipeTile)) { this.root.stop(); } } diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 169769824e3..9df2b636f25 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -7,7 +7,8 @@ import gregtech.api.capability.SimpleCapabilityManager; import gregtech.api.color.ColoredBlockContainer; import gregtech.api.color.containers.AE2ColorContainer; -import gregtech.api.color.containers.GTColorContainer; +import gregtech.api.color.containers.GTPipeColorContainer; +import gregtech.api.color.containers.MTEColorContainer; import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverUIFactory; @@ -311,7 +312,8 @@ public void postInit(@NotNull FMLPostInitializationEvent event) { ModHandler.postInit(); ColoredBlockContainer.registerContainerManager(new VanillaColorContainer.VanillaBlockManager()); - ColoredBlockContainer.registerContainerManager(new GTColorContainer.GTColorManager()); + ColoredBlockContainer.registerContainerManager(new MTEColorContainer.MTEColorManager()); + ColoredBlockContainer.registerContainerManager(new GTPipeColorContainer.GTPipeColorManager()); if (Mods.AppliedEnergistics2.isModLoaded()) { ColoredBlockContainer.registerContainerManager(new AE2ColorContainer.AE2BlockManager()); } From 7f0ce7c246d1777a7f5695a6cf77f70fbec48f3a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 4 Aug 2025 22:14:58 -0400 Subject: [PATCH 050/109] Fix not breaking on empty, breaking when recursive painting it still borked --- .../spray/DurabilitySprayBehavior.java | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 958eeef7cc5..690d5c88121 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -52,7 +52,8 @@ public boolean canSpray(@NotNull ItemStack stack) { public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { if (player.capabilities.isCreativeMode) return; - if (doDamage(sprayCan)) { + int usesLeft = getUsesLeft(sprayCan); + if (--usesLeft <= 0) { GTLog.logger.info("Spray can broke, replacing with replacement stack"); if (replacementStack.isEmpty()) { // If replacement stack is empty, just shrink resulting stack @@ -61,7 +62,11 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu // Otherwise, update held item to replacement stack player.setHeldItem(hand, replacementStack.copy()); } + + return; } + + setUsesLeft(sprayCan, usesLeft); } @Override @@ -85,18 +90,6 @@ protected static void setUsesLeft(@NotNull ItemStack itemStack, int usesLeft) { GTUtility.getOrCreateNbtCompound(itemStack).setInteger(NBT_KEY, usesLeft); } - /** - * Decrement 1 point of durability from a spray can - * - * @param stack the stack to damage - * @return if it ran out - */ - protected boolean doDamage(@NotNull ItemStack stack) { - int usesLeft = getUsesLeft(stack) - 1; - setUsesLeft(stack, usesLeft); - return usesLeft == 0; - } - @Override public void addInformation(ItemStack itemStack, List lines) { int remainingUses = getUsesLeft(itemStack); From ccb059fa3765ff9bb773684ba9c947ef554b2550 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:35:31 -0400 Subject: [PATCH 051/109] Use Predicate instead of "BooleanFunction" (what was I doing bruh) --- .../api/util/function/BooleanFunction.java | 14 -------------- .../common/pipelike/PipeCollectorWalker.java | 10 ++++++---- 2 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 src/main/java/gregtech/api/util/function/BooleanFunction.java diff --git a/src/main/java/gregtech/api/util/function/BooleanFunction.java b/src/main/java/gregtech/api/util/function/BooleanFunction.java deleted file mode 100644 index f92ff8f0573..00000000000 --- a/src/main/java/gregtech/api/util/function/BooleanFunction.java +++ /dev/null @@ -1,14 +0,0 @@ -package gregtech.api.util.function; - -import java.util.function.Function; - -@FunctionalInterface -public interface BooleanFunction extends Function { - - @Override - default Boolean apply(T t) { - return applyAsBoolean(t); - } - - boolean applyAsBoolean(T t); -} diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index d1f9b314684..d4c692c73fa 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -2,7 +2,6 @@ import gregtech.api.pipenet.PipeNetWalker; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.util.function.BooleanFunction; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; @@ -12,10 +11,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.function.Predicate; + public class PipeCollectorWalker> extends PipeNetWalker { public static void collectPipeNet(@NotNull World world, @NotNull BlockPos sourcePipe, @NotNull IPipeTile pipe, - @NotNull BooleanFunction> pipeFunction) { + @NotNull Predicate> pipeFunction) { PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( world, sourcePipe, 0, pipe.getClass()); walker.pipeFunction = pipeFunction; @@ -24,11 +25,12 @@ public static void collectPipeNet(@NotNull World world, @NotNull BlockPos source // I love type erasure - htmlcsjs private final Class basePipeClass; + /** * Function to run on every pipe * If false is returned then halt the walker */ - private BooleanFunction> pipeFunction; + private Predicate> pipeFunction; private BlockPos sourcePipe; @@ -49,7 +51,7 @@ protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextP @Override protected void checkPipe(T pipeTile, BlockPos pos) { - if (this.pipeFunction != null && !this.pipeFunction.applyAsBoolean(pipeTile)) { + if (this.pipeFunction != null && !this.pipeFunction.test(pipeTile)) { this.root.stop(); } } From b0b87677b47f8d89d80d750cb02f0b3d5fda4872 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:41:40 -0400 Subject: [PATCH 052/109] No need to null check here --- .../common/pipelike/PipeCollectorWalker.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index d4c692c73fa..71223dd7076 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -18,8 +18,7 @@ public class PipeCollectorWalker> extends PipeNetWalke public static void collectPipeNet(@NotNull World world, @NotNull BlockPos sourcePipe, @NotNull IPipeTile pipe, @NotNull Predicate> pipeFunction) { PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( - world, sourcePipe, 0, pipe.getClass()); - walker.pipeFunction = pipeFunction; + world, sourcePipe, 0, pipe.getClass(), pipeFunction); walker.traversePipeNet(); } @@ -30,28 +29,31 @@ public static void collectPipeNet(@NotNull World world, @NotNull BlockPos source * Function to run on every pipe * If false is returned then halt the walker */ - private Predicate> pipeFunction; + @NotNull + private final Predicate> pipeFunction; private BlockPos sourcePipe; - protected PipeCollectorWalker(World world, BlockPos sourcePipe, int walkedBlocks, Class basePipeClass) { + protected PipeCollectorWalker(@NotNull World world, @NotNull BlockPos sourcePipe, int walkedBlocks, + @NotNull Class basePipeClass, @NotNull Predicate> pipeFunction) { super(world, sourcePipe, walkedBlocks); this.sourcePipe = sourcePipe; this.basePipeClass = basePipeClass; + this.pipeFunction = pipeFunction; } @Override protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks) { - PipeCollectorWalker walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass); - walker.pipeFunction = pipeFunction; + PipeCollectorWalker walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass, + pipeFunction); walker.sourcePipe = sourcePipe; return walker; } @Override protected void checkPipe(T pipeTile, BlockPos pos) { - if (this.pipeFunction != null && !this.pipeFunction.test(pipeTile)) { + if (!this.pipeFunction.test(pipeTile)) { this.root.stop(); } } From 80db4d2e1825d38a50a2fae670388a927830f704 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:42:54 -0400 Subject: [PATCH 053/109] Misc static analysis changes --- src/main/java/gregtech/api/pipenet/PipeNetWalker.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/PipeNetWalker.java b/src/main/java/gregtech/api/pipenet/PipeNetWalker.java index 3b70d1cf3b4..1a39f8a6e4d 100644 --- a/src/main/java/gregtech/api/pipenet/PipeNetWalker.java +++ b/src/main/java/gregtech/api/pipenet/PipeNetWalker.java @@ -10,6 +10,7 @@ import net.minecraft.world.World; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -30,11 +31,13 @@ public abstract class PipeNetWalker> { protected PipeNetWalker root; + @NotNull private final World world; private Set walked; private final List nextPipeFacings = new ArrayList<>(5); private final List nextPipes = new ArrayList<>(5); private List> walkers; + @NotNull private final BlockPos.MutableBlockPos currentPos; private T currentPipe; private EnumFacing from = null; @@ -43,7 +46,7 @@ public abstract class PipeNetWalker> { private boolean running; private boolean failed = false; - protected PipeNetWalker(World world, BlockPos sourcePipe, int walkedBlocks) { + protected PipeNetWalker(@NotNull World world, @NotNull BlockPos sourcePipe, int walkedBlocks) { this.world = Objects.requireNonNull(world); this.walkedBlocks = walkedBlocks; this.currentPos = new BlockPos.MutableBlockPos(Objects.requireNonNull(sourcePipe)); @@ -189,6 +192,7 @@ private boolean checkPos() { if (!getBasePipeClass().isAssignableFrom(thisPipe.getClass())) { return false; } + // noinspection unchecked currentPipe = (T) thisPipe; } T pipeTile = currentPipe; @@ -203,6 +207,7 @@ private boolean checkPos() { TileEntity tile = pipeTile.getNeighbor(accessSide); if (tile != null && getBasePipeClass().isAssignableFrom(tile.getClass())) { + // noinspection unchecked T otherPipe = (T) tile; if (!otherPipe.isConnected(accessSide.getOpposite()) || otherPipe.isFaceBlocked(accessSide.getOpposite()) || isWalked(otherPipe)) @@ -233,11 +238,11 @@ public boolean isRunning() { return root.running; } - public World getWorld() { + public @NotNull World getWorld() { return world; } - public BlockPos getCurrentPos() { + public @NotNull BlockPos getCurrentPos() { return currentPos; } From 164ddaa5e560b93b96871a7335b9478d69bde6b5 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:26:59 -0400 Subject: [PATCH 054/109] Fix replacing with empty can when depleted --- .../spray/AbstractSprayBehavior.java | 66 +++++++------------ .../spray/DurabilitySprayBehavior.java | 17 +++-- 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 1c0d32742dc..bba1519c9b3 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -61,14 +61,6 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu return null; } - @Override - public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, - EnumFacing facing, float hitX, float hitY, float hitZ) { - ItemStack sprayCan = player.getHeldItem(hand); - EnumActionResult result = spray(player, hand, world, pos, facing, sprayCan); - return ActionResult.newResult(result, sprayCan); - } - @SuppressWarnings("UnusedReturnValue") public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull World world, @NotNull BlockPos pos, @@ -88,8 +80,17 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } } + @Override + public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, + EnumFacing facing, float hitX, float hitY, float hitZ) { + ItemStack sprayCan = player.getHeldItem(hand); + EnumActionResult result = spray(player, hand, world, pos, facing, sprayCan); + return ActionResult.newResult(result, sprayCan); + } + protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, - @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, @NotNull ItemStack sprayCan) { if (!canSpray(sprayCan)) { return EnumActionResult.PASS; @@ -97,48 +98,32 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block return EnumActionResult.FAIL; } - int returnCode = tryPaintBlock(world, pos, player, hand, facing, sprayCan); - if (returnCode == -2) { - return EnumActionResult.PASS; - } else if (returnCode == -1) { - onSpray(player, hand, sprayCan); - } - - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); - return EnumActionResult.SUCCESS; - } - - /** - * Return codes:
- * {@code -2}: didn't paint any block(s)
- * {@code -1}: colored 1 block
- * {@code 0+}: colored multiple blocks and {@link #onSpray(EntityPlayer, EnumHand, ItemStack)} was handled already - */ - protected int tryPaintBlock(@NotNull World world, @NotNull BlockPos pos, @NotNull EntityPlayer player, - @NotNull EnumHand hand, @NotNull EnumFacing side, @NotNull ItemStack sprayCan) { if (player.isSneaking()) { TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile) { - if (pipeTile.getPaintingColor() == getColorInt(sprayCan)) return -2; - return traversePipes(world, player, hand, pos, pipeTile, sprayCan); + if (te instanceof IPipeTilepipeTile && pipeTile.getPaintingColor() != getColorInt(sprayCan)) { + traversePipes(world, player, hand, pos, pipeTile, sprayCan); + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, + SoundCategory.PLAYERS, 1.0f, 1.0f); + return EnumActionResult.SUCCESS; } } - ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, side, player); + ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, facing, player); if (blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan))) { - return -1; + onSpray(player, hand, sprayCan); + world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, + SoundCategory.PLAYERS, 1.0f, 1.0f); + return EnumActionResult.SUCCESS; } - return -2; + return EnumActionResult.PASS; } - protected int traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull EnumHand hand, - @NotNull BlockPos startPos, @NotNull IPipeTile startingPipe, - @NotNull ItemStack sprayCan) { + protected void traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull EnumHand hand, + @NotNull BlockPos startPos, @NotNull IPipeTile startingPipe, + @NotNull ItemStack sprayCan) { EnumDyeColor dyeColor = getColor(sprayCan); int color = dyeColor == null ? -1 : dyeColor.colorValue; - int[] paintedCountHolder = { 0 }; PipeCollectorWalker.collectPipeNet(world, startPos, startingPipe, pipe -> { if (!canSpray(sprayCan)) { return false; @@ -148,12 +133,9 @@ protected int traversePipes(@NotNull World world, @NotNull EntityPlayer player, pipe.setPaintingColor(color); pipe.scheduleRenderUpdate(); onSpray(player, hand, sprayCan); - paintedCountHolder[0]++; } return true; }); - - return paintedCountHolder[0]; } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 690d5c88121..b6e9e641d71 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -7,6 +7,7 @@ import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -52,21 +53,25 @@ public boolean canSpray(@NotNull ItemStack stack) { public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { if (player.capabilities.isCreativeMode) return; - int usesLeft = getUsesLeft(sprayCan); - if (--usesLeft <= 0) { + if (damageCan(sprayCan)) { GTLog.logger.info("Spray can broke, replacing with replacement stack"); if (replacementStack.isEmpty()) { // If replacement stack is empty, just shrink resulting stack sprayCan.shrink(1); } else { - // Otherwise, update held item to replacement stack - player.setHeldItem(hand, replacementStack.copy()); + // Update held item to replacement stack + sprayCan.setItemDamage(replacementStack.getItemDamage()); + // Clear NBT from old can + sprayCan.setTagCompound(new NBTTagCompound()); + player.playSound(SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 1.0f, 1.0f); } - - return; } + } + protected boolean damageCan(@NotNull ItemStack sprayCan) { + int usesLeft = getUsesLeft(sprayCan) - 1; setUsesLeft(sprayCan, usesLeft); + return usesLeft == 0; } @Override From 74bd2bca4a9d62828674139c3bc6e5054e7f077d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:54:12 -0400 Subject: [PATCH 055/109] Try to stop at a branch --- .../gregtech/api/pipenet/block/BlockPipe.java | 36 ++++++------------- .../api/pipenet/tile/TileEntityPipeBase.java | 2 +- .../spray/AbstractSprayBehavior.java | 4 +++ .../common/pipelike/PipeCollectorWalker.java | 6 ++-- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index abefdd68e10..4c32aa8720a 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -80,36 +80,22 @@ public BlockPipe() { disableStats(); } - public static Cuboid6 getSideBox(EnumFacing side, float thickness) { + public static Cuboid6 getSideBox(@Nullable EnumFacing side, float thickness) { float min = (1.0f - thickness) / 2.0f, max = min + thickness; float faceMin = 0f, faceMax = 1f; if (side == null) return new Cuboid6(min, min, min, max, max, max); - Cuboid6 cuboid; - switch (side) { - case WEST: - cuboid = new Cuboid6(faceMin, min, min, min, max, max); - break; - case EAST: - cuboid = new Cuboid6(max, min, min, faceMax, max, max); - break; - case NORTH: - cuboid = new Cuboid6(min, min, faceMin, max, max, min); - break; - case SOUTH: - cuboid = new Cuboid6(min, min, max, max, max, faceMax); - break; - case UP: - cuboid = new Cuboid6(min, max, min, max, faceMax, max); - break; - case DOWN: - cuboid = new Cuboid6(min, faceMin, min, max, min, max); - break; - default: - cuboid = new Cuboid6(min, min, min, max, max, max); - } - return cuboid; + return switch (side) { + case WEST -> new Cuboid6(faceMin, min, min, min, max, max); + case EAST -> new Cuboid6(max, min, min, faceMax, max, max); + case NORTH -> new Cuboid6(min, min, faceMin, max, max, min); + case SOUTH -> new Cuboid6(min, min, max, max, max, faceMax); + case UP -> new Cuboid6(min, max, min, max, faceMax, max); + case DOWN -> new Cuboid6(min, faceMin, min, max, min, max); + // noinspection UnnecessaryDefault + default -> new Cuboid6(min, min, min, max, max, max); + }; } /** diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 3756849a3e7..4b3b474e108 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -145,7 +145,7 @@ public IPipeTile setSupportsTicking() { public BlockPipe getPipeBlock() { if (pipeBlock == null) { Block block = getBlockState().getBlock(); - // noinspection unchecked + // noinspection unchecked,rawtypes this.pipeBlock = block instanceof BlockPipe blockPipe ? blockPipe : null; } return pipeBlock; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index bba1519c9b3..e3de1782572 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -125,6 +125,10 @@ protected void traversePipes(@NotNull World world, @NotNull EntityPlayer player, EnumDyeColor dyeColor = getColor(sprayCan); int color = dyeColor == null ? -1 : dyeColor.colorValue; PipeCollectorWalker.collectPipeNet(world, startPos, startingPipe, pipe -> { + if (pipe.getNumConnections() > 2) { + return false; + } + if (!canSpray(sprayCan)) { return false; } diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java index 71223dd7076..a88d2a89a4a 100644 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java @@ -23,15 +23,15 @@ public static void collectPipeNet(@NotNull World world, @NotNull BlockPos source } // I love type erasure - htmlcsjs + @NotNull private final Class basePipeClass; - /** * Function to run on every pipe * If false is returned then halt the walker */ @NotNull private final Predicate> pipeFunction; - + @NotNull private BlockPos sourcePipe; protected PipeCollectorWalker(@NotNull World world, @NotNull BlockPos sourcePipe, int walkedBlocks, @@ -63,7 +63,7 @@ protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNei @Nullable TileEntity neighbourTile) {} @Override - protected Class getBasePipeClass() { + protected @NotNull Class getBasePipeClass() { return basePipeClass; } } From afdef145133798710a3cfdfb79e1813d0b4cdb71 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:56:20 -0400 Subject: [PATCH 056/109] Prevent recursive spraying if the pipe unpainted and the can is solvent --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index e3de1782572..3b1b5ac0401 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -100,7 +100,8 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block if (player.isSneaking()) { TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile && pipeTile.getPaintingColor() != getColorInt(sprayCan)) { + if (te instanceof IPipeTilepipeTile && (pipeTile.getPaintingColor() != getColorInt(sprayCan) || + (!pipeTile.isPainted() && getColor(sprayCan) == null))) { traversePipes(world, player, hand, pos, pipeTile, sprayCan); world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); From 0ca0466dd230761a20f194880c6b49eeab3cca9e Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:16:14 -0400 Subject: [PATCH 057/109] formatting changes --- .../gregtech/api/pipenet/tile/TileEntityPipeBase.java | 9 +++------ .../items/behaviors/spray/AbstractSprayBehavior.java | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 4b3b474e108..c8d168bf1eb 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -216,20 +216,17 @@ public void setConnection(EnumFacing side, boolean connected, boolean fromNeighb } TileEntity tile = getNeighbor(side); // block connections if Pipe Types do not match - if (connected && - tile instanceof IPipeTile pipeTile && + if (connected && tile instanceof IPipeTile pipeTile && pipeTile.getPipeType().getClass() != this.getPipeType().getClass()) { return; } connections = withSideConnection(connections, side, connected); updateNetworkConnection(side, connected); - writeCustomData(UPDATE_CONNECTIONS, buffer -> { - buffer.writeVarInt(connections); - }); + writeCustomData(UPDATE_CONNECTIONS, buffer -> buffer.writeVarInt(connections)); markDirty(); - if (!fromNeighbor && tile instanceof IPipeTile pipeTile) { + if (!fromNeighbor && tile instanceof IPipeTile pipeTile) { syncPipeConnections(side, pipeTile); } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 3b1b5ac0401..142800cf26b 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -100,8 +100,8 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block if (player.isSneaking()) { TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile && (pipeTile.getPaintingColor() != getColorInt(sprayCan) || - (!pipeTile.isPainted() && getColor(sprayCan) == null))) { + if (te instanceof IPipeTilepipeTile && (pipeTile.isPainted() ? + pipeTile.getPaintingColor() != getColorInt(sprayCan) : getColor(sprayCan) != null)) { traversePipes(world, player, hand, pos, pipeTile, sprayCan); world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); From 8784a9627a19049b34179d616691e87be4323255 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:32:18 -0400 Subject: [PATCH 058/109] Remove debug logger --- .../common/items/behaviors/spray/DurabilitySprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index b6e9e641d71..b17a79faa4e 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -54,7 +54,6 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu if (player.capabilities.isCreativeMode) return; if (damageCan(sprayCan)) { - GTLog.logger.info("Spray can broke, replacing with replacement stack"); if (replacementStack.isEmpty()) { // If replacement stack is empty, just shrink resulting stack sprayCan.shrink(1); @@ -63,6 +62,7 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu sprayCan.setItemDamage(replacementStack.getItemDamage()); // Clear NBT from old can sprayCan.setTagCompound(new NBTTagCompound()); + // Play sound manually since we aren't using player.setHeldItem(...) player.playSound(SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 1.0f, 1.0f); } } From a9a8bfac565c98a81266ce22eb31576d4ec01a2e Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:49:33 -0400 Subject: [PATCH 059/109] spobl --- .../java/gregtech/api/pipenet/tile/TileEntityPipeBase.java | 4 ++-- .../common/items/behaviors/spray/DurabilitySprayBehavior.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index c8d168bf1eb..b8955257a3d 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -216,7 +216,7 @@ public void setConnection(EnumFacing side, boolean connected, boolean fromNeighb } TileEntity tile = getNeighbor(side); // block connections if Pipe Types do not match - if (connected && tile instanceof IPipeTile pipeTile && + if (connected && tile instanceof IPipeTilepipeTile && pipeTile.getPipeType().getClass() != this.getPipeType().getClass()) { return; } @@ -226,7 +226,7 @@ public void setConnection(EnumFacing side, boolean connected, boolean fromNeighb writeCustomData(UPDATE_CONNECTIONS, buffer -> buffer.writeVarInt(connections)); markDirty(); - if (!fromNeighbor && tile instanceof IPipeTile pipeTile) { + if (!fromNeighbor && tile instanceof IPipeTilepipeTile) { syncPipeConnections(side, pipeTile); } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index b17a79faa4e..327fe4649e2 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -1,7 +1,6 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; -import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; From 2f05b944c2b4e7874452e930c6325b1a9ecfbfd0 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:50:43 -0400 Subject: [PATCH 060/109] Close the color picker gui when color pressed --- .../spray/CreativeSprayBehavior.java | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index f6446d972a6..a0c36670947 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -46,30 +46,38 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager newColor -> setColor(usedStack, newColor)); guiSyncManager.syncValue("color", 0, colorSync); - return GTGuis.createPanel(usedStack, 176, 120) - .child(SlotGroupWidget.builder() - .matrix("SCCCCCCCC", - "CCCCCCCC") - .key('S', new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == -1, - $ -> colorSync.setIntValue(-1))) - .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) - .key('C', index -> { - EnumDyeColor color = EnumDyeColor.values()[index]; - return new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == index, - $ -> colorSync.setIntValue(index))) - .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); - }) - .build()); + ModularPanel panel = GTGuis.createPanel(usedStack, 176, 120); + panel.child(SlotGroupWidget.builder() + .matrix("SCCCCCCCC", + "CCCCCCCC") + .key('S', new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == -1, + $ -> { + colorSync.setIntValue(-1); + panel.closeIfOpen(true); + })) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) + .asIcon() + .margin(2)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) + .key('C', index -> { + EnumDyeColor color = EnumDyeColor.values()[index]; + return new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == index, + $ -> { + colorSync.setIntValue(index); + panel.closeIfOpen(true); + })) + .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) + .asIcon() + .margin(2)) + .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); + }) + .build()); + + return panel; } @Override From ae48a1f13dc4aa86edf057b47fac23850ec95e7c Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 20:02:08 -0400 Subject: [PATCH 061/109] Cancel subwalkers at a split --- .../behaviors/spray/AbstractSprayBehavior.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 142800cf26b..303102caef3 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -125,12 +125,9 @@ protected void traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull ItemStack sprayCan) { EnumDyeColor dyeColor = getColor(sprayCan); int color = dyeColor == null ? -1 : dyeColor.colorValue; + boolean[] metSplit = { false }; PipeCollectorWalker.collectPipeNet(world, startPos, startingPipe, pipe -> { - if (pipe.getNumConnections() > 2) { - return false; - } - - if (!canSpray(sprayCan)) { + if (metSplit[0] || !canSpray(sprayCan)) { return false; } @@ -140,6 +137,12 @@ protected void traversePipes(@NotNull World world, @NotNull EntityPlayer player, onSpray(player, hand, sprayCan); } + if (pipe.getNumConnections() > 2) { + // Returning false here will not stop subwalkers from continuing, so make them exit immediately later + metSplit[0] = true; + return false; + } + return true; }); } From ec0e4ec98ccdfcf2f89497dc7c25b69c1cf2ef4a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 20:03:04 -0400 Subject: [PATCH 062/109] Make spray cans show the grid overlay when sneaking --- .../gregtech/api/pipenet/block/BlockPipe.java | 20 +++++++++++++------ .../gregtech/common/ToolEventHandlers.java | 7 +++++-- .../spray/AbstractSprayBehavior.java | 4 ++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 4c32aa8720a..674ce081472 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -633,20 +633,28 @@ private List getCollisionBox(IBlockAccess world, BlockPos pos, @ return result; } - 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)) || - entity.isSneaking() && isHoldingPipe((EntityPlayer) entity); + public boolean hasPipeCollisionChangingItem(@NotNull IBlockAccess world, @NotNull BlockPos pos, + @Nullable Entity entity) { + if (entity instanceof EntityPlayer entityPlayer) { + return hasPipeCollisionChangingItem(world, pos, entityPlayer, + entityPlayer.getHeldItem(EnumHand.MAIN_HAND)) || + hasPipeCollisionChangingItem(world, pos, entityPlayer, + entityPlayer.getHeldItem(EnumHand.OFF_HAND)) || + entity.isSneaking() && isHoldingPipe(entityPlayer); } return false; } public abstract boolean isHoldingPipe(EntityPlayer player); - public boolean hasPipeCollisionChangingItem(IBlockAccess world, BlockPos pos, ItemStack stack) { + public boolean hasPipeCollisionChangingItem(@NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityPlayer player, @NotNull ItemStack stack) { if (isPipeTool(stack)) return true; + if (player.isSneaking() && AbstractSprayBehavior.isSprayCan(stack)) { + return true; + } + IPipeTile pipeTile = getPipeTileEntity(world, pos); if (pipeTile == null) return false; diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index e503b539547..7f5db87a4ae 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -19,6 +19,7 @@ import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.util.GTUtility; import gregtech.api.util.TaskScheduler; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.common.items.tool.rotation.CustomBlockRotations; import gregtech.common.items.tool.rotation.ICustomRotationBehavior; @@ -303,10 +304,12 @@ private static void postRenderDamagedBlocks() { @SideOnly(Side.CLIENT) private static boolean shouldRenderGridOverlays(@NotNull IBlockState state, @Nullable TileEntity tile, - ItemStack mainHand, ItemStack offHand, boolean isSneaking) { + @NotNull ItemStack mainHand, @NotNull 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() || + AbstractSprayBehavior.isSprayCan(mainHand) || AbstractSprayBehavior.isSprayCan(offHand))) { return true; } else { Set mainToolClasses = mainHand.getItem().getToolClasses(mainHand); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 303102caef3..d4edfe58b02 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -61,6 +61,10 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNu return null; } + public static boolean isSprayCan(@NotNull ItemStack stack) { + return getSprayCanBehavior(stack) != null; + } + @SuppressWarnings("UnusedReturnValue") public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull World world, @NotNull BlockPos pos, From ecb4dcc824a2ecec5eba4c0a79e2622fe75dae48 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 21:03:44 -0400 Subject: [PATCH 063/109] Allow setting ARBG ints in color containers. Add explicit methods to GTPipeColorContainer to get either the color (actual pipe color or painting color) and only the painted color. --- .../api/color/ColoredBlockContainer.java | 9 ++++ .../containers/GTPipeColorContainer.java | 42 ++++++++++++++++++ .../color/containers/MTEColorContainer.java | 43 +++++++++++++------ .../spray/AbstractSprayBehavior.java | 5 ++- .../spray/CreativeSprayBehavior.java | 4 +- 5 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 9389c315b07..547b19e1c43 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -31,6 +31,15 @@ public static void registerContainerManager(@NotNull ContainerManager manager) { public abstract boolean setColor(@Nullable EnumDyeColor newColor); + public boolean setColor(int newColor) { + // Do nothing + return false; + } + + public boolean supportsARGB() { + return false; + } + public abstract boolean removeColor(); public abstract @Nullable EnumDyeColor getColor(); diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index 8fa8f080c6b..acf94903b2f 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -42,6 +42,29 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return false; } + @Override + public boolean setColor(int newColor) { + if (newColor == -1) { + return removeColor(); + } + + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { + if (pipeTile.isPainted() && getColorInt() == newColor) { + return false; + } else { + pipeTile.setPaintingColor(newColor); + return true; + } + } + + return false; + } + + @Override + public boolean supportsARGB() { + return true; + } + @Override public boolean removeColor() { if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { @@ -64,6 +87,17 @@ public boolean removeColor() { return null; } + public @Nullable EnumDyeColor getPaintingColor() { + int mteColor = getPaintingColorInt(); + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (mteColor == dyeColor.colorValue) { + return dyeColor; + } + } + + return null; + } + @Override public int getColorInt() { if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { @@ -73,6 +107,14 @@ public int getColorInt() { return -1; } + public int getPaintingColorInt() { + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { + return pipeTile.getPaintingColor(); + } + + return -1; + } + public static class GTPipeColorManager extends ContainerManager { @Override diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index ac86582f1c1..0c3f74949cd 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -6,7 +6,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -14,6 +13,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static gregtech.api.util.GTUtility.getMetaTileEntity; + public class MTEColorContainer extends ColoredBlockContainer { @NotNull @@ -43,7 +44,26 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return false; } - MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + MetaTileEntity mte = getMetaTileEntity(world, pos); + if (mte != null && mte.canBeModifiedBy(player)) { + mte.setPaintingColor(newColor, facing); + return true; + } + + return false; + } + + @Override + public boolean setColor(int newColor) { + if (newColor == -1) { + return removeColor(); + } + + if (getColorInt() == newColor) { + return false; + } + + MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.canBeModifiedBy(player)) { mte.setPaintingColor(newColor, facing); return true; @@ -52,9 +72,14 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { return false; } + @Override + public boolean supportsARGB() { + return true; + } + @Override public boolean removeColor() { - MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { mte.setPaintingColor(-1, facing); return true; @@ -77,7 +102,7 @@ public boolean removeColor() { @Override public int getColorInt() { - MetaTileEntity mte = getMetaTileEntity(world.getTileEntity(pos)); + MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null) { return mte.getPaintingColor(); } @@ -106,14 +131,4 @@ protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @Not return false; } } - - private static @Nullable MetaTileEntity getMetaTileEntity(@Nullable TileEntity te) { - if (te instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - if (mte == null || !mte.isValid()) return null; - return mte; - } - - return null; - } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index d4edfe58b02..08a7fc03caa 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -113,8 +113,9 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } } - ColoredBlockContainer blockContainer = ColoredBlockContainer.getInstance(world, pos, facing, player); - if (blockContainer.isValid() && blockContainer.setColor(getColor(sprayCan))) { + ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(world, pos, facing, player); + if (colorContainer.isValid() && colorContainer.supportsARGB() ? colorContainer.setColor(getColorInt(sprayCan)) : + colorContainer.setColor(getColor(sprayCan))) { onSpray(player, hand, sprayCan); world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, SoundCategory.PLAYERS, 1.0f, 1.0f); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index a0c36670947..3fda4e6a66e 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -1,6 +1,7 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.color.containers.GTPipeColorContainer; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; @@ -170,7 +171,8 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); - EnumDyeColor hitColor = colorContainer.getColor(); + EnumDyeColor hitColor = colorContainer instanceof GTPipeColorContainer pipeContainer ? + pipeContainer.getPaintingColor() : colorContainer.getColor(); if (hitColor != null && hitColor != getColor(stack)) { setColor(stack, hitColor); sendToServer(buf -> buf From b098157a5f042d0757ba1f4fff63391af018a74d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Tue, 5 Aug 2025 21:52:22 -0400 Subject: [PATCH 064/109] Use a custom pipe traversal method as PipeNetWalker doesn't fit my needs. (I think it's desyncing!!!! woooo) --- .../api/items/toolitem/ItemGTToolbelt.java | 3 +- .../spray/AbstractSprayBehavior.java | 115 +++++++++++------- .../spray/DurabilitySprayBehavior.java | 3 +- .../common/pipelike/PipeCollectorWalker.java | 69 ----------- 4 files changed, 74 insertions(+), 116 deletions(-) delete mode 100644 src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 84220893888..7be15367d3a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -506,8 +506,7 @@ public void setSelectedTool(int slot, ItemStack stack) { ToolStackHandler handler = getHandler(player.getHeldItem(hand)); ItemStack selected = handler.getSelectedStack(); if (!selected.isEmpty()) { - EnumActionResult result = AbstractSprayBehavior.handleExternalSpray(player, hand, world, pos, facing, - selected); + EnumActionResult result = AbstractSprayBehavior.handleExternalSpray(player, world, pos, facing, selected); if (result != EnumActionResult.PASS) { return result; } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 08a7fc03caa..343c33aa566 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -1,10 +1,10 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.common.pipelike.PipeCollectorWalker; import gregtech.core.sound.GTSoundEvents; import net.minecraft.entity.player.EntityPlayer; @@ -16,15 +16,20 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import codechicken.lib.raytracer.RayTracer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; public abstract class AbstractSprayBehavior implements IItemBehaviour { + private static final int MAX_PIPE_TRAVERSAL_LENGTH = 128; + /** * Get the color of the spray can. {@code null} = solvent */ @@ -35,18 +40,26 @@ public int getColorInt(@NotNull ItemStack stack) { return color == null ? -1 : color.colorValue; } + public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack stack) { + EnumDyeColor color = getColor(stack); + return color == null ? -1 : color.ordinal(); + } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public boolean canSpray(@NotNull ItemStack stack) { return true; } - public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { + public void onSpray(@NotNull EntityPlayer player, @NotNull ItemStack sprayCan) { // } - public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack stack) { - EnumDyeColor color = getColor(stack); - return color == null ? -1 : color.ordinal(); + public boolean hasSpraySound(@NotNull ItemStack sprayCan) { + return true; + } + + public @NotNull SoundEvent getSpraySound(@NotNull ItemStack sprayCan) { + return GTSoundEvents.SPRAY_CAN_TOOL; } public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack stack) { @@ -69,10 +82,10 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing) { - return handleExternalSpray(player, hand, world, pos, facing, player.getHeldItem(hand)); + return handleExternalSpray(player, world, pos, facing, player.getHeldItem(hand)); } - public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, + public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull ItemStack sprayCan) { @@ -80,7 +93,7 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { if (sprayBehavior == null) { return EnumActionResult.PASS; } else { - return sprayBehavior.spray(player, hand, world, pos, facing, sprayCan); + return sprayBehavior.spray(player, world, pos, facing, sprayCan); } } @@ -88,14 +101,16 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { ItemStack sprayCan = player.getHeldItem(hand); - EnumActionResult result = spray(player, hand, world, pos, facing, sprayCan); + EnumActionResult result = spray(player, world, pos, facing, sprayCan); + if (hasSpraySound(sprayCan) && result == EnumActionResult.SUCCESS) { + world.playSound(null, player.posX, player.posY, player.posZ, getSpraySound(sprayCan), SoundCategory.PLAYERS, + 1.0f, 1.0f); + } return ActionResult.newResult(result, sprayCan); } - protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull EnumHand hand, - @NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull ItemStack sprayCan) { + protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, @NotNull ItemStack sprayCan) { if (!canSpray(sprayCan)) { return EnumActionResult.PASS; } else if (!player.canPlayerEdit(pos, facing, sprayCan)) { @@ -104,51 +119,65 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block if (player.isSneaking()) { TileEntity te = world.getTileEntity(pos); - if (te instanceof IPipeTilepipeTile && (pipeTile.isPainted() ? - pipeTile.getPaintingColor() != getColorInt(sprayCan) : getColor(sprayCan) != null)) { - traversePipes(world, player, hand, pos, pipeTile, sprayCan); - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); - return EnumActionResult.SUCCESS; + int color = getColorInt(sprayCan); + if (te instanceof IPipeTilefirstPipe && (firstPipe.isPainted() ? + firstPipe.getPaintingColor() != color : getColor(sprayCan) != null)) { + RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); + if (hitResult != null) { + EnumFacing hitSide = CoverRayTracer.determineGridSideHit(hitResult); + if (hitSide != null && firstPipe.isConnected(hitSide)) { + firstPipe.setPaintingColor(color); + traversePipes(world, pos, hitSide, player, sprayCan, color); + return EnumActionResult.SUCCESS; + } + } } } ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(world, pos, facing, player); if (colorContainer.isValid() && colorContainer.supportsARGB() ? colorContainer.setColor(getColorInt(sprayCan)) : colorContainer.setColor(getColor(sprayCan))) { - onSpray(player, hand, sprayCan); - world.playSound(null, player.posX, player.posY, player.posZ, GTSoundEvents.SPRAY_CAN_TOOL, - SoundCategory.PLAYERS, 1.0f, 1.0f); + onSpray(player, sprayCan); return EnumActionResult.SUCCESS; } return EnumActionResult.PASS; } - protected void traversePipes(@NotNull World world, @NotNull EntityPlayer player, @NotNull EnumHand hand, - @NotNull BlockPos startPos, @NotNull IPipeTile startingPipe, - @NotNull ItemStack sprayCan) { - EnumDyeColor dyeColor = getColor(sprayCan); - int color = dyeColor == null ? -1 : dyeColor.colorValue; - boolean[] metSplit = { false }; - PipeCollectorWalker.collectPipeNet(world, startPos, startingPipe, pipe -> { - if (metSplit[0] || !canSpray(sprayCan)) { - return false; - } + protected void traversePipes(@NotNull World world, @NotNull BlockPos startPos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @NotNull ItemStack sprayCan, int color) { + startPos = startPos.offset(facing); + IPipeTile nextPipeTile; + if (world.getTileEntity(startPos) instanceof IPipeTilepipeTile) { + nextPipeTile = pipeTile; + } else { + return; + } - if (pipe.getPaintingColor() != color) { - pipe.setPaintingColor(color); - pipe.scheduleRenderUpdate(); - onSpray(player, hand, sprayCan); + for (int count = 1; count < MAX_PIPE_TRAVERSAL_LENGTH && canSpray(sprayCan); count++) { + if (nextPipeTile.isPainted() ? nextPipeTile.getPaintingColor() != color : color != -1) { + nextPipeTile.setPaintingColor(color); + onSpray(player, sprayCan); + } else { + break; } - if (pipe.getNumConnections() > 2) { - // Returning false here will not stop subwalkers from continuing, so make them exit immediately later - metSplit[0] = true; - return false; + if (nextPipeTile.getNumConnections() == 2) { + int connections = nextPipeTile.getConnections(); + connections &= ~(1 << facing.getOpposite().getIndex()); + for (EnumFacing other : EnumFacing.VALUES) { + if ((connections & (1 << other.getIndex())) != 0) { + facing = other; + if (nextPipeTile.getNeighbor(facing) instanceof IPipeTileneighboringPipe) { + nextPipeTile = neighboringPipe; + } else { + break; + } + } + } + } else { + break; } - - return true; - }); + } } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 327fe4649e2..614dbc07a4d 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -10,7 +10,6 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; import net.minecraftforge.common.util.Constants; import org.apache.commons.lang3.tuple.Pair; @@ -49,7 +48,7 @@ public boolean canSpray(@NotNull ItemStack stack) { } @Override - public void onSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { + public void onSpray(@NotNull EntityPlayer player, @NotNull ItemStack sprayCan) { if (player.capabilities.isCreativeMode) return; if (damageCan(sprayCan)) { diff --git a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java b/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java deleted file mode 100644 index a88d2a89a4a..00000000000 --- a/src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java +++ /dev/null @@ -1,69 +0,0 @@ -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.function.Predicate; - -public class PipeCollectorWalker> extends PipeNetWalker { - - public static void collectPipeNet(@NotNull World world, @NotNull BlockPos sourcePipe, @NotNull IPipeTile pipe, - @NotNull Predicate> pipeFunction) { - PipeCollectorWalker> walker = (PipeCollectorWalker>) new PipeCollectorWalker<>( - world, sourcePipe, 0, pipe.getClass(), pipeFunction); - walker.traversePipeNet(); - } - - // I love type erasure - htmlcsjs - @NotNull - private final Class basePipeClass; - /** - * Function to run on every pipe - * If false is returned then halt the walker - */ - @NotNull - private final Predicate> pipeFunction; - @NotNull - private BlockPos sourcePipe; - - protected PipeCollectorWalker(@NotNull World world, @NotNull BlockPos sourcePipe, int walkedBlocks, - @NotNull Class basePipeClass, @NotNull Predicate> pipeFunction) { - super(world, sourcePipe, walkedBlocks); - this.sourcePipe = sourcePipe; - this.basePipeClass = basePipeClass; - this.pipeFunction = pipeFunction; - } - - @Override - protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, - int walkedBlocks) { - PipeCollectorWalker walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass, - pipeFunction); - walker.sourcePipe = sourcePipe; - return walker; - } - - @Override - protected void checkPipe(T pipeTile, BlockPos pos) { - if (!this.pipeFunction.test(pipeTile)) { - this.root.stop(); - } - } - - @Override - protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, - @Nullable TileEntity neighbourTile) {} - - @Override - protected @NotNull Class getBasePipeClass() { - return basePipeClass; - } -} From 6f5aafb8864783a22c105680baf03798bf313a49 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 17:36:45 -0400 Subject: [PATCH 065/109] Make the ray trace not die server side (ie ACTUALLY WORK) --- .../gregtech/api/pipenet/block/BlockPipe.java | 4 +- .../spray/AbstractSprayBehavior.java | 43 ++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 674ce081472..34073b9cd1c 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -562,12 +562,12 @@ protected boolean isThisPipeBlock(Block block) { /** * Just returns proper pipe tile entity */ - public IPipeTile getPipeTileEntity(IBlockAccess world, BlockPos selfPos) { + public @Nullable IPipeTile getPipeTileEntity(IBlockAccess world, BlockPos selfPos) { TileEntity tileEntityAtPos = world.getTileEntity(selfPos); return getPipeTileEntity(tileEntityAtPos); } - public IPipeTile getPipeTileEntity(TileEntity tileEntityAtPos) { + public @Nullable IPipeTile getPipeTileEntity(TileEntity tileEntityAtPos) { if (tileEntityAtPos instanceof IPipeTile && isThisPipeBlock(((IPipeTile) tileEntityAtPos).getPipeBlock())) { return (IPipeTile) tileEntityAtPos; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 343c33aa566..67b5fa1f842 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -4,13 +4,13 @@ import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.core.sound.GTSoundEvents; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -21,7 +21,6 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; -import codechicken.lib.raytracer.RayTracer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; @@ -118,16 +117,14 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } if (player.isSneaking()) { - TileEntity te = world.getTileEntity(pos); int color = getColorInt(sprayCan); - if (te instanceof IPipeTilefirstPipe && (firstPipe.isPainted() ? - firstPipe.getPaintingColor() != color : getColor(sprayCan) != null)) { - RayTraceResult hitResult = RayTracer.retraceBlock(world, player, pos); + if (world.getBlockState(pos).getBlock() instanceof BlockPipeblockPipe) { + RayTraceResult hitResult = blockPipe.getServerCollisionRayTrace(player, pos, world); if (hitResult != null) { EnumFacing hitSide = CoverRayTracer.determineGridSideHit(hitResult); - if (hitSide != null && firstPipe.isConnected(hitSide)) { - firstPipe.setPaintingColor(color); - traversePipes(world, pos, hitSide, player, sprayCan, color); + IPipeTile firstPipe = blockPipe.getPipeTileEntity(world, pos); + if (hitSide != null && firstPipe != null && firstPipe.isConnected(hitSide)) { + traversePipes(firstPipe, hitSide, player, sprayCan, color); return EnumActionResult.SUCCESS; } } @@ -144,32 +141,29 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block return EnumActionResult.PASS; } - protected void traversePipes(@NotNull World world, @NotNull BlockPos startPos, @NotNull EnumFacing facing, + protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @NotNull ItemStack sprayCan, int color) { - startPos = startPos.offset(facing); - IPipeTile nextPipeTile; - if (world.getTileEntity(startPos) instanceof IPipeTilepipeTile) { - nextPipeTile = pipeTile; + if (tryPaintPipe(pipeTile, color) && pipeTile.getNeighbor(facing) instanceof IPipeTilenextPipe) { + pipeTile = nextPipe; } else { return; } for (int count = 1; count < MAX_PIPE_TRAVERSAL_LENGTH && canSpray(sprayCan); count++) { - if (nextPipeTile.isPainted() ? nextPipeTile.getPaintingColor() != color : color != -1) { - nextPipeTile.setPaintingColor(color); + if (tryPaintPipe(pipeTile, color)) { onSpray(player, sprayCan); } else { break; } - if (nextPipeTile.getNumConnections() == 2) { - int connections = nextPipeTile.getConnections(); + if (pipeTile.getNumConnections() == 2) { + int connections = pipeTile.getConnections(); connections &= ~(1 << facing.getOpposite().getIndex()); for (EnumFacing other : EnumFacing.VALUES) { if ((connections & (1 << other.getIndex())) != 0) { facing = other; - if (nextPipeTile.getNeighbor(facing) instanceof IPipeTileneighboringPipe) { - nextPipeTile = neighboringPipe; + if (pipeTile.getNeighbor(facing) instanceof IPipeTileneighboringPipe) { + pipeTile = neighboringPipe; } else { break; } @@ -180,4 +174,13 @@ protected void traversePipes(@NotNull World world, @NotNull BlockPos startPos, @ } } } + + private static boolean tryPaintPipe(@NotNull IPipeTile pipeTile, int color) { + if (pipeTile.isPainted() ? pipeTile.getPaintingColor() != color : color != -1) { + pipeTile.setPaintingColor(color); + return true; + } + + return false; + } } From 63fa2de73e31c17052d3712e2322461cc84859e0 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 19:49:42 -0400 Subject: [PATCH 066/109] Fix using 1 durability too less on recursive paints --- .../behaviors/spray/AbstractSprayBehavior.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 67b5fa1f842..90f2d680e49 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -143,14 +143,17 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @NotNull ItemStack sprayCan, int color) { - if (tryPaintPipe(pipeTile, color) && pipeTile.getNeighbor(facing) instanceof IPipeTilenextPipe) { + if (canPipeBePainted(pipeTile, color) && pipeTile.getNeighbor(facing) instanceof IPipeTilenextPipe) { + pipeTile.setPaintingColor(color); + onSpray(player, sprayCan); pipeTile = nextPipe; } else { return; } for (int count = 1; count < MAX_PIPE_TRAVERSAL_LENGTH && canSpray(sprayCan); count++) { - if (tryPaintPipe(pipeTile, color)) { + if (canPipeBePainted(pipeTile, color)) { + pipeTile.setPaintingColor(color); onSpray(player, sprayCan); } else { break; @@ -175,12 +178,7 @@ protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFac } } - private static boolean tryPaintPipe(@NotNull IPipeTile pipeTile, int color) { - if (pipeTile.isPainted() ? pipeTile.getPaintingColor() != color : color != -1) { - pipeTile.setPaintingColor(color); - return true; - } - - return false; + private static boolean canPipeBePainted(@NotNull IPipeTile pipeTile, int color) { + return pipeTile.isPainted() ? pipeTile.getPaintingColor() != color : color != -1; } } From 6834dcc528bddcb0f7c834f62cc66f7d4c1b4d2e Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 19:49:57 -0400 Subject: [PATCH 067/109] Add config for max spray distance --- src/main/java/gregtech/common/ConfigHolder.java | 4 ++++ .../common/items/behaviors/spray/AbstractSprayBehavior.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 93cbb1dbdcf..a3c55b53384 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -717,6 +717,10 @@ public static class ToolOptions { @Config.RangeInt(min = 1, max = 100) @Config.SlidingOption public int magnetDelay = 10; + + @Config.Comment({ "The maximum amount of pipes a recursive spray can do at once", "Default: 128 blocks" }) + @Config.RangeInt(min = 1, max = 1024) + public int maxRecursiveSprayLength = 128; } public static class ArmorHud { diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 90f2d680e49..c8122eaceb0 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -6,6 +6,7 @@ import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.tile.IPipeTile; +import gregtech.common.ConfigHolder; import gregtech.core.sound.GTSoundEvents; import net.minecraft.entity.player.EntityPlayer; @@ -151,7 +152,7 @@ protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFac return; } - for (int count = 1; count < MAX_PIPE_TRAVERSAL_LENGTH && canSpray(sprayCan); count++) { + for (int count = 1; count < ConfigHolder.tools.maxRecursiveSprayLength && canSpray(sprayCan); count++) { if (canPipeBePainted(pipeTile, color)) { pipeTile.setPaintingColor(color); onSpray(player, sprayCan); From 12ddcf14d3c0999383c74a695903547a60f8bbc5 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:05:12 -0400 Subject: [PATCH 068/109] Remove left clicking to shift the creative spray cans color --- .../spray/CreativeSprayBehavior.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 3fda4e6a66e..1a0926b9c27 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -137,26 +137,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla int button = event.getButton(); boolean sneaking = playerClient.isSneaking(); - // TODO make changing it in the hand shift scrolling. - if (button == 0) { // Left click - if (isLocked(stack)) return; - - int color; - if (sneaking) { - color = getColorOrdinal(stack) - 1; - if (color == -2) color = 15; - } else { - color = getColorOrdinal(stack) + 1; - } - - setColor(stack, color); - event.setCanceled(true); - - final int finalColor = color; // grr java - sendToServer(buf -> buf - .writeByte(0) - .writeByte(finalColor)); - } else if (button == 2) { // Middle click + if (button == 2) { // Middle click if (sneaking) { toggleLocked(stack); } else if (!isLocked(stack)) { From c1df493dc06054b67d1ccb21404b7ea040459afb Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:05:39 -0400 Subject: [PATCH 069/109] Tiny color container refactor --- .../color/containers/AE2ColorContainer.java | 5 +++++ .../containers/GTPipeColorContainer.java | 22 +++++-------------- .../color/containers/MTEColorContainer.java | 8 +++++++ .../spray/CreativeSprayBehavior.java | 3 +-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index 407e9ec2203..b52d1d64e13 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -76,6 +76,11 @@ public boolean removeColor() { return null; } + @Override + public boolean isValid() { + return world.getTileEntity(pos) instanceof IColorableTile; + } + public static class AE2BlockManager extends ColoredBlockContainer.ContainerManager { @Override diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index acf94903b2f..adb6d4a5396 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -78,17 +78,8 @@ public boolean removeColor() { @Override public @Nullable EnumDyeColor getColor() { int mteColor = getColorInt(); - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { - if (mteColor == dyeColor.colorValue) { - return dyeColor; - } - } - - return null; - } + if (mteColor == -1) return null; - public @Nullable EnumDyeColor getPaintingColor() { - int mteColor = getPaintingColorInt(); for (EnumDyeColor dyeColor : EnumDyeColor.values()) { if (mteColor == dyeColor.colorValue) { return dyeColor; @@ -100,19 +91,16 @@ public boolean removeColor() { @Override public int getColorInt() { - if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { + if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { return pipeTile.getPaintingColor(); } return -1; } - public int getPaintingColorInt() { - if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { - return pipeTile.getPaintingColor(); - } - - return -1; + @Override + public boolean isValid() { + return world.getTileEntity(pos) instanceof IPipeTile; } public static class GTPipeColorManager extends ContainerManager { diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index 0c3f74949cd..e2da855c831 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -91,6 +91,8 @@ public boolean removeColor() { @Override public @Nullable EnumDyeColor getColor() { int mteColor = getColorInt(); + if (mteColor == -1) return null; + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { if (mteColor == dyeColor.colorValue) { return dyeColor; @@ -110,6 +112,12 @@ public int getColorInt() { return -1; } + @Override + public boolean isValid() { + MetaTileEntity mte = getMetaTileEntity(world, pos); + return mte != null && mte.isValid(); + } + public static class MTEColorManager extends ColoredBlockContainer.ContainerManager { @Override diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 1a0926b9c27..165b6d21293 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -152,8 +152,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); - EnumDyeColor hitColor = colorContainer instanceof GTPipeColorContainer pipeContainer ? - pipeContainer.getPaintingColor() : colorContainer.getColor(); + EnumDyeColor hitColor = colorContainer.getColor(); if (hitColor != null && hitColor != getColor(stack)) { setColor(stack, hitColor); sendToServer(buf -> buf From afed92efdd377fc8739317b727983e08193924a6 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:10:03 -0400 Subject: [PATCH 070/109] Remove redundant check (The AE2 color manager won't be registered in the first place if AE2 isn't installed) --- .../java/gregtech/api/color/containers/AE2ColorContainer.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index b52d1d64e13..06ab22b4e83 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -93,9 +93,7 @@ public static class AE2BlockManager extends ColoredBlockContainer.ContainerManag @Override protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - if (!Mods.AppliedEnergistics2.isModLoaded()) return false; - TileEntity te = world.getTileEntity(pos); - return te instanceof IColorableTile; + return world.getTileEntity(pos) instanceof IColorableTile; } } } From cede48d94ac505094389ded9356494ef2211bc45 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:23:07 -0400 Subject: [PATCH 071/109] spotless --- .../java/gregtech/api/color/containers/AE2ColorContainer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index 06ab22b4e83..72b4f4bf4b3 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -1,7 +1,6 @@ package gregtech.api.color.containers; import gregtech.api.color.ColoredBlockContainer; -import gregtech.api.util.Mods; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; From dc3c01324b2769a5bf9b2369dc43f2e1d52c7320 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:25:16 -0400 Subject: [PATCH 072/109] Remove locking after removing the left click functionality --- .../java/gregtech/common/items/MetaItem1.java | 2 - .../spray/CreativeSprayBehavior.java | 67 ++++++------------ .../resources/assets/gregtech/lang/en_us.lang | 36 +++++----- .../models/item/metaitems/spray.creative.json | 16 +---- .../item/metaitems/spray.creative/locked.json | 8 --- .../item/metaitems/spray.creative/normal.json | 7 -- .../items/metaitems/spray.creative/lock.png | Bin 4450 -> 0 bytes 7 files changed, 42 insertions(+), 94 deletions(-) delete mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json delete mode 100644 src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json delete mode 100644 src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 1b9d3087187..e10a06c201c 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -180,8 +180,6 @@ public void registerSubItems() { SPRAY_CREATIVE = addItem(30, "spray.creative") .addComponents(new CreativeSprayBehavior()); - SPRAY_CREATIVE.getMetaItem().addPropertyOverride(GTUtility.gregtechId("spray.creative"), - (stack, worldIn, entityIn) -> CreativeSprayBehavior.isLocked(stack) ? 1.0f : 0.0f); // Extruder Shapes: ID 31-59 SHAPE_EXTRUDERS[0] = SHAPE_EXTRUDER_PLATE = addItem(31, "shape.extruder.plate") diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 165b6d21293..bffbe41bb1a 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -1,7 +1,6 @@ package gregtech.common.items.behaviors.spray; import gregtech.api.color.ColoredBlockContainer; -import gregtech.api.color.containers.GTPipeColorContainer; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; @@ -110,18 +109,6 @@ public int getItemStackColor(ItemStack itemStack, int tintIndex) { return color != null && tintIndex == 1 ? color.colorValue : 0xFFFFFF; } - public static boolean isLocked(@NotNull ItemStack stack) { - return GTUtility.getOrCreateNbtCompound(stack).getBoolean("Locked"); - } - - public static void setLocked(@NotNull ItemStack stack, boolean locked) { - GTUtility.getOrCreateNbtCompound(stack).setBoolean("Locked", locked); - } - - public static void toggleLocked(@NotNull ItemStack stack) { - setLocked(stack, !isLocked(stack)); - } - @Override public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedName) { EnumDyeColor color = getColor(itemStack); @@ -133,39 +120,31 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam @Override public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, @NotNull ItemStack stack) { - if (event.getButton() != -1 && event.isButtonstate()) { - int button = event.getButton(); - boolean sneaking = playerClient.isSneaking(); - - if (button == 2) { // Middle click - if (sneaking) { - toggleLocked(stack); - } else if (!isLocked(stack)) { - event.setCanceled(true); - - double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); - if (!playerClient.capabilities.isCreativeMode) { - reach -= 0.5d; - } - - RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); - if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { - ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, - rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); - EnumDyeColor hitColor = colorContainer.getColor(); - if (hitColor != null && hitColor != getColor(stack)) { - setColor(stack, hitColor); - sendToServer(buf -> buf - .writeByte(0) - .writeByte(hitColor.ordinal())); - return; - } - } - - // If the player isn't sneaking and wasn't looking at a colored block, open gui - sendToServer(buf -> buf.writeByte(1)); + // Middle click pressed down + if (event.getButton() == 2 && event.isButtonstate()) { + event.setCanceled(true); + + double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); + if (!playerClient.capabilities.isCreativeMode) { + reach -= 0.5d; + } + + RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); + if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { + ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, + rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); + EnumDyeColor hitColor = colorContainer.getColor(); + if (hitColor != null && hitColor != getColor(stack)) { + setColor(stack, hitColor); + sendToServer(buf -> buf + .writeByte(0) + .writeByte(hitColor.ordinal())); + return; } } + + // If the player isn't sneaking and wasn't looking at a colored block, open gui + sendToServer(buf -> buf.writeByte(1)); } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 5399a45de4d..93e9f7d5380 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -330,6 +330,24 @@ metaitem.shape.extruder.rotor.tooltip=Extruder Shape for making Rotors metaitem.spray.empty.name=Spray Can (Empty) metaitem.spray.empty.tooltip=Can be filled with sprays of various colors +metaitem.spray.creative.name=Creative Spray Can (%s) +metaitem.spray.creative.solvent=Solvent +metaitem.spray.creative.white=White +metaitem.spray.creative.orange=Orange +metaitem.spray.creative.magenta=Magenta +metaitem.spray.creative.lightBlue=Light Blue +metaitem.spray.creative.yellow=Yellow +metaitem.spray.creative.lime=Lime +metaitem.spray.creative.pink=Pink +metaitem.spray.creative.gray=Gray +metaitem.spray.creative.silver=Gray +metaitem.spray.creative.cyan=Cyan +metaitem.spray.creative.purple=Purple +metaitem.spray.creative.blue=Blue +metaitem.spray.creative.brown=Brown +metaitem.spray.creative.green=Green +metaitem.spray.creative.red=Red +metaitem.spray.creative.black=Black metaitem.plant.ball.name=Plantball @@ -362,24 +380,6 @@ metaitem.spray.can.dyes.brown.name=Spray Can (Brown) metaitem.spray.can.dyes.green.name=Spray Can (Green) metaitem.spray.can.dyes.red.name=Spray Can (Red) metaitem.spray.can.dyes.black.name=Spray Can (Black) -metaitem.spray.creative.name=Creative Spray Can (%s) -metaitem.spray.creative.solvent=Solvent -metaitem.spray.creative.white=White -metaitem.spray.creative.orange=Orange -metaitem.spray.creative.magenta=Magenta -metaitem.spray.creative.lightBlue=Light Blue -metaitem.spray.creative.yellow=Yellow -metaitem.spray.creative.lime=Lime -metaitem.spray.creative.pink=Pink -metaitem.spray.creative.gray=Gray -metaitem.spray.creative.silver=Gray -metaitem.spray.creative.cyan=Cyan -metaitem.spray.creative.purple=Purple -metaitem.spray.creative.blue=Blue -metaitem.spray.creative.brown=Brown -metaitem.spray.creative.green=Green -metaitem.spray.creative.red=Red -metaitem.spray.creative.black=Black metaitem.tool.matches.name=Match diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json index 18784119b80..bbc05432e18 100644 --- a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json +++ b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative.json @@ -3,19 +3,5 @@ "textures": { "layer0": "gregtech:items/metaitems/spray.creative/base", "layer1": "gregtech:items/metaitems/spray.creative/overlay" - }, - "overrides": [ - { - "predicate": { - "gregtech:spray.creative": 0.0 - }, - "model": "gregtech:item/metaitems/spray.creative/normal" - }, - { - "predicate": { - "gregtech:spray.creative": 1.0 - }, - "model": "gregtech:item/metaitems/spray.creative/locked" - } - ] + } } diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json deleted file mode 100644 index 2c431a94d35..00000000000 --- a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/locked.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "gregtech:items/metaitems/spray.creative/base", - "layer1": "gregtech:items/metaitems/spray.creative/overlay", - "layer2": "gregtech:items/metaitems/spray.creative/lock" - } -} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json b/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json deleted file mode 100644 index bbc05432e18..00000000000 --- a/src/main/resources/assets/gregtech/models/item/metaitems/spray.creative/normal.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "gregtech:items/metaitems/spray.creative/base", - "layer1": "gregtech:items/metaitems/spray.creative/overlay" - } -} diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png b/src/main/resources/assets/gregtech/textures/items/metaitems/spray.creative/lock.png deleted file mode 100644 index 3cf38a228f46b6c553a8e6cbfff8384670f80d09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4450 zcmeHKYitx%6dqa%ZIP!HP_c|t1O;a2v9Fo2TP(Y!yU60wE(f7V4edKBI|gqW+Y2a%OIunA5OzZnPug$Gh5zqh7VG?pk$C@vb9#YqsRsPb_Pg z(RIz2HDz7hrrK$|#5b8XW{ryGjd@@GD34b@oPYlD>~9XvZ4RvcVC81z@`ch>AhmL=I_t9VTem|c+J8kQTye-T@tr0to?r7el z9qDZ1AKaeRqPDoI49>34q9@N;kKFZS+KyW-yDwCo zrhwY$Lc2-6}aphvKSXm~r z5;iX{GdIpbfFRI#G#(6uR4#7A61W_E*3ATlCS0^K8@Al-LG4NepeBRKK;i{)xtzxG zGSS?K?h@hYxgtVN25R%vzAC5)>iE<>7009t$t}0xW8nk4g%kAll&?)fC z!Eho9l0C>%lYRYU4a!ZQNt81%5g6WwJIK4Y_JlL^a=ST)B1ZM}Tn-ziug^(}C`(-8 z5dhX~0h9^nc_88@0a$Uys1GR%!&?DM308Ihlq;lad`JX36a+WO5XUD`60iyuTo45a z!BA$L5lk#@CIw0qC8L$~`368d5RsuO`M|)ebSMczNrJ%BRuh8@RwIp@D1pLRz_K_` z3p8yNEg~z52`EYA7ATP*58EjRc|Rb+A%9{*C!EXoxNI10Ap0$z0I&IA0Nev|NK#^I z|CCn_f?|!=`J}A0g*H(%%~BM_Sj_!S4}ypawWy;~q`_!O%;=5bU^$RlURNpvNZ4UD zoIL_~O^J9FC1At!q)iVxPC>#l-yIrU|n*Q90ugXWDZ@z?CoNu*;fyT&V#NPY9_` z(ju5C)@Vrz^j|8kUlD!fK(IP;_{aA@Ms**Dzf}Vqi$l!|EEQYe)5Qz04QlnyG13Q`_3wx}JQ`Znt-D1x^6Yb$4{cKY8Wl1&x(iBuOI3@2wfLvp3dt Q!Z^fLu-Ng={52c?1iKF{uK)l5 From 884ccdec189e9d7f1ee5fc3a90bc79338d491698 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:26:31 -0400 Subject: [PATCH 073/109] No more spellchecking!!! --- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index bffbe41bb1a..5addac281d4 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -47,6 +47,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager guiSyncManager.syncValue("color", 0, colorSync); ModularPanel panel = GTGuis.createPanel(usedStack, 176, 120); + // noinspection SpellCheckingInspection panel.child(SlotGroupWidget.builder() .matrix("SCCCCCCCC", "CCCCCCCC") From 59ec19989babcb2b871efaddecdf6801e6b1eb97 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:17:55 -0400 Subject: [PATCH 074/109] Make color containers more static, less object creation --- .../api/color/ColoredBlockContainer.java | 79 +++++++++++-------- .../color/containers/AE2ColorContainer.java | 49 +++--------- .../containers/GTPipeColorContainer.java | 62 +++++---------- .../color/containers/MTEColorContainer.java | 74 +++++------------ .../color/containers/NullColorContainer.java | 17 +++- .../containers/VanillaColorContainer.java | 49 +++--------- .../spray/AbstractSprayBehavior.java | 6 +- .../spray/CreativeSprayBehavior.java | 12 ++- src/main/java/gregtech/core/CoreModule.java | 12 +-- 9 files changed, 131 insertions(+), 229 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 547b19e1c43..78e1e5efa0e 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -1,6 +1,11 @@ package gregtech.api.color; +import gregtech.api.color.containers.AE2ColorContainer; +import gregtech.api.color.containers.GTPipeColorContainer; +import gregtech.api.color.containers.MTEColorContainer; import gregtech.api.color.containers.NullColorContainer; +import gregtech.api.color.containers.VanillaColorContainer; +import gregtech.api.util.Mods; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -9,6 +14,7 @@ import net.minecraft.world.World; import it.unimi.dsi.fastutil.objects.ObjectArraySet; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,56 +28,59 @@ */ public abstract class ColoredBlockContainer { - private static final Set MANAGERS = new ObjectArraySet<>(3); + @NotNull + private static final Set CONTAINERS = new ObjectArraySet<>(4); - public static void registerContainerManager(@NotNull ContainerManager manager) { - Objects.requireNonNull(manager); - MANAGERS.add(manager); + public static void registerContainer(@NotNull ColoredBlockContainer container) { + CONTAINERS.add(Objects.requireNonNull(container)); } - public abstract boolean setColor(@Nullable EnumDyeColor newColor); + public static @NotNull ColoredBlockContainer getContainer(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + for (ColoredBlockContainer container : CONTAINERS) { + if (container.isValid(world, pos, facing, player)) { + return container; + } + } - public boolean setColor(int newColor) { - // Do nothing - return false; + return NullColorContainer.NULL_CONTAINER; } - public boolean supportsARGB() { - return false; + @ApiStatus.Internal + public static void registerCEuContainers() { + registerContainer(new VanillaColorContainer()); + registerContainer(new GTPipeColorContainer()); + registerContainer(new MTEColorContainer()); + if (Mods.AppliedEnergistics2.isModLoaded()) { + registerContainer(new AE2ColorContainer()); + } } - public abstract boolean removeColor(); + public abstract boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player); - public abstract @Nullable EnumDyeColor getColor(); + public abstract boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor); - public int getColorInt() { - EnumDyeColor dyeColor = getColor(); - return dyeColor == null ? -1 : dyeColor.colorValue; + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { + return false; } - public boolean isValid() { - return true; - } + public abstract boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player); - public static @NotNull ColoredBlockContainer getInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - for (ContainerManager manager : MANAGERS) { - if (manager.blockMatches(world, pos, facing, player)) { - return manager.createInstance(world, pos, facing, player); - } - } + public abstract @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, @NotNull EntityPlayer player); - return NullColorContainer.NULL_CONTAINER; + public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + EnumDyeColor dyeColor = getColor(world, pos, facing, player); + return dyeColor == null ? -1 : dyeColor.colorValue; } - public static abstract class ContainerManager { - - protected abstract @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player); - - protected abstract boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, @NotNull EntityPlayer player); + public boolean supportsARGB() { + return false; } } diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index 72b4f4bf4b3..bc91048a358 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -16,30 +16,14 @@ public class AE2ColorContainer extends ColoredBlockContainer { - @NotNull - private final World world; - @NotNull - private final BlockPos pos; - @NotNull - private final EnumFacing facing; - @NotNull - private final EntityPlayer player; - - private AE2ColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - this.world = world; - this.pos = pos; - this.facing = facing; - this.player = player; - } - @Override - public boolean setColor(@Nullable EnumDyeColor newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { - return removeColor(); + return removeColor(world, pos, facing, player); } - if (getColor() == newColor) { + if (getColor(world, pos, facing, player) == newColor) { return false; } @@ -55,7 +39,8 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { } @Override - public boolean removeColor() { + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile && colorableTile.getColor() != AEColor.TRANSPARENT) { colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player); @@ -66,7 +51,8 @@ public boolean removeColor() { } @Override - public @Nullable EnumDyeColor getColor() { + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile) { return colorableTile.getColor().dye; @@ -76,23 +62,8 @@ public boolean removeColor() { } @Override - public boolean isValid() { + public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof IColorableTile; } - - public static class AE2BlockManager extends ColoredBlockContainer.ContainerManager { - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new AE2ColorContainer(world, pos, facing, player); - } - - @Override - protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return world.getTileEntity(pos) instanceof IColorableTile; - } - } } diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index adb6d4a5396..a30fbf52686 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -14,23 +14,14 @@ public class GTPipeColorContainer extends ColoredBlockContainer { - @NotNull - private final World world; - @NotNull - private final BlockPos pos; - - private GTPipeColorContainer(@NotNull World world, @NotNull BlockPos pos) { - this.world = world; - this.pos = pos; - } - @Override - public boolean setColor(@Nullable EnumDyeColor newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { - return removeColor(); + return removeColor(world, pos, facing, player); } - if (getColorInt() == newColor.colorValue) { + if (getColorInt(world, pos, facing, player) == newColor.colorValue) { return false; } @@ -43,13 +34,14 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { } @Override - public boolean setColor(int newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { if (newColor == -1) { - return removeColor(); + return removeColor(world, pos, facing, player); } if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { - if (pipeTile.isPainted() && getColorInt() == newColor) { + if (pipeTile.isPainted() && getColorInt(world, pos, facing, player) == newColor) { return false; } else { pipeTile.setPaintingColor(newColor); @@ -61,12 +53,8 @@ public boolean setColor(int newColor) { } @Override - public boolean supportsARGB() { - return true; - } - - @Override - public boolean removeColor() { + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { pipeTile.setPaintingColor(-1); return true; @@ -76,8 +64,9 @@ public boolean removeColor() { } @Override - public @Nullable EnumDyeColor getColor() { - int mteColor = getColorInt(); + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + int mteColor = getColorInt(world, pos, facing, player); if (mteColor == -1) return null; for (EnumDyeColor dyeColor : EnumDyeColor.values()) { @@ -90,7 +79,8 @@ public boolean removeColor() { } @Override - public int getColorInt() { + public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { return pipeTile.getPaintingColor(); } @@ -99,23 +89,13 @@ public int getColorInt() { } @Override - public boolean isValid() { - return world.getTileEntity(pos) instanceof IPipeTile; + public boolean supportsARGB() { + return true; } - public static class GTPipeColorManager extends ContainerManager { - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new GTPipeColorContainer(world, pos); - } - - @Override - protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return world.getTileEntity(pos) instanceof IPipeTile; - } + @Override + public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return world.getTileEntity(pos) instanceof IPipeTile; } } diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index e2da855c831..f1fc227301a 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -2,7 +2,6 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -17,30 +16,14 @@ public class MTEColorContainer extends ColoredBlockContainer { - @NotNull - private final World world; - @NotNull - private final BlockPos pos; - @NotNull - private final EnumFacing facing; - @NotNull - private final EntityPlayer player; - - private MTEColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - this.world = world; - this.pos = pos; - this.facing = facing; - this.player = player; - } - @Override - public boolean setColor(@Nullable EnumDyeColor newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { - return removeColor(); + return removeColor(world, pos, facing, player); } - if (getColorInt() == newColor.colorValue) { + if (getColorInt(world, pos, facing, player) == newColor.colorValue) { return false; } @@ -54,12 +37,13 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { } @Override - public boolean setColor(int newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { if (newColor == -1) { - return removeColor(); + return removeColor(world, pos, facing, player); } - if (getColorInt() == newColor) { + if (getColorInt(world, pos, facing, player) == newColor) { return false; } @@ -73,12 +57,8 @@ public boolean setColor(int newColor) { } @Override - public boolean supportsARGB() { - return true; - } - - @Override - public boolean removeColor() { + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { mte.setPaintingColor(-1, facing); @@ -89,8 +69,9 @@ public boolean removeColor() { } @Override - public @Nullable EnumDyeColor getColor() { - int mteColor = getColorInt(); + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + int mteColor = getColorInt(world, pos, facing, player); if (mteColor == -1) return null; for (EnumDyeColor dyeColor : EnumDyeColor.values()) { @@ -103,7 +84,8 @@ public boolean removeColor() { } @Override - public int getColorInt() { + public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null) { return mte.getPaintingColor(); @@ -113,30 +95,14 @@ public int getColorInt() { } @Override - public boolean isValid() { + public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { MetaTileEntity mte = getMetaTileEntity(world, pos); return mte != null && mte.isValid(); } - public static class MTEColorManager extends ColoredBlockContainer.ContainerManager { - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new MTEColorContainer(world, pos, facing, player); - } - - @Override - protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - if (world.getTileEntity(pos) instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - if (mte == null || !mte.isValid()) return false; - return mte.canBeModifiedBy(player); - } - - return false; - } + @Override + public boolean supportsARGB() { + return true; } } diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index def240be4f8..8f2f1be6c8b 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -2,8 +2,13 @@ import gregtech.api.color.ColoredBlockContainer; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; +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; public class NullColorContainer extends ColoredBlockContainer { @@ -11,22 +16,26 @@ public class NullColorContainer extends ColoredBlockContainer { public static final NullColorContainer NULL_CONTAINER = new NullColorContainer(); @Override - public boolean setColor(@Nullable EnumDyeColor newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { return false; } @Override - public boolean removeColor() { + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, + @NotNull EntityPlayer player) { return false; } @Override - public @Nullable EnumDyeColor getColor() { + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, + @NotNull EntityPlayer player) { return null; } @Override - public boolean isValid() { + public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, + @NotNull EntityPlayer player) { return false; } } diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index b848972adff..3e367e5b0af 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -35,26 +35,14 @@ public class VanillaColorContainer extends ColoredBlockContainer { Blocks.GLASS_PANE, BlockStainedGlassPane.COLOR, Blocks.HARDENED_CLAY, BlockColored.COLOR); - @NotNull - private final World world; - @NotNull - private final BlockPos pos; - @NotNull - private final EnumFacing facing; - - private VanillaColorContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing) { - this.world = world; - this.pos = pos; - this.facing = facing; - } - @Override - public boolean setColor(@Nullable EnumDyeColor newColor) { + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { - return removeColor(); + return removeColor(world, pos, facing, player); } - if (getColor() == newColor) { + if (getColor(world, pos, facing, player) == newColor) { return false; } @@ -73,7 +61,8 @@ public boolean setColor(@Nullable EnumDyeColor newColor) { } @Override - public boolean removeColor() { + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); @@ -107,7 +96,8 @@ public boolean removeColor() { } @Override - public @Nullable EnumDyeColor getColor() { + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); for (IProperty prop : state.getPropertyKeys()) { if (prop.getValueClass() == EnumDyeColor.class) { @@ -120,27 +110,8 @@ public boolean removeColor() { } @Override - public boolean isValid() { + public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { return !world.isAirBlock(pos); } - - public static class VanillaBlockManager extends ColoredBlockContainer.ContainerManager { - - @Override - protected @NotNull ColoredBlockContainer createInstance(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return new VanillaColorContainer(world, pos, facing); - } - - @Override - protected boolean blockMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - IBlockState blockState = world.getBlockState(pos); - Block block = blockState.getBlock(); - - return TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block) || - block instanceof BlockColored; - } - } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index c8122eaceb0..0c49453b510 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -132,9 +132,9 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } } - ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(world, pos, facing, player); - if (colorContainer.isValid() && colorContainer.supportsARGB() ? colorContainer.setColor(getColorInt(sprayCan)) : - colorContainer.setColor(getColor(sprayCan))) { + ColoredBlockContainer colorContainer = ColoredBlockContainer.getContainer(world, pos, facing, player); + if (colorContainer.supportsARGB() ? colorContainer.setColor(world, pos, facing, player, getColorInt(sprayCan)) : + colorContainer.setColor(world, pos, facing, player, getColor(sprayCan))) { onSpray(player, sprayCan); return EnumActionResult.SUCCESS; } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 5addac281d4..94138592520 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -19,8 +19,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; @@ -132,9 +135,12 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { - ColoredBlockContainer colorContainer = ColoredBlockContainer.getInstance(playerClient.world, - rayTrace.getBlockPos(), rayTrace.sideHit, playerClient); - EnumDyeColor hitColor = colorContainer.getColor(); + World world = playerClient.world; + BlockPos pos = rayTrace.getBlockPos(); + EnumFacing facing = rayTrace.sideHit; + ColoredBlockContainer colorContainer = ColoredBlockContainer.getContainer(world, pos, facing, + playerClient); + EnumDyeColor hitColor = colorContainer.getColor(world, pos, facing, playerClient); if (hitColor != null && hitColor != getColor(stack)) { setColor(stack, hitColor); sendToServer(buf -> buf diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 9df2b636f25..c969f4fcae1 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -6,10 +6,6 @@ import gregtech.api.block.IHeatingCoilBlockStats; import gregtech.api.capability.SimpleCapabilityManager; import gregtech.api.color.ColoredBlockContainer; -import gregtech.api.color.containers.AE2ColorContainer; -import gregtech.api.color.containers.GTPipeColorContainer; -import gregtech.api.color.containers.MTEColorContainer; -import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverUIFactory; import gregtech.api.fluids.GTFluidRegistration; @@ -310,13 +306,7 @@ public void postInit(@NotNull FMLPostInitializationEvent event) { } ModHandler.postInit(); - - ColoredBlockContainer.registerContainerManager(new VanillaColorContainer.VanillaBlockManager()); - ColoredBlockContainer.registerContainerManager(new MTEColorContainer.MTEColorManager()); - ColoredBlockContainer.registerContainerManager(new GTPipeColorContainer.GTPipeColorManager()); - if (Mods.AppliedEnergistics2.isModLoaded()) { - ColoredBlockContainer.registerContainerManager(new AE2ColorContainer.AE2BlockManager()); - } + ColoredBlockContainer.registerCEuContainers(); } @Override From 1becdaaf8260d2cf42aa79ab9f0b4bace17b3c25 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:18:29 -0400 Subject: [PATCH 075/109] Constant not needed after I added the spray range config --- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 0c49453b510..db9f6b45d11 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -28,8 +28,6 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { - private static final int MAX_PIPE_TRAVERSAL_LENGTH = 128; - /** * Get the color of the spray can. {@code null} = solvent */ From cdd102b1ff0746d798a6fce0c9e96c0ad5a8f520 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:27:29 -0400 Subject: [PATCH 076/109] Add message to null check --- src/main/java/gregtech/api/color/ColoredBlockContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 78e1e5efa0e..4771a822d93 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -32,7 +32,7 @@ public abstract class ColoredBlockContainer { private static final Set CONTAINERS = new ObjectArraySet<>(4); public static void registerContainer(@NotNull ColoredBlockContainer container) { - CONTAINERS.add(Objects.requireNonNull(container)); + CONTAINERS.add(Objects.requireNonNull(container, "A null ColoredBlockContainer cannot be registered!")); } public static @NotNull ColoredBlockContainer getContainer(@NotNull World world, @NotNull BlockPos pos, From 3e0410de4d90b5a8db39781ced98420b3415536a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 8 Aug 2025 18:48:59 -0400 Subject: [PATCH 077/109] Prep ARGB support in the creative can --- .../api/color/ColoredBlockContainer.java | 15 ++- .../color/containers/NullColorContainer.java | 6 + .../containers/VanillaColorContainer.java | 9 +- .../spray/AbstractSprayBehavior.java | 27 +++-- .../spray/CreativeSprayBehavior.java | 103 ++++++++++++------ 5 files changed, 109 insertions(+), 51 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 4771a822d93..ac9963c98ec 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -49,12 +49,12 @@ public static void registerContainer(@NotNull ColoredBlockContainer container) { @ApiStatus.Internal public static void registerCEuContainers() { - registerContainer(new VanillaColorContainer()); registerContainer(new GTPipeColorContainer()); registerContainer(new MTEColorContainer()); if (Mods.AppliedEnergistics2.isModLoaded()) { registerContainer(new AE2ColorContainer()); } + registerContainer(new VanillaColorContainer()); } public abstract boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @@ -76,8 +76,17 @@ public abstract boolean removeColor(@NotNull World world, @NotNull BlockPos pos, public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - EnumDyeColor dyeColor = getColor(world, pos, facing, player); - return dyeColor == null ? -1 : dyeColor.colorValue; + return -1; + } + + public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor color) { + return getColor(world, pos, facing, player) == color; + } + + public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int color) { + return getColorInt(world, pos, facing, player) == color; } public boolean supportsARGB() { diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index 8f2f1be6c8b..72b3ad13a7d 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -38,4 +38,10 @@ public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @Nullable En @NotNull EntityPlayer player) { return false; } + + @Override + public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor color) { + return false; + } } diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 3e367e5b0af..f4f691b17bf 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -112,6 +112,13 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull @Override public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return !world.isAirBlock(pos); + IBlockState state = world.getBlockState(pos); + for (IProperty prop : state.getPropertyKeys()) { + if (prop.getValueClass() == EnumDyeColor.class) { + return !world.isAirBlock(pos); + } + } + + return false; } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index db9f6b45d11..d5a5addfc96 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -31,20 +31,20 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { /** * Get the color of the spray can. {@code null} = solvent */ - public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack stack); + public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack sprayCan); - public int getColorInt(@NotNull ItemStack stack) { - EnumDyeColor color = getColor(stack); + public int getColorInt(@NotNull ItemStack sprayCan) { + EnumDyeColor color = getColor(sprayCan); return color == null ? -1 : color.colorValue; } - public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack stack) { - EnumDyeColor color = getColor(stack); + public @Range(from = -1, to = 15) int getColorOrdinal(@NotNull ItemStack sprayCan) { + EnumDyeColor color = getColor(sprayCan); return color == null ? -1 : color.ordinal(); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean canSpray(@NotNull ItemStack stack) { + public boolean canSpray(@NotNull ItemStack sprayCan) { return true; } @@ -60,10 +60,14 @@ public boolean hasSpraySound(@NotNull ItemStack sprayCan) { return GTSoundEvents.SPRAY_CAN_TOOL; } - public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack stack) { - if (!(stack.getItem() instanceof MetaItemmetaItem)) return null; + public int getMaximumSprayLength(@NotNull ItemStack sprayCan) { + return ConfigHolder.tools.maxRecursiveSprayLength; + } + + public static @Nullable AbstractSprayBehavior getSprayCanBehavior(@NotNull ItemStack sprayCan) { + if (!(sprayCan.getItem() instanceof MetaItemmetaItem)) return null; - for (IItemBehaviour behaviour : metaItem.getBehaviours(stack)) { + for (IItemBehaviour behaviour : metaItem.getBehaviours(sprayCan)) { if (behaviour instanceof AbstractSprayBehavior sprayBehavior) { return sprayBehavior; } @@ -122,7 +126,8 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block if (hitResult != null) { EnumFacing hitSide = CoverRayTracer.determineGridSideHit(hitResult); IPipeTile firstPipe = blockPipe.getPipeTileEntity(world, pos); - if (hitSide != null && firstPipe != null && firstPipe.isConnected(hitSide)) { + if (hitSide != null && firstPipe != null && firstPipe.isConnected(hitSide) && + (firstPipe.isPainted() ? firstPipe.getPaintingColor() != color : color != -1)) { traversePipes(firstPipe, hitSide, player, sprayCan, color); return EnumActionResult.SUCCESS; } @@ -150,7 +155,7 @@ protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFac return; } - for (int count = 1; count < ConfigHolder.tools.maxRecursiveSprayLength && canSpray(sprayCan); count++) { + for (int count = 1; count < getMaximumSprayLength(sprayCan) && canSpray(sprayCan); count++) { if (canPipeBePainted(pipeTile, color)) { pipeTile.setPaintingColor(color); onSpray(player, sprayCan); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 94138592520..3636d4a05dc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -13,7 +13,6 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; @@ -27,13 +26,16 @@ import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; +import codechicken.lib.raytracer.RayTracer; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import org.jetbrains.annotations.NotNull; @@ -42,12 +44,18 @@ public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, IItemNameProvider, IMouseEventHandler { + private static final String NBT_KEY_COLOR = "color"; + private static final String NBT_KEY_USESARGB = "usesARGB"; + private static final String NBT_KEY_ARGB_COLOR = "argbColor"; + @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { ItemStack usedStack = guiData.getUsedItemStack(); - IntSyncValue colorSync = new IntSyncValue(() -> getColorOrdinal(usedStack), - newColor -> setColor(usedStack, newColor)); + IntSyncValue colorSync = SyncHandlers.intNumber(() -> getColorOrdinal(usedStack), + newColor -> setColorOrdinal(usedStack, newColor)); guiSyncManager.syncValue("color", 0, colorSync); + BooleanSyncValue arbgSync = SyncHandlers.bool(() -> usesARGB(usedStack), bool -> useARGB(usedStack, bool)); + guiSyncManager.syncValue("uses_argb", arbgSync); ModularPanel panel = GTGuis.createPanel(usedStack, 176, 120); // noinspection SpellCheckingInspection @@ -85,37 +93,53 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager } @Override - public @Nullable EnumDyeColor getColor(@NotNull ItemStack stack) { - NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(stack); - if (tag.hasKey("color", Constants.NBT.TAG_INT)) { - int color = tag.getInteger("color"); + public @Nullable EnumDyeColor getColor(@NotNull ItemStack sprayCan) { + NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); + if (tag.hasKey(NBT_KEY_COLOR, Constants.NBT.TAG_INT)) { + int color = tag.getInteger(NBT_KEY_COLOR); if (color < 0 || color > 15) return null; return EnumDyeColor.values()[color]; } return null; } - public static void setColor(@NotNull ItemStack stack, @Nullable EnumDyeColor color) { - GTUtility.getOrCreateNbtCompound(stack).setInteger("color", color == null ? -1 : color.ordinal()); + @Override + public int getColorInt(@NotNull ItemStack sprayCan) { + NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); + return tag.hasKey(NBT_KEY_USESARGB, Constants.NBT.TAG_INT) ? tag.getInteger(NBT_KEY_ARGB_COLOR) : + super.getColorInt(sprayCan); } - public static void setColor(@NotNull ItemStack stack, int color) { - if (color >= 0 && color <= 15) { - setColor(stack, EnumDyeColor.values()[color]); - } else { - setColor(stack, null); - } + public static void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, color == null ? -1 : color.ordinal()); + } + + public static void setColorOrdinal(@NotNull ItemStack sprayCan, int ordinal) { + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, + ordinal >= 0 && ordinal <= 15 ? ordinal : -1); + } + + public static void setColor(@NotNull ItemStack sprayCan, int argbColor) { + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_ARGB_COLOR, argbColor); + } + + public static boolean usesARGB(@NotNull ItemStack sprayCan) { + return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(NBT_KEY_USESARGB); + } + + public static void useARGB(@NotNull ItemStack sprayCan, boolean bool) { + GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(NBT_KEY_USESARGB, bool); } @Override - public int getItemStackColor(ItemStack itemStack, int tintIndex) { - EnumDyeColor color = getColor(itemStack); + public int getItemStackColor(ItemStack sprayCan, int tintIndex) { + EnumDyeColor color = getColor(sprayCan); return color != null && tintIndex == 1 ? color.colorValue : 0xFFFFFF; } @Override - public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedName) { - EnumDyeColor color = getColor(itemStack); + public String getItemStackDisplayName(ItemStack sprayCan, String unlocalizedName) { + EnumDyeColor color = getColor(sprayCan); String colorString = color == null ? I18n.format("metaitem.spray.creative.solvent") : I18n.format("metaitem.spray.creative." + color); return I18n.format(unlocalizedName, colorString); @@ -123,45 +147,52 @@ public String getItemStackDisplayName(ItemStack itemStack, String unlocalizedNam @Override public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, - @NotNull ItemStack stack) { + @NotNull ItemStack sprayCan) { // Middle click pressed down if (event.getButton() == 2 && event.isButtonstate()) { event.setCanceled(true); - double reach = playerClient.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); - if (!playerClient.capabilities.isCreativeMode) { - reach -= 0.5d; - } - - RayTraceResult rayTrace = playerClient.rayTrace(reach, 1.0f); + RayTraceResult rayTrace = RayTracer.retrace(playerClient); if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { World world = playerClient.world; BlockPos pos = rayTrace.getBlockPos(); EnumFacing facing = rayTrace.sideHit; - ColoredBlockContainer colorContainer = ColoredBlockContainer.getContainer(world, pos, facing, + ColoredBlockContainer container = ColoredBlockContainer.getContainer(world, pos, facing, playerClient); - EnumDyeColor hitColor = colorContainer.getColor(world, pos, facing, playerClient); - if (hitColor != null && hitColor != getColor(stack)) { - setColor(stack, hitColor); + + if (usesARGB(sprayCan) && container.supportsARGB() && + !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { + int color = container.getColorInt(world, pos, facing, playerClient); + if (color == -1) return; + setColor(sprayCan, color); + sendToServer(buf -> buf + .writeByte(1) + .writeInt(color)); + return; + } else if (!container.colorMatches(world, pos, facing, playerClient, getColor(sprayCan))) { + EnumDyeColor color = container.getColor(world, pos, facing, playerClient); + if (color == null) return; + setColor(sprayCan, color); sendToServer(buf -> buf - .writeByte(0) - .writeByte(hitColor.ordinal())); + .writeByte(2) + .writeByte(color.ordinal())); return; } } // If the player isn't sneaking and wasn't looking at a colored block, open gui - sendToServer(buf -> buf.writeByte(1)); + sendToServer(buf -> buf.writeByte(0)); } } @Override public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, - @NotNull ItemStack stack) { + @NotNull ItemStack sprayCan) { PacketBuffer buf = packet.getBuffer(); switch (buf.readByte()) { - case 0 -> setColor(stack, buf.readByte()); - case 1 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); + case 0 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); + case 1 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); + case 2 -> setColor(sprayCan, buf.readInt()); } } } From da9cb66a0f5f6ad6bad1ce0e45b914c81c8e4539 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 15:27:47 -0400 Subject: [PATCH 078/109] Slight event handler refactor --- .../api/color/ColoredBlockContainer.java | 3 +- .../containers/GTPipeColorContainer.java | 12 +----- .../color/containers/MTEColorContainer.java | 12 +----- .../metaitem/stats/IMouseEventHandler.java | 30 ++++++++++---- .../api/items/toolitem/ItemGTToolbelt.java | 27 ++++++++++--- .../java/gregtech/api/util/GTUtility.java | 13 +++++++ .../java/gregtech/client/ClientProxy.java | 25 ++++++------ .../spray/CreativeSprayBehavior.java | 39 ++++++++++--------- .../network/packets/PacketItemMouseEvent.java | 29 ++++++++------ 9 files changed, 115 insertions(+), 75 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index ac9963c98ec..b67bb103aa3 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -76,7 +76,8 @@ public abstract boolean removeColor(@NotNull World world, @NotNull BlockPos pos, public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return -1; + EnumDyeColor dyeColor = getColor(world, pos, facing, player); + return dyeColor == null ? -1 : dyeColor.colorValue; } public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index a30fbf52686..5fb8eaf2ec8 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -2,6 +2,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.pipenet.tile.IPipeTile; +import gregtech.api.util.GTUtility; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -66,16 +67,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull @Override public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - int mteColor = getColorInt(world, pos, facing, player); - if (mteColor == -1) return null; - - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { - if (mteColor == dyeColor.colorValue) { - return dyeColor; - } - } - - return null; + return GTUtility.getDyeColorFromARGB(getColorInt(world, pos, facing, player)); } @Override diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index f1fc227301a..e2f60680bf4 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -2,6 +2,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.GTUtility; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -71,16 +72,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull @Override public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - int mteColor = getColorInt(world, pos, facing, player); - if (mteColor == -1) return null; - - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { - if (mteColor == dyeColor.colorValue) { - return dyeColor; - } - } - - return null; + return GTUtility.getDyeColorFromARGB(getColorInt(world, pos, facing, player)); } @Override diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 033f1195f0f..912a02e90cd 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -1,16 +1,20 @@ package gregtech.api.items.metaitem.stats; +import gregtech.api.items.metaitem.MetaItem; import gregtech.core.network.packets.PacketItemMouseEvent; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumHand; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -43,23 +47,35 @@ public interface IMouseEventHandler extends IItemComponent { * * @param event the event * @param playerClient the player object on the client side - * @param stack the {@link ItemStack} the player is holding in their main hand + * @param stack the stack the player is holding in their main hand */ @SideOnly(Side.CLIENT) void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, - @NotNull ItemStack stack); + @NotNull EnumHand hand, @NotNull ItemStack stack); - default void sendToServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { - PacketItemMouseEvent.toServer(bufferWriter); + default void sendToServer(@NotNull EnumHand hand, @NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { + PacketItemMouseEvent.toServer(bufferWriter, hand); } /** * Handle the received mouse event on the server side. * - * @param packet the packet containing the data from the client event + * @param buf the packet containing the data from the client event * @param playerServer the server side counterpart of the client player * @param stack the stack the player was holding upon receiving the packet */ - void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, - @NotNull ItemStack stack); + void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPlayerMP playerServer, + @NotNull EnumHand hand, @NotNull ItemStack stack); + + static @Nullable IMouseEventHandler getHandler(@NotNull ItemStack stack) { + Item item = stack.getItem(); + + if (item instanceof MetaItemmetaItem) { + return metaItem.getMouseEventHandler(stack); + } else if (item instanceof IMouseEventHandler itemHandler) { + return itemHandler; + } + + return null; + } } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 7be15367d3a..a8cd231fcaa 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -3,6 +3,7 @@ import gregtech.api.GregTechAPI; import gregtech.api.items.IDyeableItem; import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.items.toolitem.behavior.IToolBehavior; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.mui.GTGuiTextures; @@ -17,6 +18,7 @@ import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMaintenanceHatch; import gregtech.core.network.packets.PacketToolbeltSelectionChange; +import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -34,9 +36,11 @@ import net.minecraft.item.ItemTool; import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; 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.IBlockAccess; @@ -79,7 +83,7 @@ import static gregtech.api.items.toolitem.ToolHelper.MATERIAL_KEY; -public class ItemGTToolbelt extends ItemGTTool implements IDyeableItem { +public class ItemGTToolbelt extends ItemGTTool implements IDyeableItem, IMouseEventHandler { private static final ThreadLocal lastSlot = ThreadLocal.withInitial(() -> -999); private static final ThreadLocal lastPlayer = ThreadLocal.withInitial(() -> null); @@ -427,9 +431,9 @@ public ICapabilityProvider initCapabilities(@NotNull ItemStack stack, NBTTagComp } @SideOnly(Side.CLIENT) - public void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, - @NotNull ItemStack stack) { - if (!ConfigHolder.client.toolbeltConfig.enableToolbeltScrollingCapture) return; + public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull EnumHand hand, @NotNull ItemStack stack) { + if (!ConfigHolder.client.toolbeltConfig.enableToolbeltScrollingCapture || hand != EnumHand.MAIN_HAND) return; if (event.getDwheel() != 0 && playerClient.isSneaking()) { // vanilla code in GuiIngame line 1235 does not copy the stack before storing it in the highlighting // item stack, so unless we copy the stack the tool highlight will not refresh. @@ -440,13 +444,26 @@ public void handleMouseEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP } else { handler.decrementSelectedSlot(); } - PacketToolbeltSelectionChange.toServer(handler.selectedSlot); + + sendToServer(hand, buf -> buf.writeInt(handler.selectedSlot)); InventoryPlayer inv = Minecraft.getMinecraft().player.inventory; inv.mainInventory.set(inv.currentItem, stack); event.setCanceled(true); } } + @Override + public void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPlayerMP playerServer, + @NotNull EnumHand hand, @NotNull ItemStack stack) { + // Should never happen, but just in case. + if (hand != EnumHand.MAIN_HAND) return; + if (stack.getItem() instanceof ItemGTToolbelt toolbelt) { + playerServer.getServerWorld().playSound(null, playerServer.posX, playerServer.posY, playerServer.posZ, + GTSoundEvents.CLICK, SoundCategory.PLAYERS, 2F, 1F); + toolbelt.setSelectedTool(buf.readInt(), stack); + } + } + @SideOnly(Side.CLIENT) public void changeSelectedToolHotkey(int slot, ItemStack stack) { ToolStackHandler handler = getHandler(stack); diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index d0c20c3e28e..ded4d8e0888 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -29,6 +29,7 @@ import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.inventory.Slot; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -1052,4 +1053,16 @@ public static double calculateDurabilityFromDamageTaken(int damageTaken, int max public static double calculateDurabilityFromRemaining(int remainingDurability, int maxDurability) { return (double) (maxDurability - remainingDurability) / maxDurability; } + + public static @Nullable EnumDyeColor getDyeColorFromARGB(int color) { + if (color == -1) return null; + + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (color == dyeColor.colorValue) { + return dyeColor; + } + } + + return null; + } } diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index e7486d6c994..4150dd68120 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -2,7 +2,6 @@ import gregtech.api.GTValues; import gregtech.api.fluids.GTFluidRegistration; -import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.items.toolitem.IGTTool; @@ -53,10 +52,10 @@ import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumHand; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.GuiIngameForge; import net.minecraftforge.client.event.ModelBakeEvent; @@ -355,17 +354,19 @@ public boolean isFancyGraphics() { @SubscribeEvent(priority = EventPriority.HIGH) public static void onMouseEvent(@NotNull MouseEvent event) { EntityPlayerSP player = Minecraft.getMinecraft().player; - ItemStack stack = player.getHeldItemMainhand(); // Todo main hand first, then try offhand - if (stack.isEmpty()) return; - Item item = stack.getItem(); - if (item instanceof MetaItemmetaItem) { - IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); - if (mouseEventHandler != null) { - mouseEventHandler.handleMouseEventClient(event, player, stack); - } - } else if (item instanceof ItemGTToolbelt toolbelt) { - toolbelt.handleMouseEvent(event, player, stack); + handleItemEvent(event, player, EnumHand.MAIN_HAND); + if (!event.isCanceled()) { + handleItemEvent(event, player, EnumHand.OFF_HAND); + } + } + + private static void handleItemEvent(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, + @NotNull EnumHand hand) { + ItemStack heldStack = playerClient.getHeldItem(hand); + IMouseEventHandler mouseEventHandler = IMouseEventHandler.getHandler(heldStack); + if (mouseEventHandler != null) { + mouseEventHandler.handleMouseEventClient(event, playerClient, hand, heldStack); } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 3636d4a05dc..9a952af1a76 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -9,7 +9,6 @@ import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; -import gregtech.core.network.packets.PacketItemMouseEvent; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.resources.I18n; @@ -25,6 +24,8 @@ import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.raytracer.RayTracer; import com.cleanroommc.modularui.api.drawable.IKey; @@ -145,9 +146,10 @@ public String getItemStackDisplayName(ItemStack sprayCan, String unlocalizedName return I18n.format(unlocalizedName, colorString); } + @SideOnly(Side.CLIENT) @Override public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPlayerSP playerClient, - @NotNull ItemStack sprayCan) { + @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { // Middle click pressed down if (event.getButton() == 2 && event.isButtonstate()) { event.setCanceled(true); @@ -163,32 +165,33 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla if (usesARGB(sprayCan) && container.supportsARGB() && !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { int color = container.getColorInt(world, pos, facing, playerClient); - if (color == -1) return; - setColor(sprayCan, color); - sendToServer(buf -> buf - .writeByte(1) - .writeInt(color)); - return; + if (color != -1) { + setColor(sprayCan, color); + sendToServer(hand, buf -> buf + .writeByte(1) + .writeInt(color)); + return; + } } else if (!container.colorMatches(world, pos, facing, playerClient, getColor(sprayCan))) { EnumDyeColor color = container.getColor(world, pos, facing, playerClient); - if (color == null) return; - setColor(sprayCan, color); - sendToServer(buf -> buf - .writeByte(2) - .writeByte(color.ordinal())); - return; + if (color != null) { + setColor(sprayCan, color); + sendToServer(hand, buf -> buf + .writeByte(2) + .writeByte(color.ordinal())); + return; + } } } // If the player isn't sneaking and wasn't looking at a colored block, open gui - sendToServer(buf -> buf.writeByte(0)); + sendToServer(hand, buf -> buf.writeByte(0)); } } @Override - public void handleMouseEventServer(@NotNull PacketItemMouseEvent packet, @NotNull EntityPlayerMP playerServer, - @NotNull ItemStack sprayCan) { - PacketBuffer buf = packet.getBuffer(); + public void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPlayerMP playerServer, + @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { switch (buf.readByte()) { case 0 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); case 1 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); diff --git a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java index d30d81d8a05..1a346846c76 100644 --- a/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java +++ b/src/main/java/gregtech/core/network/packets/PacketItemMouseEvent.java @@ -1,7 +1,6 @@ package gregtech.core.network.packets; import gregtech.api.GregTechAPI; -import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.network.IPacket; import gregtech.api.network.IServerExecutor; @@ -10,6 +9,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumHand; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -19,10 +19,11 @@ public class PacketItemMouseEvent implements IPacket, IServerExecutor { - private final ByteBuf internalBuffer = Unpooled.buffer(); + @NotNull + private final ByteBuf internalBuffer; - public @NotNull PacketBuffer getBuffer() { - return new PacketBuffer(internalBuffer.asReadOnly()); + public PacketItemMouseEvent() { + this.internalBuffer = Unpooled.buffer(); } @Override @@ -35,21 +36,25 @@ public void decode(PacketBuffer buf) { internalBuffer.writeBytes(buf); } - public static void toServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter) { + public static void toServer(@NotNull Consumer<@NotNull PacketBuffer> bufferWriter, @NotNull EnumHand hand) { PacketItemMouseEvent packet = new PacketItemMouseEvent(); - bufferWriter.accept(new PacketBuffer(packet.internalBuffer)); + PacketBuffer buf = new PacketBuffer(packet.internalBuffer); + buf.writeByte(hand.ordinal()); + bufferWriter.accept(buf); + GregTechAPI.networkHandler.sendToServer(packet); } @Override public void executeServer(NetHandlerPlayServer handler) { EntityPlayerMP player = handler.player; - ItemStack stack = player.getHeldItemMainhand(); - if (stack.getItem() instanceof MetaItemmetaItem) { - IMouseEventHandler mouseEventHandler = metaItem.getMouseEventHandler(stack); - if (mouseEventHandler != null) { - mouseEventHandler.handleMouseEventServer(this, player, stack); - } + EnumHand hand = EnumHand.values()[internalBuffer.readByte()]; + ItemStack stack = player.getHeldItem(hand); + + IMouseEventHandler mouseEventHandler = IMouseEventHandler.getHandler(stack); + if (mouseEventHandler != null) { + mouseEventHandler.handleMouseEventServer(new PacketBuffer(internalBuffer.asReadOnly()), player, hand, + stack); } } } From deb32a7e59124fa2bcbf608677ad1df06a2c908b Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:41:42 -0400 Subject: [PATCH 079/109] Add basic (A)RGB support to the creative can --- .../containers/GTPipeColorContainer.java | 4 +- .../color/containers/MTEColorContainer.java | 4 +- .../api/unification/material/Material.java | 3 +- .../java/gregtech/api/util/ColorUtil.java | 52 ++++++++ .../java/gregtech/api/util/GTUtility.java | 21 +-- .../items/behaviors/TricorderBehavior.java | 2 +- .../spray/CreativeSprayBehavior.java | 124 ++++++++++++------ .../resources/assets/gregtech/lang/en_us.lang | 1 + 8 files changed, 148 insertions(+), 63 deletions(-) create mode 100644 src/main/java/gregtech/api/util/ColorUtil.java diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index 5fb8eaf2ec8..cb7e8f2cb9b 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -2,7 +2,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.util.GTUtility; +import gregtech.api.util.ColorUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -67,7 +67,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull @Override public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return GTUtility.getDyeColorFromARGB(getColorInt(world, pos, facing, player)); + return ColorUtil.getDyeColorFromRGB(getColorInt(world, pos, facing, player)); } @Override diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index e2f60680bf4..51d6bdf5f59 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -2,7 +2,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.util.GTUtility; +import gregtech.api.util.ColorUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -72,7 +72,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull @Override public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - return GTUtility.getDyeColorFromARGB(getColorInt(world, pos, facing, player)); + return ColorUtil.getDyeColorFromRGB(getColorInt(world, pos, facing, player)); } @Override diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 569fe556e4b..b7b70f2b48b 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -32,6 +32,7 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.MaterialStack; +import gregtech.api.util.ColorUtil; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; @@ -904,7 +905,7 @@ public Builder color(int color) { */ public Builder color(@Range(from = 0, to = 255) int r, @Range(from = 0, to = 255) int g, @Range(from = 0, to = 255) int b) { - return color(GTUtility.combineRGB(r, g, b)); + return color(ColorUtil.combineRGB(r, g, b)); } public Builder colorAverage() { diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java new file mode 100644 index 00000000000..e40cd2692d4 --- /dev/null +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -0,0 +1,52 @@ +package gregtech.api.util; + +import net.minecraft.item.EnumDyeColor; + +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; + +public class ColorUtil { + + public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, to = 255) int g, + @Range(from = 0, to = 255) int b) { + return (r << 16) | (g << 8) | b; + } + + public static @Nullable EnumDyeColor getDyeColorFromRGB(int color) { + if (color == -1) return null; + + for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + if (color == dyeColor.colorValue) { + return dyeColor; + } + } + + return null; + } + + public enum ARGBHelper { + + ALPHA(0xFF000000, 24), + RED(0xFF0000, 16), + GREEN(0xFF00, 8), + BLUE(0xFF, 0); + + public final int overlay; + public final int invertedOverlay; + public final int shift; + + ARGBHelper(int overlay, int shift) { + this.overlay = overlay; + this.invertedOverlay = ~overlay; + this.shift = shift; + } + + public @Range(from = 0, to = 0xFF) int getFromInt(int sourceARGB) { + return (sourceARGB >> shift) & 0xFF; + } + + public int setInInt(int originalARGB, @Range(from = 0, to = 0xFF) int replacementColor) { + return (originalARGB & invertedOverlay) | (replacementColor << shift); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index ded4d8e0888..76e26b64a38 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -29,7 +29,6 @@ import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.inventory.Slot; -import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -64,7 +63,6 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; import java.util.AbstractList; import java.util.ArrayList; @@ -798,7 +796,7 @@ public static boolean canSeeSunClearly(@NotNull World world, @NotNull BlockPos b return world.isDaytime(); } - public static MapColor getMapColor(int rgb) { + public static @NotNull MapColor getMapColor(int rgb) { MapColor color = MapColor.BLACK; int originalR = (rgb >> 16) & 0xFF; int originalG = (rgb >> 8) & 0xFF; @@ -1010,11 +1008,6 @@ public static long scaleVoltage(long voltage, int workingTier) { return Math.min(voltage, GTValues.VA[workingTier]); } - public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, to = 255) int g, - @Range(from = 0, to = 255) int b) { - return (r << 16) | (g << 8) | b; - } - /** * @param map the map to get from * @param key the key to retrieve with @@ -1053,16 +1046,4 @@ public static double calculateDurabilityFromDamageTaken(int damageTaken, int max public static double calculateDurabilityFromRemaining(int remainingDurability, int maxDurability) { return (double) (maxDurability - remainingDurability) / maxDurability; } - - public static @Nullable EnumDyeColor getDyeColorFromARGB(int color) { - if (color == -1) return null; - - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { - if (color == dyeColor.colorValue) { - return dyeColor; - } - } - - return null; - } } diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 0f8abef5cbe..c7126d548b7 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -228,7 +228,7 @@ public List getScannerInfo(EntityPlayer player, World world, Blo } // if (workable.wasShutdown()) { //todo // list.add(new TextComponentTranslation("behavior.tricorder.machine_power_loss").setStyle(new - // Style().setColor(TextFormatting.RED))); + // Style().setInInt(TextFormatting.RED))); // } energyCost += 400; if (workable.getMaxProgress() > 0) { diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 9a952af1a76..b56ad1319fc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -33,15 +33,21 @@ import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.IntValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static gregtech.api.cover.CoverWithUI.UI_TITLE_COLOR; +import static gregtech.api.util.ColorUtil.*; + public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, IItemNameProvider, IMouseEventHandler { @@ -56,41 +62,79 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager newColor -> setColorOrdinal(usedStack, newColor)); guiSyncManager.syncValue("color", 0, colorSync); BooleanSyncValue arbgSync = SyncHandlers.bool(() -> usesARGB(usedStack), bool -> useARGB(usedStack, bool)); - guiSyncManager.syncValue("uses_argb", arbgSync); + IntSyncValue argb = SyncHandlers.intNumber(() -> getColorInt(usedStack), + newColor -> setColor(usedStack, newColor)); + guiSyncManager.syncValue("argb", 0, argb); - ModularPanel panel = GTGuis.createPanel(usedStack, 176, 120); // noinspection SpellCheckingInspection - panel.child(SlotGroupWidget.builder() - .matrix("SCCCCCCCC", - "CCCCCCCC") - .key('S', new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == -1, - $ -> { - colorSync.setIntValue(-1); - panel.closeIfOpen(true); - })) - .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) - .key('C', index -> { - EnumDyeColor color = EnumDyeColor.values()[index]; - return new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic(() -> colorSync.getIntValue() == index, - $ -> { - colorSync.setIntValue(index); - panel.closeIfOpen(true); - })) - .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); - }) - .build()); - - return panel; + return GTGuis.createPanel(usedStack, 176, 120) + .child(Flow.row() + .pos(4, 4) + .coverChildrenWidth() + .height(16) + .child(new ItemDrawable(usedStack).asWidget().size(16).marginRight(4)) + .child(IKey.lang("metaitem.spray.creative.name_base") + .color(UI_TITLE_COLOR) + .asWidget().heightRel(1.0f))) + .child(SlotGroupWidget.builder() + .matrix("SCCCCCCCC", + "CCCCCCCC") + .key('S', new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic( + () -> colorSync.getIntValue() == -1 && !arbgSync.getBoolValue(), + $ -> { + if (!arbgSync.getBoolValue()) colorSync.setIntValue(-1); + })) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) + .asIcon() + .margin(2)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) + .key('C', index -> { + EnumDyeColor color = EnumDyeColor.values()[index]; + return new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic( + () -> colorSync.getIntValue() == index && !arbgSync.getBoolValue(), + $ -> { + if (!arbgSync.getBoolValue()) colorSync.setIntValue(index); + })) + .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) + .asIcon() + .margin(2)) + .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); + }) + .build() + .left(4) + .top(24)) + .child(Flow.row() + .left(4) + .top(24 + 18 * 2 + 8) + .coverChildren() + .child(new ToggleButton() + .size(18) + .value(arbgSync)) + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(new IntValue.Dynamic( + () -> ARGBHelper.RED.getFromInt(argb.getIntValue()), + newR -> argb.setIntValue( + ARGBHelper.RED.setInInt(argb.getIntValue(), newR))))) + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(new IntValue.Dynamic( + () -> ARGBHelper.GREEN.getFromInt(argb.getIntValue()), + newG -> argb.setIntValue( + ARGBHelper.GREEN.setInInt(argb.getIntValue(), newG))))) + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(new IntValue.Dynamic( + () -> ARGBHelper.BLUE.getFromInt(argb.getIntValue()), + newB -> argb.setIntValue( + ARGBHelper.BLUE.setInInt(argb.getIntValue(), newB)))))); } @Override @@ -101,14 +145,14 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager if (color < 0 || color > 15) return null; return EnumDyeColor.values()[color]; } + return null; } @Override public int getColorInt(@NotNull ItemStack sprayCan) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); - return tag.hasKey(NBT_KEY_USESARGB, Constants.NBT.TAG_INT) ? tag.getInteger(NBT_KEY_ARGB_COLOR) : - super.getColorInt(sprayCan); + return tag.getBoolean(NBT_KEY_USESARGB) ? tag.getInteger(NBT_KEY_ARGB_COLOR) : super.getColorInt(sprayCan); } public static void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { @@ -134,8 +178,14 @@ public static void useARGB(@NotNull ItemStack sprayCan, boolean bool) { @Override public int getItemStackColor(ItemStack sprayCan, int tintIndex) { - EnumDyeColor color = getColor(sprayCan); - return color != null && tintIndex == 1 ? color.colorValue : 0xFFFFFF; + if (tintIndex != 1) return 0xFFFFFF; + + if (usesARGB(sprayCan)) { + return getColorInt(sprayCan); + } else { + EnumDyeColor color = getColor(sprayCan); + return color != null ? color.colorValue : 0xFFFFFF; + } } @Override diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index fa613f6ba6e..7c042f528d1 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -331,6 +331,7 @@ metaitem.shape.extruder.rotor.tooltip=Extruder Shape for making Rotors metaitem.spray.empty.name=Spray Can (Empty) metaitem.spray.empty.tooltip=Can be filled with sprays of various colors metaitem.spray.creative.name=Creative Spray Can (%s) +metaitem.spray.creative.name_base=Creative Spray Can metaitem.spray.creative.solvent=Solvent metaitem.spray.creative.white=White metaitem.spray.creative.orange=Orange From ef55e119fe586a65b238125ebe8c11bd573d672c Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 20:08:48 -0400 Subject: [PATCH 080/109] Use `onItemUseFirst` instead of `onItemUse` for spraying --- .../items/behaviors/spray/AbstractSprayBehavior.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index d5a5addfc96..28a2a84dd19 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -12,7 +12,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; @@ -100,15 +99,15 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { } @Override - public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, - EnumFacing facing, float hitX, float hitY, float hitZ) { + public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, + float hitY, float hitZ, EnumHand hand) { ItemStack sprayCan = player.getHeldItem(hand); - EnumActionResult result = spray(player, world, pos, facing, sprayCan); + EnumActionResult result = spray(player, world, pos, side, sprayCan); if (hasSpraySound(sprayCan) && result == EnumActionResult.SUCCESS) { world.playSound(null, player.posX, player.posY, player.posZ, getSpraySound(sprayCan), SoundCategory.PLAYERS, 1.0f, 1.0f); } - return ActionResult.newResult(result, sprayCan); + return result; } protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, @@ -120,12 +119,12 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block } if (player.isSneaking()) { - int color = getColorInt(sprayCan); if (world.getBlockState(pos).getBlock() instanceof BlockPipeblockPipe) { RayTraceResult hitResult = blockPipe.getServerCollisionRayTrace(player, pos, world); if (hitResult != null) { EnumFacing hitSide = CoverRayTracer.determineGridSideHit(hitResult); IPipeTile firstPipe = blockPipe.getPipeTileEntity(world, pos); + int color = getColorInt(sprayCan); if (hitSide != null && firstPipe != null && firstPipe.isConnected(hitSide) && (firstPipe.isPainted() ? firstPipe.getPaintingColor() != color : color != -1)) { traversePipes(firstPipe, hitSide, player, sprayCan, color); From f8a5c0b3a21f15c9bc7fa46a914adb5f6242f98d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 20:10:30 -0400 Subject: [PATCH 081/109] Undo accidental renaming --- .../java/gregtech/common/items/behaviors/TricorderBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index c7126d548b7..0f8abef5cbe 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -228,7 +228,7 @@ public List getScannerInfo(EntityPlayer player, World world, Blo } // if (workable.wasShutdown()) { //todo // list.add(new TextComponentTranslation("behavior.tricorder.machine_power_loss").setStyle(new - // Style().setInInt(TextFormatting.RED))); + // Style().setColor(TextFormatting.RED))); // } energyCost += 400; if (workable.getMaxProgress() > 0) { From 5efbdcea994bb1a2a5ab7f854b52e868c5d4a1e2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 20:46:53 -0400 Subject: [PATCH 082/109] Add a couple methods to ColorUtil --- src/main/java/gregtech/api/util/ColorUtil.java | 13 +++++++++++++ .../behaviors/spray/CreativeSprayBehavior.java | 1 + 2 files changed, 14 insertions(+) diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java index e40cd2692d4..9a046103fbf 100644 --- a/src/main/java/gregtech/api/util/ColorUtil.java +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -12,6 +12,11 @@ public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, return (r << 16) | (g << 8) | b; } + public static int combineARGB(@Range(from = 0, to = 255) int a, @Range(from = 0, to = 255) int r, + @Range(from = 0, to = 255) int g, @Range(from = 0, to = 255) int b) { + return (a << 24) | (r << 16) | (g << 8) | b; + } + public static @Nullable EnumDyeColor getDyeColorFromRGB(int color) { if (color == -1) return null; @@ -48,5 +53,13 @@ public enum ARGBHelper { public int setInInt(int originalARGB, @Range(from = 0, to = 0xFF) int replacementColor) { return (originalARGB & invertedOverlay) | (replacementColor << shift); } + + public int addInInt(int originalARGB, @Range(from = 0, to = 0xFF) int addingColor) { + return setInInt(originalARGB, (getFromInt(originalARGB) + addingColor) & 0xFF); + } + + public int subtractFromInt(int originalARGB, @Range(from = 0, to = 0xFF) int subtractingColor) { + return setInInt(originalARGB, (getFromInt(originalARGB) - subtractingColor) & 0xFF); + } } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index b56ad1319fc..641555f56e0 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -107,6 +107,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .build() .left(4) .top(24)) + .child(Flow.column()) .child(Flow.row() .left(4) .top(24 + 18 * 2 + 8) From 71e7b1bde6f030b19a745b47a21b0394945a99ec Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 22:00:39 -0400 Subject: [PATCH 083/109] Simplify item stack color method --- .../items/behaviors/spray/CreativeSprayBehavior.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 641555f56e0..c16dd94313b 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -179,14 +179,7 @@ public static void useARGB(@NotNull ItemStack sprayCan, boolean bool) { @Override public int getItemStackColor(ItemStack sprayCan, int tintIndex) { - if (tintIndex != 1) return 0xFFFFFF; - - if (usesARGB(sprayCan)) { - return getColorInt(sprayCan); - } else { - EnumDyeColor color = getColor(sprayCan); - return color != null ? color.colorValue : 0xFFFFFF; - } + return tintIndex == 1 ? getColorInt(sprayCan) : 0xFFFFFF; } @Override From f6d114ba67e47d6a4e094ed490eb8894a57764dc Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 22:01:01 -0400 Subject: [PATCH 084/109] Add slider widgets for RGB mode --- .../java/gregtech/api/util/ColorUtil.java | 4 + .../spray/CreativeSprayBehavior.java | 155 ++++++++++++------ 2 files changed, 105 insertions(+), 54 deletions(-) diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java index 9a046103fbf..a52fb58be7d 100644 --- a/src/main/java/gregtech/api/util/ColorUtil.java +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -54,6 +54,10 @@ public int setInInt(int originalARGB, @Range(from = 0, to = 0xFF) int replacemen return (originalARGB & invertedOverlay) | (replacementColor << shift); } + public int setInInt(@Range(from = 0, to = 0xFF) int color) { + return color << shift; + } + public int addInInt(int originalARGB, @Range(from = 0, to = 0xFF) int addingColor) { return setInInt(originalARGB, (getFromInt(originalARGB) + addingColor) & 0xFF); } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index c16dd94313b..c4715ca101e 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -32,12 +32,15 @@ import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.DoubleValue; import com.cleanroommc.modularui.value.IntValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.SliderWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; @@ -45,6 +48,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.function.BooleanSupplier; + import static gregtech.api.cover.CoverWithUI.UI_TITLE_COLOR; import static gregtech.api.util.ColorUtil.*; @@ -61,13 +66,13 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager IntSyncValue colorSync = SyncHandlers.intNumber(() -> getColorOrdinal(usedStack), newColor -> setColorOrdinal(usedStack, newColor)); guiSyncManager.syncValue("color", 0, colorSync); - BooleanSyncValue arbgSync = SyncHandlers.bool(() -> usesARGB(usedStack), bool -> useARGB(usedStack, bool)); - IntSyncValue argb = SyncHandlers.intNumber(() -> getColorInt(usedStack), + BooleanSyncValue usesARGBSync = SyncHandlers.bool(() -> usesARGB(usedStack), bool -> useARGB(usedStack, bool)); + IntSyncValue argbColorSync = SyncHandlers.intNumber(() -> getColorInt(usedStack), newColor -> setColor(usedStack, newColor)); - guiSyncManager.syncValue("argb", 0, argb); + guiSyncManager.syncValue("argbColor", 0, argbColorSync); // noinspection SpellCheckingInspection - return GTGuis.createPanel(usedStack, 176, 120) + return GTGuis.createPanel(usedStack, 175, 175) .child(Flow.row() .pos(4, 4) .coverChildrenWidth() @@ -82,9 +87,9 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .key('S', new ToggleButton() .size(18) .value(new BoolValue.Dynamic( - () -> colorSync.getIntValue() == -1 && !arbgSync.getBoolValue(), + () -> colorSync.getIntValue() == -1 && !usesARGBSync.getBoolValue(), $ -> { - if (!arbgSync.getBoolValue()) colorSync.setIntValue(-1); + if (!usesARGBSync.getBoolValue()) colorSync.setIntValue(-1); })) .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) .asIcon() @@ -95,9 +100,9 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager return new ToggleButton() .size(18) .value(new BoolValue.Dynamic( - () -> colorSync.getIntValue() == index && !arbgSync.getBoolValue(), + () -> colorSync.getIntValue() == index && !usesARGBSync.getBoolValue(), $ -> { - if (!arbgSync.getBoolValue()) colorSync.setIntValue(index); + if (!usesARGBSync.getBoolValue()) colorSync.setIntValue(index); })) .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) .asIcon() @@ -107,35 +112,75 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .build() .left(4) .top(24)) - .child(Flow.column()) - .child(Flow.row() - .left(4) + .child(Flow.column() + .margin(4, 0) .top(24 + 18 * 2 + 8) - .coverChildren() + .coverChildrenHeight() + .expanded() + .crossAxisAlignment(Alignment.CrossAxis.START) .child(new ToggleButton() .size(18) - .value(arbgSync)) - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(new IntValue.Dynamic( - () -> ARGBHelper.RED.getFromInt(argb.getIntValue()), - newR -> argb.setIntValue( - ARGBHelper.RED.setInInt(argb.getIntValue(), newR))))) - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(new IntValue.Dynamic( - () -> ARGBHelper.GREEN.getFromInt(argb.getIntValue()), - newG -> argb.setIntValue( - ARGBHelper.GREEN.setInInt(argb.getIntValue(), newG))))) - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(new IntValue.Dynamic( - () -> ARGBHelper.BLUE.getFromInt(argb.getIntValue()), - newB -> argb.setIntValue( - ARGBHelper.BLUE.setInInt(argb.getIntValue(), newB)))))); + .value(usesARGBSync)) + .child(Flow.row() + .coverChildrenHeight() + .expanded() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.RED, argbColorSync, + usesARGBSync::getBoolValue))) + .child(new SliderWidget() + .width(100) + .bounds(0.0D, 255.0D) + .value(createRGBDoubleValue(ARGBHelper.RED, argbColorSync, + usesARGBSync::getBoolValue)))) + .child(Flow.row() + .coverChildrenHeight() + .expanded() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.GREEN, argbColorSync, + usesARGBSync::getBoolValue))) + .child(new SliderWidget() + .width(100) + .bounds(0.0D, 255.0D) + .value(createRGBDoubleValue(ARGBHelper.GREEN, argbColorSync, + usesARGBSync::getBoolValue)))) + .child(Flow.row() + .coverChildrenHeight() + .expanded() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.BLUE, argbColorSync, + usesARGBSync::getBoolValue))) + .child(new SliderWidget() + .width(100) + .bounds(0.0D, 255.0D) + .value(createRGBDoubleValue(ARGBHelper.BLUE, argbColorSync, + usesARGBSync::getBoolValue))))); + } + + private static IntValue.Dynamic createRGBIntValue(@NotNull ARGBHelper helper, @NotNull IntSyncValue argbSync, + @NotNull BooleanSupplier allowSetting) { + return new IntValue.Dynamic(() -> helper.getFromInt(argbSync.getIntValue()), + newSingleColor -> { + if (allowSetting.getAsBoolean()) { + argbSync.setIntValue(helper.setInInt(argbSync.getIntValue(), newSingleColor)); + } + }); + } + + private static DoubleValue.Dynamic createRGBDoubleValue(@NotNull ARGBHelper helper, + @NotNull IntSyncValue argbSync, + @NotNull BooleanSupplier allowSetting) { + return new DoubleValue.Dynamic(() -> helper.getFromInt(argbSync.getIntValue()), + newSingleColor -> { + if (allowSetting.getAsBoolean()) { + argbSync.setIntValue(helper.setInInt(argbSync.getIntValue(), (int) newSingleColor)); + } + }); } @Override @@ -206,24 +251,26 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla ColoredBlockContainer container = ColoredBlockContainer.getContainer(world, pos, facing, playerClient); - if (usesARGB(sprayCan) && container.supportsARGB() && - !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { - int color = container.getColorInt(world, pos, facing, playerClient); - if (color != -1) { - setColor(sprayCan, color); - sendToServer(hand, buf -> buf - .writeByte(1) - .writeInt(color)); - return; - } - } else if (!container.colorMatches(world, pos, facing, playerClient, getColor(sprayCan))) { - EnumDyeColor color = container.getColor(world, pos, facing, playerClient); - if (color != null) { - setColor(sprayCan, color); - sendToServer(hand, buf -> buf - .writeByte(2) - .writeByte(color.ordinal())); - return; + if (container.isValid(world, pos, facing, playerClient)) { + if (usesARGB(sprayCan) && container.supportsARGB() && + !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { + int color = container.getColorInt(world, pos, facing, playerClient); + if (color != -1) { + setColor(sprayCan, color); + sendToServer(hand, buf -> buf + .writeByte(1) + .writeInt(color)); + return; + } + } else if (!container.colorMatches(world, pos, facing, playerClient, getColor(sprayCan))) { + EnumDyeColor color = container.getColor(world, pos, facing, playerClient); + if (color != null) { + setColor(sprayCan, color); + sendToServer(hand, buf -> buf + .writeByte(2) + .writeByte(color.ordinal())); + return; + } } } } @@ -238,8 +285,8 @@ public void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPla @NotNull EnumHand hand, @NotNull ItemStack sprayCan) { switch (buf.readByte()) { case 0 -> MetaItemGuiFactory.open(playerServer, EnumHand.MAIN_HAND); - case 1 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); - case 2 -> setColor(sprayCan, buf.readInt()); + case 1 -> setColor(sprayCan, buf.readInt()); + case 2 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); } } } From 81cbeaf771ef6a8205338d59404e376d3779d7a6 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 23 Aug 2025 22:13:09 -0400 Subject: [PATCH 085/109] Put hex color in item name when in RGB mode --- .../items/behaviors/spray/CreativeSprayBehavior.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index c4715ca101e..54b8954346c 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -229,9 +229,15 @@ public int getItemStackColor(ItemStack sprayCan, int tintIndex) { @Override public String getItemStackDisplayName(ItemStack sprayCan, String unlocalizedName) { - EnumDyeColor color = getColor(sprayCan); - String colorString = color == null ? I18n.format("metaitem.spray.creative.solvent") : - I18n.format("metaitem.spray.creative." + color); + String colorString; + if (usesARGB(sprayCan)) { + colorString = String.format("0x%06X", getColorInt(sprayCan) & 0xFFFFFF); + } else { + EnumDyeColor color = getColor(sprayCan); + colorString = color == null ? I18n.format("metaitem.spray.creative.solvent") : + I18n.format("metaitem.spray.creative." + color); + } + return I18n.format(unlocalizedName, colorString); } From 95ad95282cd7cabc1f870a8d710b8aaa651018c7 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 24 Aug 2025 19:38:06 -0400 Subject: [PATCH 086/109] Use tabs to separate normal and RGB mode --- .../java/gregtech/api/mui/GTGuiTextures.java | 1 + .../spray/CreativeSprayBehavior.java | 269 +++++++++++------- .../resources/assets/gregtech/lang/en_us.lang | 2 + .../textures/gui/widget/rgb_gradient.png | Bin 0 -> 479 bytes 4 files changed, 170 insertions(+), 102 deletions(-) create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/rgb_gradient.png diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index d1a46722ba4..5f8372d031b 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -643,6 +643,7 @@ private static String id(String path) { "textures/gui/progress_bar/progress_bar_fluid_rig_depletion.png", 190, 14); // MISC + public static final UITexture RGB_GRADIENT = fullImage("textures/gui/widget/rgb_gradient.png"); public static void init() {/**/} diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 54b8954346c..c6d68fc8ce3 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -5,8 +5,10 @@ import gregtech.api.items.metaitem.stats.IItemColorProvider; import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.items.metaitem.stats.IMouseEventHandler; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.factory.MetaItemGuiFactory; +import gregtech.api.mui.sync.PagedWidgetSyncHandler; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; @@ -29,10 +31,10 @@ import codechicken.lib.raytracer.RayTracer; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.DoubleValue; import com.cleanroommc.modularui.value.IntValue; @@ -40,6 +42,8 @@ import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.PageButton; +import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SliderWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; @@ -49,16 +53,16 @@ import org.jetbrains.annotations.Nullable; import java.util.function.BooleanSupplier; +import java.util.function.IntConsumer; -import static gregtech.api.cover.CoverWithUI.UI_TITLE_COLOR; import static gregtech.api.util.ColorUtil.*; public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, IItemNameProvider, IMouseEventHandler { private static final String NBT_KEY_COLOR = "color"; - private static final String NBT_KEY_USESARGB = "usesARGB"; - private static final String NBT_KEY_ARGB_COLOR = "argbColor"; + private static final String NBT_KEY_USES_RGB = "usesRGB"; + private static final String NBT_KEY_RGB_COLOR = "rgbColor"; @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { @@ -66,100 +70,119 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager IntSyncValue colorSync = SyncHandlers.intNumber(() -> getColorOrdinal(usedStack), newColor -> setColorOrdinal(usedStack, newColor)); guiSyncManager.syncValue("color", 0, colorSync); - BooleanSyncValue usesARGBSync = SyncHandlers.bool(() -> usesARGB(usedStack), bool -> useARGB(usedStack, bool)); - IntSyncValue argbColorSync = SyncHandlers.intNumber(() -> getColorInt(usedStack), + BooleanSyncValue usesRGBSync = SyncHandlers.bool(() -> usesRGB(usedStack), bool -> useRGB(usedStack, bool)); + guiSyncManager.syncValue("usesRGB", 0, usesRGBSync); + // Doesn't use getColorInt because the slider widgets take a moment to update so it ended up showing the normal + // can colors when you switched to RGB mode. + IntSyncValue rgbColorSync = SyncHandlers.intNumber( + () -> GTUtility.getOrCreateNbtCompound(usedStack).getInteger(NBT_KEY_RGB_COLOR), newColor -> setColor(usedStack, newColor)); - guiSyncManager.syncValue("argbColor", 0, argbColorSync); + guiSyncManager.syncValue("rgbColor", 0, rgbColorSync); - // noinspection SpellCheckingInspection - return GTGuis.createPanel(usedStack, 175, 175) + var pageController = new InterceptedPageController(page -> usesRGBSync.setBoolValue(page == 1)); + guiSyncManager.syncValue("page_controller", 0, new PagedWidgetSyncHandler(pageController)); + + return GTGuis.createPanel(usedStack, 176, 95) .child(Flow.row() - .pos(4, 4) - .coverChildrenWidth() - .height(16) - .child(new ItemDrawable(usedStack).asWidget().size(16).marginRight(4)) - .child(IKey.lang("metaitem.spray.creative.name_base") - .color(UI_TITLE_COLOR) - .asWidget().heightRel(1.0f))) - .child(SlotGroupWidget.builder() - .matrix("SCCCCCCCC", - "CCCCCCCC") - .key('S', new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic( - () -> colorSync.getIntValue() == -1 && !usesARGBSync.getBoolValue(), - $ -> { - if (!usesARGBSync.getBoolValue()) colorSync.setIntValue(-1); - })) - .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) - .key('C', index -> { - EnumDyeColor color = EnumDyeColor.values()[index]; - return new ToggleButton() - .size(18) - .value(new BoolValue.Dynamic( - () -> colorSync.getIntValue() == index && !usesARGBSync.getBoolValue(), - $ -> { - if (!usesARGBSync.getBoolValue()) colorSync.setIntValue(index); - })) - .overlay(new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) - .asIcon() - .margin(2)) - .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); - }) - .build() - .left(4) - .top(24)) - .child(Flow.column() - .margin(4, 0) - .top(24 + 18 * 2 + 8) + .widthRel(1.0f) + .leftRel(0.5f) + .margin(3, 0) .coverChildrenHeight() - .expanded() - .crossAxisAlignment(Alignment.CrossAxis.START) - .child(new ToggleButton() - .size(18) - .value(usesARGBSync)) - .child(Flow.row() - .coverChildrenHeight() - .expanded() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.RED, argbColorSync, - usesARGBSync::getBoolValue))) - .child(new SliderWidget() - .width(100) - .bounds(0.0D, 255.0D) - .value(createRGBDoubleValue(ARGBHelper.RED, argbColorSync, - usesARGBSync::getBoolValue)))) - .child(Flow.row() - .coverChildrenHeight() - .expanded() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.GREEN, argbColorSync, - usesARGBSync::getBoolValue))) - .child(new SliderWidget() - .width(100) - .bounds(0.0D, 255.0D) - .value(createRGBDoubleValue(ARGBHelper.GREEN, argbColorSync, - usesARGBSync::getBoolValue)))) - .child(Flow.row() - .coverChildrenHeight() - .expanded() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.BLUE, argbColorSync, - usesARGBSync::getBoolValue))) - .child(new SliderWidget() - .width(100) - .bounds(0.0D, 255.0D) - .value(createRGBDoubleValue(ARGBHelper.BLUE, argbColorSync, - usesARGBSync::getBoolValue))))); + .topRel(0.0f, 3, 1.0f) + .child(new PageButton(0, pageController) + .tab(GuiTextures.TAB_TOP, 0) + .overlay(new ItemDrawable(MetaItems.SPRAY_EMPTY.getStackForm()) + .asIcon() + .size(16)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.mode.normal"))) + .child(new PageButton(1, pageController) + .tab(GuiTextures.TAB_TOP, 0) + .overlay(GTGuiTextures.RGB_GRADIENT.asIcon() + .size(16)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.mode.rgb")))) + .child(IKey.lang("metaitem.spray.creative.name_base") + .asWidget() + .left(7) + .top(7)) + .child(new DefaultPagePagedWidget<>(usesRGBSync.getIntValue()) + .margin(7, 7, 22, 7) + .widthRel(1.0f) + .heightRel(1.0f) + .controller(pageController) + .addPage(SlotGroupWidget.builder() + .matrix("SCCCCCCCC", + "CCCCCCCC") + .key('S', new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic( + () -> colorSync.getIntValue() == -1 && !usesRGBSync.getBoolValue(), + $ -> { + if (!usesRGBSync.getBoolValue()) colorSync.setIntValue(-1); + })) + .overlay(new ItemDrawable(MetaItems.SPRAY_SOLVENT.getStackForm()) + .asIcon() + .size(16)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.solvent"))) + .key('C', index -> { + EnumDyeColor color = EnumDyeColor.values()[index]; + return new ToggleButton() + .size(18) + .value(new BoolValue.Dynamic( + () -> colorSync.getIntValue() == index && + !usesRGBSync.getBoolValue(), + $ -> { + if (!usesRGBSync.getBoolValue()) colorSync.setIntValue(index); + })) + .overlay( + new ItemDrawable(MetaItems.SPRAY_CAN_DYES.get(color).getStackForm()) + .asIcon() + .size(16)) + .addTooltipLine(IKey.lang("metaitem.spray.creative." + color)); + }) + .build() + .alignY(0.5f)) + .addPage(Flow.column() + .widthRel(1.0f) + .heightRel(1.0f) + .child(Flow.row() + .widthRel(1.0f) + .coverChildrenHeight() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.RED, rgbColorSync, + usesRGBSync::getBoolValue))) + .child(new SliderWidget() + .width(132) + .bounds(0.0D, 255.0d) + .value(createRGBDoubleValue(ARGBHelper.RED, rgbColorSync, + usesRGBSync::getBoolValue)))) + .child(Flow.row() + .widthRel(1.0f) + .coverChildrenHeight() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.GREEN, rgbColorSync, + usesRGBSync::getBoolValue))) + .child(new SliderWidget() + .width(132) + .bounds(0.0D, 255.0d) + .value(createRGBDoubleValue(ARGBHelper.GREEN, rgbColorSync, + usesRGBSync::getBoolValue)))) + .child(Flow.row() + .widthRel(1.0f) + .coverChildrenHeight() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(createRGBIntValue(ARGBHelper.BLUE, rgbColorSync, + usesRGBSync::getBoolValue))) + .child(new SliderWidget() + .width(132) + .bounds(0.0D, 255.0d) + .value(createRGBDoubleValue(ARGBHelper.BLUE, rgbColorSync, + usesRGBSync::getBoolValue)))))); } private static IntValue.Dynamic createRGBIntValue(@NotNull ARGBHelper helper, @NotNull IntSyncValue argbSync, @@ -198,7 +221,7 @@ private static DoubleValue.Dynamic createRGBDoubleValue(@NotNull ARGBHelper help @Override public int getColorInt(@NotNull ItemStack sprayCan) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); - return tag.getBoolean(NBT_KEY_USESARGB) ? tag.getInteger(NBT_KEY_ARGB_COLOR) : super.getColorInt(sprayCan); + return tag.getBoolean(NBT_KEY_USES_RGB) ? tag.getInteger(NBT_KEY_RGB_COLOR) : super.getColorInt(sprayCan); } public static void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { @@ -211,15 +234,15 @@ public static void setColorOrdinal(@NotNull ItemStack sprayCan, int ordinal) { } public static void setColor(@NotNull ItemStack sprayCan, int argbColor) { - GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_ARGB_COLOR, argbColor); + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_RGB_COLOR, argbColor); } - public static boolean usesARGB(@NotNull ItemStack sprayCan) { - return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(NBT_KEY_USESARGB); + public static boolean usesRGB(@NotNull ItemStack sprayCan) { + return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(NBT_KEY_USES_RGB); } - public static void useARGB(@NotNull ItemStack sprayCan, boolean bool) { - GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(NBT_KEY_USESARGB, bool); + public static void useRGB(@NotNull ItemStack sprayCan, boolean bool) { + GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(NBT_KEY_USES_RGB, bool); } @Override @@ -230,7 +253,7 @@ public int getItemStackColor(ItemStack sprayCan, int tintIndex) { @Override public String getItemStackDisplayName(ItemStack sprayCan, String unlocalizedName) { String colorString; - if (usesARGB(sprayCan)) { + if (usesRGB(sprayCan)) { colorString = String.format("0x%06X", getColorInt(sprayCan) & 0xFFFFFF); } else { EnumDyeColor color = getColor(sprayCan); @@ -258,7 +281,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla playerClient); if (container.isValid(world, pos, facing, playerClient)) { - if (usesARGB(sprayCan) && container.supportsARGB() && + if (usesRGB(sprayCan) && container.supportsARGB() && !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { int color = container.getColorInt(world, pos, facing, playerClient); if (color != -1) { @@ -295,4 +318,46 @@ public void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPla case 2 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); } } + + private static class InterceptedPageController extends PagedWidget.Controller { + + @NotNull + private final IntConsumer onPageSwitch; + + public InterceptedPageController(@NotNull IntConsumer onPageSwitch) { + this.onPageSwitch = onPageSwitch; + } + + @Override + public void setPage(int page) { + super.setPage(page); + onPageSwitch.accept(getActivePageIndex()); + } + + @Override + public void nextPage() { + super.nextPage(); + onPageSwitch.accept(getActivePageIndex()); + } + + @Override + public void previousPage() { + super.previousPage(); + onPageSwitch.accept(getActivePageIndex()); + } + } + + private static class DefaultPagePagedWidget> extends PagedWidget { + + private final int defaultPage; + + public DefaultPagePagedWidget(int defaultPage) { + this.defaultPage = defaultPage; + } + + @Override + public void afterInit() { + setPage(defaultPage); + } + } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 7c042f528d1..fd8e5f3cb48 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -332,6 +332,8 @@ metaitem.spray.empty.name=Spray Can (Empty) metaitem.spray.empty.tooltip=Can be filled with sprays of various colors metaitem.spray.creative.name=Creative Spray Can (%s) metaitem.spray.creative.name_base=Creative Spray Can +metaitem.spray.creative.mode.normal=Normal Mode +metaitem.spray.creative.mode.rgb=RGB Mode metaitem.spray.creative.solvent=Solvent metaitem.spray.creative.white=White metaitem.spray.creative.orange=Orange diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/rgb_gradient.png b/src/main/resources/assets/gregtech/textures/gui/widget/rgb_gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..22c5b25b65b16a7df957fa7db1923e5e18d0ac49 GIT binary patch literal 479 zcmeAS@N?(olHy`uVBq!ia0vp^4j?SR1SCsmTb%+@3dtTpz6=aiY77hwEes65fI+O||oXmkdtOv{Qyx*TRyO`gP?eScPjR_OiB1yra&xy!@Q8m<=Zla z=Bq%jsFt`!l%yn}eUBa;v#Ln}jLD+2><0|Ou#@k3JvMMG|W uN@iLmZVj4CCoTYL(16=el9`)YT#}eufLl-9h7I*VJq(_%elF{r5}E*&HjZWh literal 0 HcmV?d00001 From 7b99a782141f1357b02f34c8d915098fe78633c8 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 24 Aug 2025 21:06:24 -0400 Subject: [PATCH 087/109] Make the slider have a background (it changes color!) Fix a small error in isolateWithFullAlpha and add javadocs --- .../mui/drawable/DynamicColorRectangle.java | 31 ++++++ .../java/gregtech/api/util/ColorUtil.java | 47 ++++++++-- .../spray/CreativeSprayBehavior.java | 94 +++++++------------ .../resources/assets/gregtech/lang/en_us.lang | 3 + 4 files changed, 107 insertions(+), 68 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/drawable/DynamicColorRectangle.java diff --git a/src/main/java/gregtech/api/mui/drawable/DynamicColorRectangle.java b/src/main/java/gregtech/api/mui/drawable/DynamicColorRectangle.java new file mode 100644 index 00000000000..4c372647dc6 --- /dev/null +++ b/src/main/java/gregtech/api/mui/drawable/DynamicColorRectangle.java @@ -0,0 +1,31 @@ +package gregtech.api.mui.drawable; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.drawable.GuiDraw; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.Color; +import org.jetbrains.annotations.NotNull; + +import java.util.function.IntSupplier; + +public class DynamicColorRectangle implements IDrawable { + + @NotNull + private final IntSupplier colorSupplier; + + public DynamicColorRectangle(@NotNull IntSupplier colorSupplier) { + this.colorSupplier = colorSupplier; + } + + @Override + public void draw(GuiContext context, int x0, int y0, int width, int height, WidgetTheme widgetTheme) { + if (canApplyTheme()) { + Color.setGlColor(widgetTheme.getColor()); + } else { + Color.setGlColorOpaque(Color.WHITE.main); + } + + GuiDraw.drawRect(x0, y0, width, height, colorSupplier.getAsInt()); + } +} diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java index a52fb58be7d..48c910d712b 100644 --- a/src/main/java/gregtech/api/util/ColorUtil.java +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -46,24 +46,51 @@ public enum ARGBHelper { this.shift = shift; } - public @Range(from = 0, to = 0xFF) int getFromInt(int sourceARGB) { - return (sourceARGB >> shift) & 0xFF; + /** + * Isolate this channel as an integer from 0 to 255.
+ * Example: {@code GREEN.isolateAndShift(0xDEADBEEF)} will return {@code 0xBE} or {@code 190}. + */ + public @Range(from = 0, to = 0xFF) int isolateAndShift(int value) { + return (value >> shift) & 0xFF; } - public int setInInt(int originalARGB, @Range(from = 0, to = 0xFF) int replacementColor) { - return (originalARGB & invertedOverlay) | (replacementColor << shift); + /** + * Remove the other two colors from the integer encoded ARGB and set the alpha to 255.
+ * Will always return {@code 0xFF000000} if called on {@link #ALPHA}.
+ * Unlike {@link #isolateAndShift(int)}, this will not be between 0 and 255.
+ * Example: {@code GREEN.isolateWithFullAlpha(0xDEADBEEF)} will return {@code 0xFF00BE00} or {@code 4278238720}. + */ + public int isolateWithFullAlpha(int value) { + return (value & overlay) | 0xFF000000; } - public int setInInt(@Range(from = 0, to = 0xFF) int color) { - return color << shift; + /** + * Set the value of this channel in an integer encoded ARGB value. + */ + public int replace(int originalARGB, @Range(from = 0, to = 0xFF) int value) { + return (originalARGB & invertedOverlay) | (value << shift); } - public int addInInt(int originalARGB, @Range(from = 0, to = 0xFF) int addingColor) { - return setInInt(originalARGB, (getFromInt(originalARGB) + addingColor) & 0xFF); + /** + * The same as {@link #replace(int, int)} but will just return the value shifted to this channel. + */ + public int replace(@Range(from = 0, to = 0xFF) int value) { + return value << shift; } - public int subtractFromInt(int originalARGB, @Range(from = 0, to = 0xFF) int subtractingColor) { - return setInInt(originalARGB, (getFromInt(originalARGB) - subtractingColor) & 0xFF); + /** + * Add a value to this channel's value. Can overflow in this channel, but will not affect the other channels. + */ + public int add(int originalARGB, @Range(from = 0, to = 0xFF) int value) { + return replace(originalARGB, (isolateAndShift(originalARGB) + value) & 0xFF); + } + + /** + * Subtract a value from this channel's value. Can underflow in this channel, but will not affect the other + * channels. + */ + public int subtract(int originalARGB, @Range(from = 0, to = 0xFF) int value) { + return replace(originalARGB, (isolateAndShift(originalARGB) - value) & 0xFF); } } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index c6d68fc8ce3..10239933caa 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -7,6 +7,7 @@ import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; +import gregtech.api.mui.drawable.DynamicColorRectangle; import gregtech.api.mui.factory.MetaItemGuiFactory; import gregtech.api.mui.sync.PagedWidgetSyncHandler; import gregtech.api.util.GTUtility; @@ -144,66 +145,43 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .addPage(Flow.column() .widthRel(1.0f) .heightRel(1.0f) - .child(Flow.row() - .widthRel(1.0f) - .coverChildrenHeight() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.RED, rgbColorSync, - usesRGBSync::getBoolValue))) - .child(new SliderWidget() - .width(132) - .bounds(0.0D, 255.0d) - .value(createRGBDoubleValue(ARGBHelper.RED, rgbColorSync, - usesRGBSync::getBoolValue)))) - .child(Flow.row() - .widthRel(1.0f) - .coverChildrenHeight() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.GREEN, rgbColorSync, - usesRGBSync::getBoolValue))) - .child(new SliderWidget() - .width(132) - .bounds(0.0D, 255.0d) - .value(createRGBDoubleValue(ARGBHelper.GREEN, rgbColorSync, - usesRGBSync::getBoolValue)))) - .child(Flow.row() - .widthRel(1.0f) - .coverChildrenHeight() - .child(new TextFieldWidget() - .width(30) - .setNumbers(0, 255) - .value(createRGBIntValue(ARGBHelper.BLUE, rgbColorSync, - usesRGBSync::getBoolValue))) - .child(new SliderWidget() - .width(132) - .bounds(0.0D, 255.0d) - .value(createRGBDoubleValue(ARGBHelper.BLUE, rgbColorSync, - usesRGBSync::getBoolValue)))))); + .child(createColorRow(ARGBHelper.RED, rgbColorSync, usesRGBSync::getBoolValue)) + .child(createColorRow(ARGBHelper.GREEN, rgbColorSync, usesRGBSync::getBoolValue)) + .child(createColorRow(ARGBHelper.BLUE, rgbColorSync, usesRGBSync::getBoolValue)))); } - private static IntValue.Dynamic createRGBIntValue(@NotNull ARGBHelper helper, @NotNull IntSyncValue argbSync, - @NotNull BooleanSupplier allowSetting) { - return new IntValue.Dynamic(() -> helper.getFromInt(argbSync.getIntValue()), - newSingleColor -> { - if (allowSetting.getAsBoolean()) { - argbSync.setIntValue(helper.setInInt(argbSync.getIntValue(), newSingleColor)); - } - }); - } - - private static DoubleValue.Dynamic createRGBDoubleValue(@NotNull ARGBHelper helper, - @NotNull IntSyncValue argbSync, - @NotNull BooleanSupplier allowSetting) { - return new DoubleValue.Dynamic(() -> helper.getFromInt(argbSync.getIntValue()), - newSingleColor -> { - if (allowSetting.getAsBoolean()) { - argbSync.setIntValue(helper.setInInt(argbSync.getIntValue(), (int) newSingleColor)); - } - }); + private static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyncValue rgbColorSync, + @NotNull BooleanSupplier allowSetting) { + return Flow.row() + .widthRel(1.0f) + .coverChildrenHeight() + .child(new TextFieldWidget() + .width(30) + .setNumbers(0, 255) + .value(new IntValue.Dynamic(() -> helper.isolateAndShift(rgbColorSync.getIntValue()), + colorDigit -> { + if (allowSetting.getAsBoolean()) { + int newColor = helper.replace(rgbColorSync.getIntValue(), colorDigit); + rgbColorSync.setIntValue(newColor); + } + }))) + .child(new SliderWidget() + .width(132) + .bounds(0.0D, 255.0d) + .value(new DoubleValue.Dynamic( + () -> (double) helper.isolateAndShift(rgbColorSync.getIntValue()), + colorDigit -> { + if (allowSetting.getAsBoolean()) { + int newColor = helper.replace(rgbColorSync.getIntValue(), (int) colorDigit); + rgbColorSync.setIntValue(newColor); + } + })) + .background( + new DynamicColorRectangle(() -> helper.isolateWithFullAlpha(rgbColorSync.getIntValue())) + .asIcon() + .margin(4, 0) + .height(8)) + .addTooltipLine(IKey.lang("metaitem.spray.creative.tip." + helper.toString().toLowerCase()))); } @Override diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index fd8e5f3cb48..ddb268da417 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -334,6 +334,9 @@ metaitem.spray.creative.name=Creative Spray Can (%s) metaitem.spray.creative.name_base=Creative Spray Can metaitem.spray.creative.mode.normal=Normal Mode metaitem.spray.creative.mode.rgb=RGB Mode +metaitem.spray.creative.tip.red=Red +metaitem.spray.creative.tip.green=Blue +metaitem.spray.creative.tip.blue=Green metaitem.spray.creative.solvent=Solvent metaitem.spray.creative.white=White metaitem.spray.creative.orange=Orange From 34d346f3f2a6970d28d4c1a77671a0a0f1c948ed Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 24 Aug 2025 21:15:38 -0400 Subject: [PATCH 088/109] Remove old and completed TODO --- .../gregtech/api/items/metaitem/stats/IMouseEventHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java index 912a02e90cd..d71a8b87357 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IMouseEventHandler.java @@ -18,7 +18,6 @@ import java.util.function.Consumer; -// TODO: add EnumHand to the methods/support for offhand items /** * Implement on your {@link IItemComponent} to handle mouse events while the corresponding item is selected on the main * hotbar.
From 999ab261fe3192f78afd43f8c21d81aa80bf64fc Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 25 Aug 2025 10:35:03 -0400 Subject: [PATCH 089/109] fix tooltip saying green is blue and blue is green --- src/main/resources/assets/gregtech/lang/en_us.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index ddb268da417..1b4f3e7c123 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -335,8 +335,8 @@ metaitem.spray.creative.name_base=Creative Spray Can metaitem.spray.creative.mode.normal=Normal Mode metaitem.spray.creative.mode.rgb=RGB Mode metaitem.spray.creative.tip.red=Red -metaitem.spray.creative.tip.green=Blue -metaitem.spray.creative.tip.blue=Green +metaitem.spray.creative.tip.green=Green +metaitem.spray.creative.tip.blue=Blue metaitem.spray.creative.solvent=Solvent metaitem.spray.creative.white=White metaitem.spray.creative.orange=Orange From b3b9a72e35f1aa6d5d1b30bdf64630a4a52657ab Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:52:08 -0400 Subject: [PATCH 090/109] Correct small error in ColorUtil javadoc --- src/main/java/gregtech/api/util/ColorUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java index 48c910d712b..69c635ca74a 100644 --- a/src/main/java/gregtech/api/util/ColorUtil.java +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -58,10 +58,10 @@ public enum ARGBHelper { * Remove the other two colors from the integer encoded ARGB and set the alpha to 255.
* Will always return {@code 0xFF000000} if called on {@link #ALPHA}.
* Unlike {@link #isolateAndShift(int)}, this will not be between 0 and 255.
- * Example: {@code GREEN.isolateWithFullAlpha(0xDEADBEEF)} will return {@code 0xFF00BE00} or {@code 4278238720}. + * Example: {@code GREEN.isolateWithFullAlpha(0xDEADBEEF)} will return {@code 0xFF00BE00} or {@code -16728576}. */ public int isolateWithFullAlpha(int value) { - return (value & overlay) | 0xFF000000; + return (value & overlay) | ALPHA.overlay; } /** From 89c6900ca9998cf395576f10e655bcfda67b9382 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:11:57 -0500 Subject: [PATCH 091/109] Formatting --- src/main/java/gregtech/api/util/ColorUtil.java | 4 +++- .../common/items/behaviors/spray/AbstractSprayBehavior.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/util/ColorUtil.java b/src/main/java/gregtech/api/util/ColorUtil.java index 69c635ca74a..993ec3010cb 100644 --- a/src/main/java/gregtech/api/util/ColorUtil.java +++ b/src/main/java/gregtech/api/util/ColorUtil.java @@ -7,6 +7,8 @@ public class ColorUtil { + public static final EnumDyeColor[] DYE_COLORS = EnumDyeColor.values(); + public static int combineRGB(@Range(from = 0, to = 255) int r, @Range(from = 0, to = 255) int g, @Range(from = 0, to = 255) int b) { return (r << 16) | (g << 8) | b; @@ -20,7 +22,7 @@ public static int combineARGB(@Range(from = 0, to = 255) int a, @Range(from = 0, public static @Nullable EnumDyeColor getDyeColorFromRGB(int color) { if (color == -1) return null; - for (EnumDyeColor dyeColor : EnumDyeColor.values()) { + for (EnumDyeColor dyeColor : DYE_COLORS) { if (color == dyeColor.colorValue) { return dyeColor; } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 28a2a84dd19..a4bef4a70ca 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -28,7 +28,8 @@ public abstract class AbstractSprayBehavior implements IItemBehaviour { /** - * Get the color of the spray can. {@code null} = solvent + * Get the color of the spray can.
+ * {@code null} = solvent */ public abstract @Nullable EnumDyeColor getColor(@NotNull ItemStack sprayCan); From 0f79f186b7aa8f0352f5b47a1a0eeead489654d3 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:18:16 -0500 Subject: [PATCH 092/109] Post merge fixes --- src/main/java/gregtech/api/items/metaitem/MetaItem.java | 2 +- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index ce7d083e1aa..b5d83db5a7a 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -21,11 +21,11 @@ import gregtech.api.items.metaitem.stats.IItemContainerItemProvider; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.items.metaitem.stats.IItemMaxStackSizeProvider; +import gregtech.api.items.metaitem.stats.IItemModelDispatcher; import gregtech.api.items.metaitem.stats.IItemNameProvider; import gregtech.api.items.metaitem.stats.IItemUseManager; import gregtech.api.items.metaitem.stats.IMouseEventHandler; import gregtech.api.items.metaitem.stats.ISubItemHandler; -import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.ore.OrePrefix; diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 10239933caa..0d1255cc221 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -36,6 +36,7 @@ import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.DoubleValue; import com.cleanroommc.modularui.value.IntValue; @@ -66,7 +67,7 @@ public class CreativeSprayBehavior extends AbstractSprayBehavior implements Item private static final String NBT_KEY_RGB_COLOR = "rgbColor"; @Override - public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { ItemStack usedStack = guiData.getUsedItemStack(); IntSyncValue colorSync = SyncHandlers.intNumber(() -> getColorOrdinal(usedStack), newColor -> setColorOrdinal(usedStack, newColor)); From 24ef97a7379993f98c8e4eeacb25ef879b0e8c93 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:27:04 -0500 Subject: [PATCH 093/109] Remove custom widgets as updating mui2 solved the reason I needed them --- .../spray/CreativeSprayBehavior.java | 51 ++----------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 0d1255cc221..c5029b54333 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -9,7 +9,6 @@ import gregtech.api.mui.GTGuis; import gregtech.api.mui.drawable.DynamicColorRectangle; import gregtech.api.mui.factory.MetaItemGuiFactory; -import gregtech.api.mui.sync.PagedWidgetSyncHandler; import gregtech.api.util.GTUtility; import gregtech.common.items.MetaItems; @@ -55,7 +54,6 @@ import org.jetbrains.annotations.Nullable; import java.util.function.BooleanSupplier; -import java.util.function.IntConsumer; import static gregtech.api.util.ColorUtil.*; @@ -81,8 +79,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager newColor -> setColor(usedStack, newColor)); guiSyncManager.syncValue("rgbColor", 0, rgbColorSync); - var pageController = new InterceptedPageController(page -> usesRGBSync.setBoolValue(page == 1)); - guiSyncManager.syncValue("page_controller", 0, new PagedWidgetSyncHandler(pageController)); + PagedWidget.Controller pageController = new PagedWidget.Controller(); return GTGuis.createPanel(usedStack, 176, 95) .child(Flow.row() @@ -106,11 +103,13 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .asWidget() .left(7) .top(7)) - .child(new DefaultPagePagedWidget<>(usesRGBSync.getIntValue()) + .child(new PagedWidget<>() .margin(7, 7, 22, 7) .widthRel(1.0f) .heightRel(1.0f) .controller(pageController) + .onPageChange(usesRGBSync::setIntValue) + .initialPage(usesRGBSync.getIntValue()) .addPage(SlotGroupWidget.builder() .matrix("SCCCCCCCC", "CCCCCCCC") @@ -297,46 +296,4 @@ public void handleMouseEventServer(@NotNull PacketBuffer buf, @NotNull EntityPla case 2 -> setColor(sprayCan, EnumDyeColor.values()[buf.readByte()]); } } - - private static class InterceptedPageController extends PagedWidget.Controller { - - @NotNull - private final IntConsumer onPageSwitch; - - public InterceptedPageController(@NotNull IntConsumer onPageSwitch) { - this.onPageSwitch = onPageSwitch; - } - - @Override - public void setPage(int page) { - super.setPage(page); - onPageSwitch.accept(getActivePageIndex()); - } - - @Override - public void nextPage() { - super.nextPage(); - onPageSwitch.accept(getActivePageIndex()); - } - - @Override - public void previousPage() { - super.previousPage(); - onPageSwitch.accept(getActivePageIndex()); - } - } - - private static class DefaultPagePagedWidget> extends PagedWidget { - - private final int defaultPage; - - public DefaultPagePagedWidget(int defaultPage) { - this.defaultPage = defaultPage; - } - - @Override - public void afterInit() { - setPage(defaultPage); - } - } } From dac01228a53bd867917ceffd7b6ac407aef23448 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:37:30 -0500 Subject: [PATCH 094/109] Less privates --- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index c5029b54333..3c82b6c46b2 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -150,7 +150,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .child(createColorRow(ARGBHelper.BLUE, rgbColorSync, usesRGBSync::getBoolValue)))); } - private static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyncValue rgbColorSync, + protected static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyncValue rgbColorSync, @NotNull BooleanSupplier allowSetting) { return Flow.row() .widthRel(1.0f) From 3da35f5852c8f9c205f87a86f13069f00247843c Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:48:04 -0500 Subject: [PATCH 095/109] Fix not being able to recolor plain vanilla blocks --- .../api/color/containers/VanillaColorContainer.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index f4f691b17bf..6dbea336717 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -113,12 +113,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); - for (IProperty prop : state.getPropertyKeys()) { - if (prop.getValueClass() == EnumDyeColor.class) { - return !world.isAirBlock(pos); - } - } - - return false; + Block block = state.getBlock(); + return TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block); } } From 6a8106cf3af80789f64caa74fc40f9718d89ad89 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:48:29 -0500 Subject: [PATCH 096/109] spootless --- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 3c82b6c46b2..5e6338688cc 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -151,7 +151,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager } protected static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyncValue rgbColorSync, - @NotNull BooleanSupplier allowSetting) { + @NotNull BooleanSupplier allowSetting) { return Flow.row() .widthRel(1.0f) .coverChildrenHeight() From 1bf401587d49614bf5c43c3d30033aee7c42b798 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 21 Nov 2025 23:48:47 -0500 Subject: [PATCH 097/109] Return the result of world.setBlockState --- .../api/color/containers/VanillaColorContainer.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 6dbea336717..590324170db 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -53,8 +53,7 @@ public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull En IBlockState newBlockState = TRANSFORMATIONS.get(block) .getDefaultState() .withProperty(PROPERTY_MAP.get(block), newColor); - world.setBlockState(pos, newBlockState); - return true; + return world.setBlockState(pos, newBlockState); } return block.recolorBlock(world, pos, facing, newColor); @@ -70,8 +69,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState newBlockState = TRANSFORMATIONS.inverse() .get(block) .getDefaultState(); - world.setBlockState(pos, newBlockState); - return true; + return world.setBlockState(pos, newBlockState); } else { for (IProperty prop : state.getPropertyKeys()) { if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { From d9ef4cf044f794c53b1cfd0be6ce086c00e55960 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 22 Nov 2025 00:09:17 -0500 Subject: [PATCH 098/109] Unbreak half of the vanilla blocks --- .../api/color/containers/VanillaColorContainer.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 590324170db..0dcb27ea795 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -112,6 +112,17 @@ public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull Enu @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); - return TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block); + + if (TRANSFORMATIONS.containsKey(block) || TRANSFORMATIONS.containsValue(block)) { + return true; + } + + for (IProperty prop : state.getPropertyKeys()) { + if (prop.getValueClass() == EnumDyeColor.class) { + return !world.isAirBlock(pos); + } + } + + return false; } } From 64220b147ea4a703ac4f62a64b821d1376679f10 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 22 Nov 2025 00:12:57 -0500 Subject: [PATCH 099/109] Rename isValid method --- src/main/java/gregtech/api/color/ColoredBlockContainer.java | 6 +++--- .../gregtech/api/color/containers/AE2ColorContainer.java | 4 ++-- .../gregtech/api/color/containers/GTPipeColorContainer.java | 4 ++-- .../gregtech/api/color/containers/MTEColorContainer.java | 4 ++-- .../gregtech/api/color/containers/NullColorContainer.java | 4 ++-- .../api/color/containers/VanillaColorContainer.java | 4 ++-- .../common/items/behaviors/spray/CreativeSprayBehavior.java | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index b67bb103aa3..9e4ce0647d2 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -39,7 +39,7 @@ public static void registerContainer(@NotNull ColoredBlockContainer container) { @NotNull EnumFacing facing, @NotNull EntityPlayer player) { for (ColoredBlockContainer container : CONTAINERS) { - if (container.isValid(world, pos, facing, player)) { + if (container.isBlockValid(world, pos, facing, player)) { return container; } } @@ -57,8 +57,8 @@ public static void registerCEuContainers() { registerContainer(new VanillaColorContainer()); } - public abstract boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player); + public abstract boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player); public abstract boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor); diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index bc91048a358..0197f923446 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -62,8 +62,8 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull } @Override - public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof IColorableTile; } } diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index cb7e8f2cb9b..93b5159964f 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -86,8 +86,8 @@ public boolean supportsARGB() { } @Override - public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof IPipeTile; } } diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index 51d6bdf5f59..24539f0efa3 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -87,8 +87,8 @@ public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull Enu } @Override - public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { MetaTileEntity mte = getMetaTileEntity(world, pos); return mte != null && mte.isValid(); } diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index 72b3ad13a7d..c0d5d7d7216 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -34,8 +34,8 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @Nullabl } @Override - public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, - @NotNull EntityPlayer player) { + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, + @NotNull EntityPlayer player) { return false; } diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 0dcb27ea795..097a759238a 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -108,8 +108,8 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull } @Override - public boolean isValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 5e6338688cc..c7771b5535d 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -258,7 +258,7 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla ColoredBlockContainer container = ColoredBlockContainer.getContainer(world, pos, facing, playerClient); - if (container.isValid(world, pos, facing, playerClient)) { + if (container.isBlockValid(world, pos, facing, playerClient)) { if (usesRGB(sprayCan) && container.supportsARGB() && !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { int color = container.getColorInt(world, pos, facing, playerClient); From 5c2a130af92ab7f404df7fac3035a37878148fe2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 22 Nov 2025 00:58:28 -0500 Subject: [PATCH 100/109] Add spray can support to beds --- .../api/color/ColoredBlockContainer.java | 2 + .../color/containers/BedColorContainer.java | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/main/java/gregtech/api/color/containers/BedColorContainer.java diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 9e4ce0647d2..75d393cab45 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -1,6 +1,7 @@ package gregtech.api.color; import gregtech.api.color.containers.AE2ColorContainer; +import gregtech.api.color.containers.BedColorContainer; import gregtech.api.color.containers.GTPipeColorContainer; import gregtech.api.color.containers.MTEColorContainer; import gregtech.api.color.containers.NullColorContainer; @@ -55,6 +56,7 @@ public static void registerCEuContainers() { registerContainer(new AE2ColorContainer()); } registerContainer(new VanillaColorContainer()); + registerContainer(new BedColorContainer()); } public abstract boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, diff --git a/src/main/java/gregtech/api/color/containers/BedColorContainer.java b/src/main/java/gregtech/api/color/containers/BedColorContainer.java new file mode 100644 index 00000000000..74885107fdd --- /dev/null +++ b/src/main/java/gregtech/api/color/containers/BedColorContainer.java @@ -0,0 +1,65 @@ +package gregtech.api.color.containers; + +import gregtech.api.color.ColoredBlockContainer; + +import net.minecraft.block.BlockBed; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityBed; +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; + +public class BedColorContainer extends ColoredBlockContainer { + + @Override + public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + // There are no uncolored beds. + if (newColor == null || getColor(world, pos, facing, player) == newColor) { + return false; + } + + IBlockState bedPart1 = world.getBlockState(pos); + BlockBed.EnumPartType partOfBed1 = bedPart1.getValue(BlockBed.PART); + EnumFacing bedFacing = bedPart1.getValue(BlockHorizontal.FACING); + + // The faced direction is always the direction of the foot -> head. + BlockPos otherPartPos = pos.offset(partOfBed1 == BlockBed.EnumPartType.FOOT ? bedFacing : + bedFacing.getOpposite()); + + TileEntity bed1TE = world.getTileEntity(pos); + TileEntity bed2TE = world.getTileEntity(otherPartPos); + if (!(bed1TE instanceof TileEntityBed bed1 && bed2TE instanceof TileEntityBed bed2)) { + return false; + } + + bed1.setColor(newColor); + bed2.setColor(newColor); + return true; + } + + @Override + public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return false; + } + + @Override + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return world.getTileEntity(pos) instanceof TileEntityBed bedTE ? bedTE.getColor() : null; + } + + @Override + public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return world.getTileEntity(pos) instanceof TileEntityBed; + } +} From 4bb82bea1d323014837f5167e611726c9bb36b1d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 22 Nov 2025 01:08:59 -0500 Subject: [PATCH 101/109] Require `ColoredBlockContainer`s to have a ResourceLocation ID --- .../api/color/ColoredBlockContainer.java | 37 ++++++++++++++----- .../color/containers/AE2ColorContainer.java | 5 +++ .../color/containers/BedColorContainer.java | 5 +++ .../containers/GTPipeColorContainer.java | 5 +++ .../color/containers/MTEColorContainer.java | 5 +++ .../color/containers/NullColorContainer.java | 4 ++ .../containers/VanillaColorContainer.java | 5 +++ 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 75d393cab45..ee15953ad61 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -6,21 +6,23 @@ import gregtech.api.color.containers.MTEColorContainer; import gregtech.api.color.containers.NullColorContainer; import gregtech.api.color.containers.VanillaColorContainer; +import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import it.unimi.dsi.fastutil.objects.ObjectArraySet; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; import java.util.Objects; -import java.util.Set; /** * Used to provide a consistent interface for dealing with colored blocks, whether vanilla or modded.
@@ -30,16 +32,24 @@ public abstract class ColoredBlockContainer { @NotNull - private static final Set CONTAINERS = new ObjectArraySet<>(4); + private static final Map CONTAINERS = new Object2ObjectOpenHashMap<>(5); public static void registerContainer(@NotNull ColoredBlockContainer container) { - CONTAINERS.add(Objects.requireNonNull(container, "A null ColoredBlockContainer cannot be registered!")); + Objects.requireNonNull(container, "A null ColoredBlockContainer cannot be registered!"); + ResourceLocation id = container.id; + Objects.requireNonNull(id, "A null ColoredBlockContainer cannot have a null ID!"); + if (CONTAINERS.containsKey(id)) { + throw new IllegalArgumentException( + String.format("A ColoredBlockContainer with an ID of %s already exists!", id)); + } + + CONTAINERS.put(id, container); } public static @NotNull ColoredBlockContainer getContainer(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { - for (ColoredBlockContainer container : CONTAINERS) { + for (ColoredBlockContainer container : CONTAINERS.values()) { if (container.isBlockValid(world, pos, facing, player)) { return container; } @@ -50,13 +60,20 @@ public static void registerContainer(@NotNull ColoredBlockContainer container) { @ApiStatus.Internal public static void registerCEuContainers() { - registerContainer(new GTPipeColorContainer()); - registerContainer(new MTEColorContainer()); + registerContainer(new GTPipeColorContainer(GTUtility.gregtechId("pipe"))); + registerContainer(new MTEColorContainer(GTUtility.gregtechId("mte"))); if (Mods.AppliedEnergistics2.isModLoaded()) { - registerContainer(new AE2ColorContainer()); + registerContainer(new AE2ColorContainer(GTUtility.gregtechId("ae2"))); } - registerContainer(new VanillaColorContainer()); - registerContainer(new BedColorContainer()); + registerContainer(new VanillaColorContainer(GTUtility.gregtechId("vanilla"))); + registerContainer(new BedColorContainer(GTUtility.gregtechId("bed"))); + } + + @NotNull + protected final ResourceLocation id; + + public ColoredBlockContainer(@NotNull ResourceLocation id) { + this.id = id; } public abstract boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index 0197f923446..ae479a61fa9 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -6,6 +6,7 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -16,6 +17,10 @@ public class AE2ColorContainer extends ColoredBlockContainer { + public AE2ColorContainer(@NotNull ResourceLocation id) { + super(id); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/color/containers/BedColorContainer.java b/src/main/java/gregtech/api/color/containers/BedColorContainer.java index 74885107fdd..30996ced321 100644 --- a/src/main/java/gregtech/api/color/containers/BedColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/BedColorContainer.java @@ -10,6 +10,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityBed; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -18,6 +19,10 @@ public class BedColorContainer extends ColoredBlockContainer { + public BedColorContainer(@NotNull ResourceLocation id) { + super(id); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index 93b5159964f..2b6d3b2689b 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -7,6 +7,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -15,6 +16,10 @@ public class GTPipeColorContainer extends ColoredBlockContainer { + public GTPipeColorContainer(@NotNull ResourceLocation id) { + super(id); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index 24539f0efa3..fb5529f3e78 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -7,6 +7,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -17,6 +18,10 @@ public class MTEColorContainer extends ColoredBlockContainer { + public MTEColorContainer(@NotNull ResourceLocation id) { + super(id); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index c0d5d7d7216..68f05971f3c 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -15,6 +15,10 @@ public class NullColorContainer extends ColoredBlockContainer { public static final NullColorContainer NULL_CONTAINER = new NullColorContainer(); + public NullColorContainer() { + super(); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 097a759238a..8b82038b23f 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -12,6 +12,7 @@ import net.minecraft.init.Blocks; import net.minecraft.item.EnumDyeColor; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -35,6 +36,10 @@ public class VanillaColorContainer extends ColoredBlockContainer { Blocks.GLASS_PANE, BlockStainedGlassPane.COLOR, Blocks.HARDENED_CLAY, BlockColored.COLOR); + public VanillaColorContainer(@NotNull ResourceLocation id) { + super(id); + } + @Override public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { From 60e58a437c3661dd57b7aeb0295160bc25fae08d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 22 Nov 2025 01:29:49 -0500 Subject: [PATCH 102/109] fix build error due to skill issue --- .../gregtech/api/color/containers/NullColorContainer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index 68f05971f3c..9f59ee6176b 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -1,6 +1,7 @@ package gregtech.api.color.containers; import gregtech.api.color.ColoredBlockContainer; +import gregtech.api.util.GTUtility; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -15,8 +16,8 @@ public class NullColorContainer extends ColoredBlockContainer { public static final NullColorContainer NULL_CONTAINER = new NullColorContainer(); - public NullColorContainer() { - super(); + private NullColorContainer() { + super(GTUtility.gregtechId("null")); } @Override From 6cfb27ce49aee5313dab63f7dbb53a997505fc64 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 23 Nov 2025 00:04:56 -0500 Subject: [PATCH 103/109] Fix bed spraying from a tool belt --- .../api/items/toolitem/ItemGTToolbelt.java | 36 +++++++------------ .../spray/AbstractSprayBehavior.java | 10 ++++++ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 43656509cd9..35eb1dd0fed 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -504,32 +504,20 @@ public void setSelectedTool(int slot, ItemStack stack) { @NotNull BlockPos pos, @NotNull EnumFacing side, float hitX, float hitY, float hitZ, @NotNull EnumHand hand) { EnumActionResult result = IDyeableItem.super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand); - if (result == EnumActionResult.PASS) { - ItemStack stack = player.getHeldItem(hand); - ToolStackHandler handler = getHandler(stack); - if (handler.getSelectedStack().isEmpty() && - world.getTileEntity(pos) instanceof MetaTileEntityHolder holder && - holder.getMetaTileEntity() instanceof MetaTileEntityMaintenanceHatch maintenance) { - maintenance.fixMaintenanceProblemsWithToolbelt(player, this, stack); - return EnumActionResult.SUCCESS; - } - return super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand); - } else return result; - } + if (result != EnumActionResult.PASS) return result; - @Override - public @NotNull EnumActionResult onItemUse(@NotNull EntityPlayer player, @NotNull World world, - @NotNull BlockPos pos, @NotNull EnumHand hand, - @NotNull EnumFacing facing, float hitX, float hitY, float hitZ) { - ToolStackHandler handler = getHandler(player.getHeldItem(hand)); - ItemStack selected = handler.getSelectedStack(); - if (!selected.isEmpty()) { - EnumActionResult result = AbstractSprayBehavior.handleExternalSpray(player, world, pos, facing, selected); - if (result != EnumActionResult.PASS) { - return result; - } + ItemStack thisToolBelt = player.getHeldItem(hand); + ToolStackHandler handler = getHandler(thisToolBelt); + ItemStack selectedToolBeltStack = handler.getSelectedStack(); + if (selectedToolBeltStack.isEmpty() && world.getTileEntity(pos) instanceof MetaTileEntityHolder holder && + holder.getMetaTileEntity() instanceof MetaTileEntityMaintenanceHatch maintenance) { + maintenance.fixMaintenanceProblemsWithToolbelt(player, this, thisToolBelt); + return EnumActionResult.SUCCESS; + } else if (AbstractSprayBehavior.isSprayCan(selectedToolBeltStack)) { + return AbstractSprayBehavior.handleExternalSpray(player, world, pos, side, selectedToolBeltStack); } - return super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); + + return super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand); } @Override diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index a4bef4a70ca..193da30ef61 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -80,6 +80,11 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { return getSprayCanBehavior(stack) != null; } + /** + * Call from your items + * {@link net.minecraft.item.Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} + * or the meta item equivalent to check if block is sprayable early enough in the click handling chain. + */ @SuppressWarnings("UnusedReturnValue") public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull World world, @NotNull BlockPos pos, @@ -87,6 +92,11 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { return handleExternalSpray(player, world, pos, facing, player.getHeldItem(hand)); } + /** + * Call from your items + * {@link net.minecraft.item.Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} + * or the meta item equivalent to check if block is sprayable early enough in the click handling chain. + */ public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, From b493fbf3128a5240bc9fee103950dffdae6f69dd Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 23 Nov 2025 11:49:15 -0500 Subject: [PATCH 104/109] WIP stuff --- .../api/color/ColoredBlockContainer.java | 5 ++--- .../color/containers/AE2ColorContainer.java | 6 +++++ .../color/containers/BedColorContainer.java | 6 +++++ .../containers/GTPipeColorContainer.java | 11 +++++----- .../color/containers/MTEColorContainer.java | 3 ++- .../color/containers/NullColorContainer.java | 6 +++++ .../containers/VanillaColorContainer.java | 6 +++++ .../spray/AbstractSprayBehavior.java | 22 +++++++++++-------- .../spray/CreativeSprayBehavior.java | 15 ++++++++----- .../spray/DurabilitySprayBehavior.java | 5 +++++ 10 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index ee15953ad61..7ddf610616a 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -8,6 +8,7 @@ import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -109,7 +110,5 @@ public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNul return getColorInt(world, pos, facing, player) == color; } - public boolean supportsARGB() { - return false; - } + public abstract boolean supportsMode(@NotNull AbstractSprayBehavior.ColorMode colorMode); } diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index ae479a61fa9..fb491aee344 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -1,6 +1,7 @@ package gregtech.api.color.containers; import gregtech.api.color.ColoredBlockContainer; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -71,4 +72,9 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof IColorableTile; } + + @Override + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { + return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + } } diff --git a/src/main/java/gregtech/api/color/containers/BedColorContainer.java b/src/main/java/gregtech/api/color/containers/BedColorContainer.java index 30996ced321..e8f8037c1a4 100644 --- a/src/main/java/gregtech/api/color/containers/BedColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/BedColorContainer.java @@ -1,6 +1,7 @@ package gregtech.api.color.containers; import gregtech.api.color.ColoredBlockContainer; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.block.BlockBed; import net.minecraft.block.BlockHorizontal; @@ -67,4 +68,9 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof TileEntityBed; } + + @Override + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { + return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + } } diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index 2b6d3b2689b..0e219425da4 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -3,6 +3,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.ColorUtil; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -85,14 +86,14 @@ public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull Enu return -1; } - @Override - public boolean supportsARGB() { - return true; - } - @Override public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { return world.getTileEntity(pos) instanceof IPipeTile; } + + @Override + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { + return true; + } } diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index fb5529f3e78..aee268bbdfa 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -3,6 +3,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.ColorUtil; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -99,7 +100,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsARGB() { + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { return true; } } diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java index 9f59ee6176b..7364fa17ab9 100644 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/NullColorContainer.java @@ -2,6 +2,7 @@ import gregtech.api.color.ColoredBlockContainer; import gregtech.api.util.GTUtility; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; @@ -49,4 +50,9 @@ public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNul @NotNull EntityPlayer player, @Nullable EnumDyeColor color) { return false; } + + @Override + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { + return false; + } } diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index 8b82038b23f..ec3f31ce119 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -1,6 +1,7 @@ package gregtech.api.color.containers; import gregtech.api.color.ColoredBlockContainer; +import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.block.Block; import net.minecraft.block.BlockColored; @@ -130,4 +131,9 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul return false; } + + @Override + public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { + return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index 193da30ef61..a7bccec0fb8 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -11,6 +11,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -82,7 +83,7 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { /** * Call from your items - * {@link net.minecraft.item.Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} + * {@link Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} * or the meta item equivalent to check if block is sprayable early enough in the click handling chain. */ @SuppressWarnings("UnusedReturnValue") @@ -94,7 +95,7 @@ public static boolean isSprayCan(@NotNull ItemStack stack) { /** * Call from your items - * {@link net.minecraft.item.Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} + * {@link Item#onItemUseFirst(EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} * or the meta item equivalent to check if block is sprayable early enough in the click handling chain. */ public static @NotNull EnumActionResult handleExternalSpray(@NotNull EntityPlayer player, @@ -138,6 +139,7 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo int color = getColorInt(sprayCan); if (hitSide != null && firstPipe != null && firstPipe.isConnected(hitSide) && (firstPipe.isPainted() ? firstPipe.getPaintingColor() != color : color != -1)) { + if (world.isRemote) return EnumActionResult.SUCCESS; traversePipes(firstPipe, hitSide, player, sprayCan, color); return EnumActionResult.SUCCESS; } @@ -146,15 +148,11 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo } ColoredBlockContainer colorContainer = ColoredBlockContainer.getContainer(world, pos, facing, player); - if (colorContainer.supportsARGB() ? colorContainer.setColor(world, pos, facing, player, getColorInt(sprayCan)) : - colorContainer.setColor(world, pos, facing, player, getColor(sprayCan))) { - onSpray(player, sprayCan); - return EnumActionResult.SUCCESS; - } - - return EnumActionResult.PASS; + //TODO: reimplement spraying according to the mode of the spray can } + public abstract @NotNull AbstractSprayBehavior.ColorMode getColorMode(@NotNull ItemStack sprayCan); + protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @NotNull ItemStack sprayCan, int color) { if (canPipeBePainted(pipeTile, color) && pipeTile.getNeighbor(facing) instanceof IPipeTilenextPipe) { @@ -195,4 +193,10 @@ protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFac private static boolean canPipeBePainted(@NotNull IPipeTile pipeTile, int color) { return pipeTile.isPainted() ? pipeTile.getPaintingColor() != color : color != -1; } + + public enum ColorMode { + DYE_ONLY, + ARGB_ONLY, + EITHER + } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index c7771b5535d..604c19d08dd 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -202,24 +202,29 @@ public int getColorInt(@NotNull ItemStack sprayCan) { return tag.getBoolean(NBT_KEY_USES_RGB) ? tag.getInteger(NBT_KEY_RGB_COLOR) : super.getColorInt(sprayCan); } - public static void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { + @Override + public @NotNull ColorMode getColorMode(@NotNull ItemStack sprayCan) { + return usesRGB(sprayCan) ? ColorMode.ARGB_ONLY : ColorMode.DYE_ONLY; + } + + public void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, color == null ? -1 : color.ordinal()); } - public static void setColorOrdinal(@NotNull ItemStack sprayCan, int ordinal) { + public void setColorOrdinal(@NotNull ItemStack sprayCan, int ordinal) { GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, ordinal >= 0 && ordinal <= 15 ? ordinal : -1); } - public static void setColor(@NotNull ItemStack sprayCan, int argbColor) { + public void setColor(@NotNull ItemStack sprayCan, int argbColor) { GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_RGB_COLOR, argbColor); } - public static boolean usesRGB(@NotNull ItemStack sprayCan) { + public boolean usesRGB(@NotNull ItemStack sprayCan) { return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(NBT_KEY_USES_RGB); } - public static void useRGB(@NotNull ItemStack sprayCan, boolean bool) { + public void useRGB(@NotNull ItemStack sprayCan, boolean bool) { GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(NBT_KEY_USES_RGB, bool); } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index 614dbc07a4d..b91351ef256 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -77,6 +77,11 @@ protected boolean damageCan(@NotNull ItemStack sprayCan) { return this.color; } + @Override + public @NotNull ColorMode getColorMode(@NotNull ItemStack sprayCan) { + return ColorMode.DYE_ONLY; + } + protected int getUsesLeft(@NotNull ItemStack stack) { if (stack.isItemEqual(replacementStack)) return 0; From 800f3e34867d3ea696253be7422b78844e23c16b Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 23 Nov 2025 12:07:56 -0500 Subject: [PATCH 105/109] wrong message --- src/main/java/gregtech/api/color/ColoredBlockContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 7ddf610616a..0164ff274db 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -38,7 +38,7 @@ public abstract class ColoredBlockContainer { public static void registerContainer(@NotNull ColoredBlockContainer container) { Objects.requireNonNull(container, "A null ColoredBlockContainer cannot be registered!"); ResourceLocation id = container.id; - Objects.requireNonNull(id, "A null ColoredBlockContainer cannot have a null ID!"); + Objects.requireNonNull(id, "A ColoredBlockContainer cannot have a null ID!"); if (CONTAINERS.containsKey(id)) { throw new IllegalArgumentException( String.format("A ColoredBlockContainer with an ID of %s already exists!", id)); From ebc3d29168b1809a994243950b5d2414456ff2aa Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:35:36 -0500 Subject: [PATCH 106/109] Finish WIP, refactor how containers support dye or argb --- .../java/gregtech/api/color/ColorMode.java | 39 ++++++++ .../gregtech/api/color/ColorModeSupport.java | 51 ++++++++++ .../api/color/ColoredBlockContainer.java | 42 +++++---- .../color/containers/AE2ColorContainer.java | 32 ++++--- .../color/containers/BedColorContainer.java | 27 +++--- .../containers/GTPipeColorContainer.java | 40 ++++---- .../color/containers/MTEColorContainer.java | 40 ++++---- .../color/containers/NullColorContainer.java | 58 ------------ .../containers/VanillaColorContainer.java | 31 ++++--- .../spray/AbstractSprayBehavior.java | 56 +++++++++-- .../spray/CreativeSprayBehavior.java | 93 ++++++++++++------- .../spray/DurabilitySprayBehavior.java | 3 +- .../resources/assets/gregtech/lang/en_us.lang | 35 ++++--- 13 files changed, 334 insertions(+), 213 deletions(-) create mode 100644 src/main/java/gregtech/api/color/ColorMode.java create mode 100644 src/main/java/gregtech/api/color/ColorModeSupport.java delete mode 100644 src/main/java/gregtech/api/color/containers/NullColorContainer.java diff --git a/src/main/java/gregtech/api/color/ColorMode.java b/src/main/java/gregtech/api/color/ColorMode.java new file mode 100644 index 00000000000..c00584d376c --- /dev/null +++ b/src/main/java/gregtech/api/color/ColorMode.java @@ -0,0 +1,39 @@ +package gregtech.api.color; + +import net.minecraft.item.EnumDyeColor; + +public enum ColorMode { + + /** + * Only try spraying a block to an {@link EnumDyeColor}. + */ + DYE(true, false), + /** + * Only try spraying a block to an ARGB value. + */ + ARGB(false, true), + /** + * Try spraying the block to an {@link EnumDyeColor}, and if that failed fall back to ARGB. + */ + PREFER_DYE(true, true), + /** + * Try spraying the block to an ARGB value, and if that failed fall back to {@link EnumDyeColor}. + */ + PREFER_ARGB(true, true); + + private final boolean dye; + private final boolean argb; + + ColorMode(boolean dye, boolean argb) { + this.dye = dye; + this.argb = argb; + } + + public boolean dye() { + return dye; + } + + public boolean argb() { + return argb; + } +} diff --git a/src/main/java/gregtech/api/color/ColorModeSupport.java b/src/main/java/gregtech/api/color/ColorModeSupport.java new file mode 100644 index 00000000000..bd628cb7d30 --- /dev/null +++ b/src/main/java/gregtech/api/color/ColorModeSupport.java @@ -0,0 +1,51 @@ +package gregtech.api.color; + +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentTranslation; + +import com.cleanroommc.modularui.api.drawable.IKey; +import org.jetbrains.annotations.NotNull; + +public enum ColorModeSupport { + + /** + * This block only supports being colored to an {@link EnumDyeColor}. + */ + DYE_ONLY("gregtech.color_mode.error.dye"), + /** + * This block only supports being colored to an ARGB value. + */ + ARGB_ONLY("gregtech.color_mode.error.argb"), + /** + * This block supports being colored to a {@link EnumDyeColor} or ARGB value. + */ + EITHER("gregtech.color_mode.error.either"); + + @NotNull + private final String errorKey; + + ColorModeSupport(@NotNull String errorKey) { + this.errorKey = errorKey; + } + + public @NotNull String getErrorTranslationKey() { + return errorKey; + } + + public @NotNull IKey getErrorKey() { + return IKey.lang(errorKey); + } + + public @NotNull ITextComponent getErrorText() { + return new TextComponentTranslation(errorKey); + } + + public boolean supportsMode(@NotNull ColorMode colorMode) { + return switch (this) { + case DYE_ONLY -> colorMode.dye(); + case ARGB_ONLY -> colorMode.argb(); + case EITHER -> true; + }; + } +} diff --git a/src/main/java/gregtech/api/color/ColoredBlockContainer.java b/src/main/java/gregtech/api/color/ColoredBlockContainer.java index 0164ff274db..7758981bc0c 100644 --- a/src/main/java/gregtech/api/color/ColoredBlockContainer.java +++ b/src/main/java/gregtech/api/color/ColoredBlockContainer.java @@ -4,14 +4,13 @@ import gregtech.api.color.containers.BedColorContainer; import gregtech.api.color.containers.GTPipeColorContainer; import gregtech.api.color.containers.MTEColorContainer; -import gregtech.api.color.containers.NullColorContainer; import gregtech.api.color.containers.VanillaColorContainer; import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -47,16 +46,20 @@ public static void registerContainer(@NotNull ColoredBlockContainer container) { CONTAINERS.put(id, container); } - public static @NotNull ColoredBlockContainer getContainer(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + /** + * Get the color container for the block or tile entity at the provided position.
+ * Will return {@code null} if no container was valid. + */ + public static @Nullable ColoredBlockContainer getContainer(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { for (ColoredBlockContainer container : CONTAINERS.values()) { if (container.isBlockValid(world, pos, facing, player)) { return container; } } - return NullColorContainer.NULL_CONTAINER; + return null; } @ApiStatus.Internal @@ -80,19 +83,26 @@ public ColoredBlockContainer(@NotNull ResourceLocation id) { public abstract boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player); - public abstract boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor); + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + return EnumActionResult.PASS; + } - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, int newColor) { - return false; + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { + return EnumActionResult.PASS; } - public abstract boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player); + public @NotNull EnumActionResult removeColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { + return EnumActionResult.PASS; + } - public abstract @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, - @NotNull EnumFacing facing, @NotNull EntityPlayer player); + public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, @NotNull EntityPlayer player) { + return null; + } public int getColorInt(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull EntityPlayer player) { @@ -110,5 +120,5 @@ public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNul return getColorInt(world, pos, facing, player) == color; } - public abstract boolean supportsMode(@NotNull AbstractSprayBehavior.ColorMode colorMode); + public abstract @NotNull ColorModeSupport getSupportedColorMode(); } diff --git a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java index fb491aee344..7c691c0eb12 100644 --- a/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/AE2ColorContainer.java @@ -1,11 +1,12 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -23,37 +24,38 @@ public AE2ColorContainer(@NotNull ResourceLocation id) { } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { return removeColor(world, pos, facing, player); } - if (getColor(world, pos, facing, player) == newColor) { - return false; + if (colorMatches(world, pos, facing, player, newColor)) { + return EnumActionResult.PASS; } TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile) { if (colorableTile.getColor().dye != newColor) { - colorableTile.recolourBlock(facing, AEColor.values()[newColor.ordinal()], player); - return true; + return colorableTile.recolourBlock(facing, AEColor.values()[newColor.ordinal()], player) ? + EnumActionResult.SUCCESS : EnumActionResult.FAIL; } } - return false; + return EnumActionResult.PASS; } @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public @NotNull EnumActionResult removeColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { TileEntity te = world.getTileEntity(pos); if (te instanceof IColorableTile colorableTile && colorableTile.getColor() != AEColor.TRANSPARENT) { - colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player); - return true; + return colorableTile.recolourBlock(facing, AEColor.TRANSPARENT, player) ? EnumActionResult.SUCCESS : + EnumActionResult.PASS; } - return false; + return EnumActionResult.PASS; } @Override @@ -74,7 +76,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + public @NotNull ColorModeSupport getSupportedColorMode() { + return ColorModeSupport.DYE_ONLY; } } diff --git a/src/main/java/gregtech/api/color/containers/BedColorContainer.java b/src/main/java/gregtech/api/color/containers/BedColorContainer.java index e8f8037c1a4..1ffd73746cf 100644 --- a/src/main/java/gregtech/api/color/containers/BedColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/BedColorContainer.java @@ -1,7 +1,7 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.block.BlockBed; import net.minecraft.block.BlockHorizontal; @@ -10,6 +10,7 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityBed; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -25,11 +26,13 @@ public BedColorContainer(@NotNull ResourceLocation id) { } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { // There are no uncolored beds. - if (newColor == null || getColor(world, pos, facing, player) == newColor) { - return false; + if (newColor == null) { + return EnumActionResult.FAIL; + } else if (colorMatches(world, pos, facing, player, newColor)) { + return EnumActionResult.PASS; } IBlockState bedPart1 = world.getBlockState(pos); @@ -43,18 +46,12 @@ public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull En TileEntity bed1TE = world.getTileEntity(pos); TileEntity bed2TE = world.getTileEntity(otherPartPos); if (!(bed1TE instanceof TileEntityBed bed1 && bed2TE instanceof TileEntityBed bed2)) { - return false; + return EnumActionResult.FAIL; } bed1.setColor(newColor); bed2.setColor(newColor); - return true; - } - - @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { - return false; + return EnumActionResult.SUCCESS; } @Override @@ -70,7 +67,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + public @NotNull ColorModeSupport getSupportedColorMode() { + return ColorModeSupport.DYE_ONLY; } } diff --git a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java index 0e219425da4..c1ab65d3093 100644 --- a/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/GTPipeColorContainer.java @@ -1,12 +1,13 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.ColorUtil; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -22,52 +23,53 @@ public GTPipeColorContainer(@NotNull ResourceLocation id) { } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { return removeColor(world, pos, facing, player); } - if (getColorInt(world, pos, facing, player) == newColor.colorValue) { - return false; + if (colorMatches(world, pos, facing, player, newColor.colorValue)) { + return EnumActionResult.PASS; } if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { pipeTile.setPaintingColor(newColor.colorValue); - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, int newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { if (newColor == -1) { return removeColor(world, pos, facing, player); } if (world.getTileEntity(pos) instanceof IPipeTilepipeTile) { - if (pipeTile.isPainted() && getColorInt(world, pos, facing, player) == newColor) { - return false; + if (pipeTile.isPainted() && colorMatches(world, pos, facing, player, newColor)) { + return EnumActionResult.PASS; } else { pipeTile.setPaintingColor(newColor); - return true; + return EnumActionResult.SUCCESS; } } - return false; + return EnumActionResult.PASS; } @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public @NotNull EnumActionResult removeColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { if (world.getTileEntity(pos) instanceof IPipeTilepipeTile && pipeTile.isPainted()) { pipeTile.setPaintingColor(-1); - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } @Override @@ -93,7 +95,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return true; + public @NotNull ColorModeSupport getSupportedColorMode() { + return ColorModeSupport.EITHER; } } diff --git a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java index aee268bbdfa..721f6ea14cc 100644 --- a/src/main/java/gregtech/api/color/containers/MTEColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/MTEColorContainer.java @@ -1,12 +1,13 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.ColorUtil; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -24,55 +25,56 @@ public MTEColorContainer(@NotNull ResourceLocation id) { } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { return removeColor(world, pos, facing, player); } - if (getColorInt(world, pos, facing, player) == newColor.colorValue) { - return false; + if (colorMatches(world, pos, facing, player, newColor.colorValue)) { + return EnumActionResult.PASS; } MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.canBeModifiedBy(player)) { mte.setPaintingColor(newColor, facing); - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, int newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, int newColor) { if (newColor == -1) { return removeColor(world, pos, facing, player); } - if (getColorInt(world, pos, facing, player) == newColor) { - return false; + if (colorMatches(world, pos, facing, player, newColor)) { + return EnumActionResult.PASS; } MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.canBeModifiedBy(player)) { mte.setPaintingColor(newColor, facing); - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public @NotNull EnumActionResult removeColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { MetaTileEntity mte = getMetaTileEntity(world, pos); if (mte != null && mte.isPainted() && mte.canBeModifiedBy(player)) { mte.setPaintingColor(-1, facing); - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } @Override @@ -100,7 +102,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return true; + public @NotNull ColorModeSupport getSupportedColorMode() { + return ColorModeSupport.EITHER; } } diff --git a/src/main/java/gregtech/api/color/containers/NullColorContainer.java b/src/main/java/gregtech/api/color/containers/NullColorContainer.java deleted file mode 100644 index 7364fa17ab9..00000000000 --- a/src/main/java/gregtech/api/color/containers/NullColorContainer.java +++ /dev/null @@ -1,58 +0,0 @@ -package gregtech.api.color.containers; - -import gregtech.api.color.ColoredBlockContainer; -import gregtech.api.util.GTUtility; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumDyeColor; -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; - -public class NullColorContainer extends ColoredBlockContainer { - - public static final NullColorContainer NULL_CONTAINER = new NullColorContainer(); - - private NullColorContainer() { - super(GTUtility.gregtechId("null")); - } - - @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { - return false; - } - - @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, - @NotNull EntityPlayer player) { - return false; - } - - @Override - public @Nullable EnumDyeColor getColor(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, - @NotNull EntityPlayer player) { - return null; - } - - @Override - public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @Nullable EnumFacing facing, - @NotNull EntityPlayer player) { - return false; - } - - @Override - public boolean colorMatches(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor color) { - return false; - } - - @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return false; - } -} diff --git a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java index ec3f31ce119..aab9449da51 100644 --- a/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java +++ b/src/main/java/gregtech/api/color/containers/VanillaColorContainer.java @@ -1,7 +1,7 @@ package gregtech.api.color.containers; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; -import gregtech.common.items.behaviors.spray.AbstractSprayBehavior; import net.minecraft.block.Block; import net.minecraft.block.BlockColored; @@ -12,6 +12,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -42,14 +43,14 @@ public VanillaColorContainer(@NotNull ResourceLocation id) { } @Override - public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { + public @NotNull EnumActionResult setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayer player, @Nullable EnumDyeColor newColor) { if (newColor == null) { return removeColor(world, pos, facing, player); } - if (getColor(world, pos, facing, player) == newColor) { - return false; + if (colorMatches(world, pos, facing, player, newColor)) { + return EnumActionResult.PASS; } IBlockState state = world.getBlockState(pos); @@ -59,15 +60,16 @@ public boolean setColor(@NotNull World world, @NotNull BlockPos pos, @NotNull En IBlockState newBlockState = TRANSFORMATIONS.get(block) .getDefaultState() .withProperty(PROPERTY_MAP.get(block), newColor); - return world.setBlockState(pos, newBlockState); + return world.setBlockState(pos, newBlockState) ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; } - return block.recolorBlock(world, pos, facing, newColor); + return block.recolorBlock(world, pos, facing, newColor) ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; } @Override - public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, - @NotNull EntityPlayer player) { + public @NotNull EnumActionResult removeColor(@NotNull World world, @NotNull BlockPos pos, + @NotNull EnumFacing facing, + @NotNull EntityPlayer player) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); @@ -75,7 +77,7 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState newBlockState = TRANSFORMATIONS.inverse() .get(block) .getDefaultState(); - return world.setBlockState(pos, newBlockState); + return world.setBlockState(pos, newBlockState) ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; } else { for (IProperty prop : state.getPropertyKeys()) { if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) { @@ -91,12 +93,13 @@ public boolean removeColor(@NotNull World world, @NotNull BlockPos pos, @NotNull // special cases above on a case-by-case basis } - return block.recolorBlock(world, pos, facing, defaultColor); + return block.recolorBlock(world, pos, facing, defaultColor) ? EnumActionResult.SUCCESS : + EnumActionResult.FAIL; } } } - return false; + return EnumActionResult.PASS; } @Override @@ -133,7 +136,7 @@ public boolean isBlockValid(@NotNull World world, @NotNull BlockPos pos, @NotNul } @Override - public boolean supportsMode(AbstractSprayBehavior.@NotNull ColorMode colorMode) { - return colorMode == AbstractSprayBehavior.ColorMode.DYE_ONLY; + public @NotNull ColorModeSupport getSupportedColorMode() { + return ColorModeSupport.DYE_ONLY; } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java index a7bccec0fb8..3eb7b37fbe2 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/AbstractSprayBehavior.java @@ -1,5 +1,7 @@ package gregtech.common.items.behaviors.spray; +import gregtech.api.color.ColorMode; +import gregtech.api.color.ColorModeSupport; import gregtech.api.color.ColoredBlockContainer; import gregtech.api.cover.CoverRayTracer; import gregtech.api.items.metaitem.MetaItem; @@ -122,6 +124,7 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo return result; } + @SuppressWarnings("ConstantValue") protected @NotNull EnumActionResult spray(@NotNull EntityPlayer player, @NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing facing, @NotNull ItemStack sprayCan) { if (!canSpray(sprayCan)) { @@ -148,10 +151,53 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo } ColoredBlockContainer colorContainer = ColoredBlockContainer.getContainer(world, pos, facing, player); - //TODO: reimplement spraying according to the mode of the spray can + if (colorContainer == null) { + return EnumActionResult.PASS; + } + + ColorModeSupport containerColorMode = colorContainer.getSupportedColorMode(); + ColorMode sprayColorMode = getColorMode(sprayCan); + if (!containerColorMode.supportsMode(sprayColorMode)) { + if (!world.isRemote) { + player.sendStatusMessage(containerColorMode.getErrorText(), true); + } + + return EnumActionResult.FAIL; + } + + return switch (sprayColorMode) { + case DYE -> colorContainer.setColor(world, pos, facing, player, getColor(sprayCan)); + case ARGB -> colorContainer.setColor(world, pos, facing, player, getColorInt(sprayCan)); + case PREFER_DYE -> { + EnumActionResult result = null; + if (containerColorMode.supportsMode(ColorMode.DYE)) { + result = colorContainer.setColor(world, pos, facing, player, getColor(sprayCan)); + } else if (result != EnumActionResult.SUCCESS && containerColorMode.supportsMode(ColorMode.ARGB)) { + result = colorContainer.setColor(world, pos, facing, player, getColorInt(sprayCan)); + } else if (result == null) { + throw new IllegalStateException( + "Container mode didn't support either color mode, this shouldn't be possible!"); + } + + yield result; + } + case PREFER_ARGB -> { + EnumActionResult result = null; + if (containerColorMode.supportsMode(ColorMode.ARGB)) { + result = colorContainer.setColor(world, pos, facing, player, getColorInt(sprayCan)); + } else if (result != EnumActionResult.SUCCESS && containerColorMode.supportsMode(ColorMode.DYE)) { + result = colorContainer.setColor(world, pos, facing, player, getColor(sprayCan)); + } else if (result == null) { + throw new IllegalStateException( + "Container mode didn't support either color mode, this shouldn't be possible!"); + } + + yield result; + } + }; } - public abstract @NotNull AbstractSprayBehavior.ColorMode getColorMode(@NotNull ItemStack sprayCan); + public abstract @NotNull ColorMode getColorMode(@NotNull ItemStack sprayCan); protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFacing facing, @NotNull EntityPlayer player, @NotNull ItemStack sprayCan, int color) { @@ -193,10 +239,4 @@ protected void traversePipes(@NotNull IPipeTile pipeTile, @NotNull EnumFac private static boolean canPipeBePainted(@NotNull IPipeTile pipeTile, int color) { return pipeTile.isPainted() ? pipeTile.getPaintingColor() != color : color != -1; } - - public enum ColorMode { - DYE_ONLY, - ARGB_ONLY, - EITHER - } } diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 604c19d08dd..0ffc72665c9 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -1,5 +1,6 @@ package gregtech.common.items.behaviors.spray; +import gregtech.api.color.ColorMode; import gregtech.api.color.ColoredBlockContainer; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.metaitem.stats.IItemColorProvider; @@ -204,7 +205,7 @@ public int getColorInt(@NotNull ItemStack sprayCan) { @Override public @NotNull ColorMode getColorMode(@NotNull ItemStack sprayCan) { - return usesRGB(sprayCan) ? ColorMode.ARGB_ONLY : ColorMode.DYE_ONLY; + return usesRGB(sprayCan) ? ColorMode.ARGB : ColorMode.DYE; } public void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { @@ -254,42 +255,68 @@ public void handleMouseEventClient(@NotNull MouseEvent event, @NotNull EntityPla // Middle click pressed down if (event.getButton() == 2 && event.isButtonstate()) { event.setCanceled(true); + if (tryCopyColor(playerClient, hand, sprayCan)) return; - RayTraceResult rayTrace = RayTracer.retrace(playerClient); - if (rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { - World world = playerClient.world; - BlockPos pos = rayTrace.getBlockPos(); - EnumFacing facing = rayTrace.sideHit; - ColoredBlockContainer container = ColoredBlockContainer.getContainer(world, pos, facing, - playerClient); - - if (container.isBlockValid(world, pos, facing, playerClient)) { - if (usesRGB(sprayCan) && container.supportsARGB() && - !container.colorMatches(world, pos, facing, playerClient, getColorInt(sprayCan))) { - int color = container.getColorInt(world, pos, facing, playerClient); - if (color != -1) { - setColor(sprayCan, color); - sendToServer(hand, buf -> buf - .writeByte(1) - .writeInt(color)); - return; - } - } else if (!container.colorMatches(world, pos, facing, playerClient, getColor(sprayCan))) { - EnumDyeColor color = container.getColor(world, pos, facing, playerClient); - if (color != null) { - setColor(sprayCan, color); - sendToServer(hand, buf -> buf - .writeByte(2) - .writeByte(color.ordinal())); - return; - } - } + // If the player wasn't looking at a colored block, open gui + sendToServer(hand, buf -> buf.writeByte(0)); + } + } + + protected boolean tryCopyColor(@NotNull EntityPlayerSP playerClient, @NotNull EnumHand hand, + @NotNull ItemStack sprayCan) { + RayTraceResult rayTrace = RayTracer.retrace(playerClient); + if (rayTrace == null || rayTrace.typeOfHit != RayTraceResult.Type.BLOCK) return false; + + World world = playerClient.world; + BlockPos pos = rayTrace.getBlockPos(); + EnumFacing facing = rayTrace.sideHit; + ColoredBlockContainer container = ColoredBlockContainer.getContainer(world, pos, facing, playerClient); + if (container == null) return false; + + return switch (getColorMode(sprayCan)) { + case DYE, PREFER_DYE -> { + if (tryCopyDyeColor(container, world, pos, facing, playerClient, hand, sprayCan)) { + yield true; } + + yield tryCopyARGBColor(container, world, pos, facing, playerClient, hand, sprayCan); } + case ARGB, PREFER_ARGB -> { + if (tryCopyARGBColor(container, world, pos, facing, playerClient, hand, sprayCan)) { + yield true; + } - // If the player isn't sneaking and wasn't looking at a colored block, open gui - sendToServer(hand, buf -> buf.writeByte(0)); - } + yield tryCopyDyeColor(container, world, pos, facing, playerClient, hand, sprayCan); + } + }; + } + + protected boolean tryCopyDyeColor(@NotNull ColoredBlockContainer container, @NotNull World world, + @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayerSP playerClient, @NotNull EnumHand hand, + @NotNull ItemStack sprayCan) { + EnumDyeColor blockColor = container.getColor(world, pos, facing, playerClient); + if (blockColor == null || blockColor == getColor(sprayCan)) return false; + + setColor(sprayCan, blockColor); + sendToServer(hand, buf -> buf + .writeByte(2) + .writeByte(blockColor.ordinal())); + return true; + } + + protected boolean tryCopyARGBColor(@NotNull ColoredBlockContainer container, @NotNull World world, + @NotNull BlockPos pos, @NotNull EnumFacing facing, + @NotNull EntityPlayerSP playerClient, @NotNull EnumHand hand, + @NotNull ItemStack sprayCan) { + int blockColor = container.getColorInt(world, pos, facing, playerClient); + if (blockColor == -1 || blockColor == getColorInt(sprayCan)) return false; + + setColor(sprayCan, blockColor); + sendToServer(hand, buf -> buf + .writeByte(1) + .writeInt(blockColor)); + return true; } @Override diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index b91351ef256..f7c37126386 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -1,5 +1,6 @@ package gregtech.common.items.behaviors.spray; +import gregtech.api.color.ColorMode; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; @@ -79,7 +80,7 @@ protected boolean damageCan(@NotNull ItemStack sprayCan) { @Override public @NotNull ColorMode getColorMode(@NotNull ItemStack sprayCan) { - return ColorMode.DYE_ONLY; + return ColorMode.DYE; } protected int getUsesLeft(@NotNull ItemStack stack) { diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index c7447d97063..b8417b9507e 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -354,21 +354,6 @@ metaitem.spray.creative.brown=Brown metaitem.spray.creative.green=Green metaitem.spray.creative.red=Red metaitem.spray.creative.black=Black - -metaitem.plant.ball.name=Plantball - -# Fluid Cells -metaitem.fluid_cell.empty=Empty -metaitem.fluid_cell.name=%s Cell -metaitem.fluid_cell.universal.empty=Empty -metaitem.fluid_cell.universal.name=%s Universal Cell -metaitem.fluid_cell.glass_vial.name=%s Glass Vial -metaitem.large_fluid_cell.steel.name=%s Steel Cell -metaitem.large_fluid_cell.aluminium.name=%s Aluminium Cell -metaitem.large_fluid_cell.stainless_steel.name=%s Stainless Steel Cell -metaitem.large_fluid_cell.titanium.name=%s Titanium Cell -metaitem.large_fluid_cell.tungstensteel.name=%s Tungstensteel Cell - metaitem.spray.solvent.name=Spray Can (Solvent) metaitem.spray.can.dyes.white.name=Spray Can (White) metaitem.spray.can.dyes.orange.name=Spray Can (Orange) @@ -387,6 +372,26 @@ metaitem.spray.can.dyes.green.name=Spray Can (Green) metaitem.spray.can.dyes.red.name=Spray Can (Red) metaitem.spray.can.dyes.black.name=Spray Can (Black) +gregtech.color_mode.error.dye=Block doesn't support dye coloring! +gregtech.color_mode.error.argb=Block doesn't support ARGB coloring! +# This shouldn't ever show up in game, but exists for completions sake +gregtech.color_mode.error.either=Block doesn't support coloring! + + +metaitem.plant.ball.name=Plantball + +# Fluid Cells +metaitem.fluid_cell.empty=Empty +metaitem.fluid_cell.name=%s Cell +metaitem.fluid_cell.universal.empty=Empty +metaitem.fluid_cell.universal.name=%s Universal Cell +metaitem.fluid_cell.glass_vial.name=%s Glass Vial +metaitem.large_fluid_cell.steel.name=%s Steel Cell +metaitem.large_fluid_cell.aluminium.name=%s Aluminium Cell +metaitem.large_fluid_cell.stainless_steel.name=%s Stainless Steel Cell +metaitem.large_fluid_cell.titanium.name=%s Titanium Cell +metaitem.large_fluid_cell.tungstensteel.name=%s Tungstensteel Cell + metaitem.tool.matches.name=Match metaitem.tool.matchbox.name=Match Box From 86a8daea5886c552843ff67ff079fffcdee26bc9 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:49:50 -0500 Subject: [PATCH 107/109] Swap error messages --- src/main/java/gregtech/api/color/ColorModeSupport.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/color/ColorModeSupport.java b/src/main/java/gregtech/api/color/ColorModeSupport.java index bd628cb7d30..481de6ae113 100644 --- a/src/main/java/gregtech/api/color/ColorModeSupport.java +++ b/src/main/java/gregtech/api/color/ColorModeSupport.java @@ -12,11 +12,11 @@ public enum ColorModeSupport { /** * This block only supports being colored to an {@link EnumDyeColor}. */ - DYE_ONLY("gregtech.color_mode.error.dye"), + DYE_ONLY("gregtech.color_mode.error.argb"), /** * This block only supports being colored to an ARGB value. */ - ARGB_ONLY("gregtech.color_mode.error.argb"), + ARGB_ONLY("gregtech.color_mode.error.dye"), /** * This block supports being colored to a {@link EnumDyeColor} or ARGB value. */ From 58885a0a1aeb9215009b84cadd77a588a2679239 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 24 Nov 2025 22:23:24 -0500 Subject: [PATCH 108/109] Actually clear NBT when spray can breaks --- .../common/items/behaviors/spray/DurabilitySprayBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java index f7c37126386..3b63fb8a0b8 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/DurabilitySprayBehavior.java @@ -60,7 +60,7 @@ public void onSpray(@NotNull EntityPlayer player, @NotNull ItemStack sprayCan) { // Update held item to replacement stack sprayCan.setItemDamage(replacementStack.getItemDamage()); // Clear NBT from old can - sprayCan.setTagCompound(new NBTTagCompound()); + sprayCan.setTagCompound(null); // Play sound manually since we aren't using player.setHeldItem(...) player.playSound(SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 1.0f, 1.0f); } From 6b03db6561a5f050ed47d751804e2951dbf32cff Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Mon, 24 Nov 2025 22:24:46 -0500 Subject: [PATCH 109/109] Use nbt constant for MUI2 sync too --- .../spray/CreativeSprayBehavior.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java index 0ffc72665c9..2b29aef47ca 100644 --- a/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/spray/CreativeSprayBehavior.java @@ -61,24 +61,24 @@ public class CreativeSprayBehavior extends AbstractSprayBehavior implements ItemUIFactory, IItemColorProvider, IItemNameProvider, IMouseEventHandler { - private static final String NBT_KEY_COLOR = "color"; - private static final String NBT_KEY_USES_RGB = "usesRGB"; - private static final String NBT_KEY_RGB_COLOR = "rgbColor"; + private static final String KEY_COLOR = "color"; + private static final String KEY_USES_RGB = "usesRGB"; + private static final String KEY_RGB_COLOR = "rgbColor"; @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { ItemStack usedStack = guiData.getUsedItemStack(); IntSyncValue colorSync = SyncHandlers.intNumber(() -> getColorOrdinal(usedStack), newColor -> setColorOrdinal(usedStack, newColor)); - guiSyncManager.syncValue("color", 0, colorSync); + guiSyncManager.syncValue(KEY_COLOR, 0, colorSync); BooleanSyncValue usesRGBSync = SyncHandlers.bool(() -> usesRGB(usedStack), bool -> useRGB(usedStack, bool)); - guiSyncManager.syncValue("usesRGB", 0, usesRGBSync); + guiSyncManager.syncValue(KEY_USES_RGB, 0, usesRGBSync); // Doesn't use getColorInt because the slider widgets take a moment to update so it ended up showing the normal // can colors when you switched to RGB mode. IntSyncValue rgbColorSync = SyncHandlers.intNumber( - () -> GTUtility.getOrCreateNbtCompound(usedStack).getInteger(NBT_KEY_RGB_COLOR), + () -> GTUtility.getOrCreateNbtCompound(usedStack).getInteger(KEY_RGB_COLOR), newColor -> setColor(usedStack, newColor)); - guiSyncManager.syncValue("rgbColor", 0, rgbColorSync); + guiSyncManager.syncValue(KEY_RGB_COLOR, 0, rgbColorSync); PagedWidget.Controller pageController = new PagedWidget.Controller(); @@ -188,8 +188,8 @@ protected static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyn @Override public @Nullable EnumDyeColor getColor(@NotNull ItemStack sprayCan) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); - if (tag.hasKey(NBT_KEY_COLOR, Constants.NBT.TAG_INT)) { - int color = tag.getInteger(NBT_KEY_COLOR); + if (tag.hasKey(KEY_COLOR, Constants.NBT.TAG_INT)) { + int color = tag.getInteger(KEY_COLOR); if (color < 0 || color > 15) return null; return EnumDyeColor.values()[color]; } @@ -200,7 +200,7 @@ protected static Flow createColorRow(@NotNull ARGBHelper helper, @NotNull IntSyn @Override public int getColorInt(@NotNull ItemStack sprayCan) { NBTTagCompound tag = GTUtility.getOrCreateNbtCompound(sprayCan); - return tag.getBoolean(NBT_KEY_USES_RGB) ? tag.getInteger(NBT_KEY_RGB_COLOR) : super.getColorInt(sprayCan); + return tag.getBoolean(KEY_USES_RGB) ? tag.getInteger(KEY_RGB_COLOR) : super.getColorInt(sprayCan); } @Override @@ -209,24 +209,24 @@ public int getColorInt(@NotNull ItemStack sprayCan) { } public void setColor(@NotNull ItemStack sprayCan, @Nullable EnumDyeColor color) { - GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, color == null ? -1 : color.ordinal()); + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(KEY_COLOR, color == null ? -1 : color.ordinal()); } public void setColorOrdinal(@NotNull ItemStack sprayCan, int ordinal) { - GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_COLOR, + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(KEY_COLOR, ordinal >= 0 && ordinal <= 15 ? ordinal : -1); } public void setColor(@NotNull ItemStack sprayCan, int argbColor) { - GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(NBT_KEY_RGB_COLOR, argbColor); + GTUtility.getOrCreateNbtCompound(sprayCan).setInteger(KEY_RGB_COLOR, argbColor); } public boolean usesRGB(@NotNull ItemStack sprayCan) { - return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(NBT_KEY_USES_RGB); + return GTUtility.getOrCreateNbtCompound(sprayCan).getBoolean(KEY_USES_RGB); } public void useRGB(@NotNull ItemStack sprayCan, boolean bool) { - GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(NBT_KEY_USES_RGB, bool); + GTUtility.getOrCreateNbtCompound(sprayCan).setBoolean(KEY_USES_RGB, bool); } @Override