From d49c91072a5f34d8e605d52950be3d08dc85de55 Mon Sep 17 00:00:00 2001 From: syticchan Date: Wed, 13 May 2026 23:18:44 +0700 Subject: [PATCH 1/3] Add Insulation feature & Asbestos Insulation Wrapper Add Asbestos Insulation Wrapper; Jade HUD shows Insulation status on fluid pipes if insulated --- .../resources/assets/gtceu/lang/en_us.json | 10 +- .../item/asbestos_insulation_wrapper.json | 6 ++ .../gtceu/common/block/FluidPipeBlock.java | 5 +- .../blockentity/FluidPipeBlockEntity.java | 11 ++- .../gtceu/common/data/GTItems.java | 9 ++ .../behavior/InsulationWrapperBehaviour.java | 89 ++++++++++++++++++ .../data/recipe/misc/ComponentRecipes.java | 12 +++ .../gtceu/integration/jade/GTJadePlugin.java | 2 + .../jade/provider/FluidPipeInfoProvider.java | 44 +++++++++ .../item/asbestos_insulation_wrapper.png | Bin 0 -> 815 bytes 10 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json create mode 100644 src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/jade/provider/FluidPipeInfoProvider.java create mode 100644 src/main/resources/assets/gtceu/textures/item/asbestos_insulation_wrapper.png diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 67ddba4f02e..9139771e6f5 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -1942,6 +1942,7 @@ "config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] Energy Converter Mode", "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] Exhaust Vent Info", "config.jade.plugin_gtceu.hazard_cleaner_provider": "[GTCEu] Hazard Cleaner", + "config.jade.plugin_gtceu.fluid_pipe_info": "[GTCEu] Fluid Pipe Info", "config.jade.plugin_gtceu.ldp_endpoint": "[GTCEu] Long Distance Pipeline Endpoint Info", "config.jade.plugin_gtceu.machine_mode": "[GTCEu] Machine Mode", "config.jade.plugin_gtceu.maintenance_info": "[GTCEu] Maintenance Info", @@ -1956,7 +1957,6 @@ "config.jade.plugin_gtceu.steam_boiler_info": "[GTCEu] Steam Boiler Info", "config.jade.plugin_gtceu.transformer": "[GTCEu] Transformer Info", "config.jade.plugin_gtceu.workable_provider": "[GTCEu] Workable", - "config.screen.gtceu": "GregTechCEu Configuration", "cover.advanced_detector.latch.disabled.0": "Behavior: Continuous", "cover.advanced_detector.latch.disabled.1": "", "cover.advanced_detector.latch.disabled.2": "Change the redstone behavior of this Cover.", @@ -2354,6 +2354,7 @@ "gtceu.fluid_pipe.channels": "§eChannels: §f%d", "gtceu.fluid_pipe.cryo_proof": "§6Can handle Cryogenics", "gtceu.fluid_pipe.gas_proof": "§6Can handle Gases", + "gtceu.fluid_pipe.insulated": "§bInsulated", "gtceu.fluid_pipe.max_temperature": "§cTemperature Limit: §f%s", "gtceu.fluid_pipe.not_gas_proof": "§4Gases may leak!", "gtceu.fluid_pipe.plasma_proof": "§6Can handle all Plasmas", @@ -2509,6 +2510,10 @@ "gtceu.io.export": "Export", "gtceu.io.import": "Import", "gtceu.io.none": "None", + "gtceu.insulation_wrapper.already_insulated": "§eAll pipes in this network are already insulated", + "gtceu.insulation_wrapper.invalid_pipe": "§eNot a fluid pipe", + "gtceu.insulation_wrapper.partial": "§aInsulated §f%s pipe(s)§a, §f%s pipe(s) §eremain uninsulated", + "gtceu.insulation_wrapper.success": "§aInsulated §f%s pipe(s)", "gtceu.item_filter.empty_item": "Empty (No Item)", "gtceu.item_filter.footer": "§eClick with item to override", "gtceu.item_list.item_stored": "§7Stored: %d", @@ -4315,6 +4320,9 @@ "item.gtceu.ilc_chip.tooltip": "§7Integrated Logic Circuit", "item.gtceu.ilc_wafer": "ILC Wafer", "item.gtceu.ilc_wafer.tooltip": "§7Raw Integrated Circuit", + "item.gtceu.asbestos_insulation_wrapper": "Asbestos Insulation Wrapper", + "item.gtceu.asbestos_insulation_wrapper.desc": "§bNullify damage from hot/cold fluids", + "item.gtceu.asbestos_insulation_wrapper.usage": "Shift-Right-Click on fluid pipe network", "item.gtceu.image_module": "Image Module", "item.gtceu.impure_bentonite_dust": "Impure Pile of Bentonite", "item.gtceu.impure_cassiterite_sand_dust": "Impure Pile of Cassiterite Sand", diff --git a/src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json b/src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json new file mode 100644 index 00000000000..99bf581f9bb --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/asbestos_insulation_wrapper" + } +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java index 1af49f770c2..1bf7864fd7c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java @@ -133,7 +133,10 @@ public void entityInside(BlockState state, Level level, BlockPos pos, Entity ent if (level.isClientSide) return; if (level.getBlockEntity(pos) == null) return; FluidPipeBlockEntity pipe = (FluidPipeBlockEntity) level.getBlockEntity(pos); - + if (pipe.isInsulated()) { + super.entityInside(state, level, pos, entity); + return; + } if (pipe.getOffsetTimer() % 10 == 0) { if (entity instanceof LivingEntity livingEntity) { if (pipe.getFluidTanks().length > 1) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java index ba6aa0648f6..c47d701c2b5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java @@ -28,6 +28,8 @@ import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.GTUtil; +import lombok.Getter; +import lombok.Setter; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -62,7 +64,7 @@ import java.util.function.Predicate; public class FluidPipeBlockEntity extends PipeBlockEntity - implements IDataInfoProvider { + implements IDataInfoProvider { public static final int FREQUENCY = 5; @@ -71,6 +73,10 @@ public class FluidPipeBlockEntity extends PipeBlockEntity tankLists = new EnumMap<>(Direction.class); @SaveField(nbtKey = "Fluids") private CustomFluidTank[] fluidTanks; + @Getter + @Setter + @SaveField(nbtKey = "Insulated") + private boolean insulated = false; private long timer = 0L; private final int offset = GTValues.RNG.nextInt(20); @@ -501,6 +507,9 @@ public static void setNeighboursToFire(Level world, BlockPos selfPos) { if (mode == PortableScannerBehavior.DisplayMode.SHOW_ALL || mode == PortableScannerBehavior.DisplayMode.SHOW_MACHINE_INFO) { + if (insulated) { + list.add(Component.translatable("gtceu.fluid_pipe.insulated")); + } FluidStack[] fluids = getContainedFluids(); if (fluids != null) { boolean allTanksEmpty = true; diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java index 7cef69333c5..a126274c421 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java @@ -2554,6 +2554,15 @@ public static ItemEntry createFluidCell(Material mat, int capacit .onRegister(attach(new ImageModuleBehaviour())) .register(); + public static ItemEntry ASBESTOS_INSULATION_WRAPPER = REGISTRATE.item("asbestos_insulation_wrapper", ComponentItem::create) + .lang("Asbestos Insulation Wrapper") + .onRegister(attach(new TooltipBehavior(lines -> { + lines.add(Component.translatable("item.gtceu.asbestos_insulation_wrapper.desc")); + lines.add(Component.translatable("item.gtceu.asbestos_insulation_wrapper.usage")); + }))) + .onRegister(attach(new InsulationWrapperBehaviour())) + .register(); + public static void init() { GTMaterialItems.generateMaterialItems(); GTMaterialItems.generateTools(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java new file mode 100644 index 00000000000..1bab572d102 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java @@ -0,0 +1,89 @@ +package com.gregtechceu.gtceu.common.item.behavior; + +import com.gregtechceu.gtceu.api.item.component.IInteractionItem; +import com.gregtechceu.gtceu.common.block.FluidPipeBlock; +import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; +import com.gregtechceu.gtceu.common.data.GTItems; +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.LevelFluidPipeNet; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.context.UseOnContext; + +import java.util.ArrayList; +import java.util.List; + +public class InsulationWrapperBehaviour implements IInteractionItem { + + @Override + public InteractionResult useOn(UseOnContext context) { + var player = context.getPlayer(); + var level = context.getLevel(); + var pos = context.getClickedPos(); + + if (player == null || level.isClientSide || !player.isCrouching()) { + return InteractionResult.PASS; + } + + if (!(level.getBlockState(pos).getBlock() instanceof FluidPipeBlock)) { + player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.invalid_pipe"), true); + return InteractionResult.FAIL; + } + + if (!(level instanceof ServerLevel serverLevel)) return InteractionResult.PASS; + + LevelFluidPipeNet levelNet = LevelFluidPipeNet.getOrCreate(serverLevel); + var net = levelNet.getNetFromPos(pos); + if (net == null) return InteractionResult.FAIL; + + // get all pipes in the network + List toInsulate = new ArrayList<>(); + for (BlockPos pipePos : net.getAllNodes().keySet()) { + if (level.getBlockEntity(pipePos) instanceof FluidPipeBlockEntity pipe) { + if (!pipe.isInsulated()) { + toInsulate.add(pipePos); + } + } + } + + int needed = toInsulate.size(); + + if (!player.isCreative()) { + // already fully insulated + if (toInsulate.isEmpty()) { + player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.already_insulated"), true); + return InteractionResult.FAIL; + } + + // count available wrappers + int available = player.getInventory().clearOrCountMatchingItems(itemStack -> itemStack.getItem() == GTItems.ASBESTOS_INSULATION_WRAPPER.get(), 0, player.inventoryMenu.getCraftSlots()); + if (available == 0) { + return InteractionResult.FAIL; + } + needed = Math.min(available, toInsulate.size()); + } + + // insulate all pipes + for (int i = 0; i < needed; i++) { + if (level.getBlockEntity(toInsulate.get(i)) instanceof FluidPipeBlockEntity pipe) { + pipe.setInsulated(true); + } + } + + // clear needed amount from inventory + if (!player.isCreative()){ + player.getInventory().clearOrCountMatchingItems(itemStack -> itemStack.getItem() == GTItems.ASBESTOS_INSULATION_WRAPPER.get(), needed, player.inventoryMenu.getCraftSlots()); + } + + // inform if its fully insulated or partially insulated; if partial, return uninsulated amount + int remaining = toInsulate.size() - needed; + if (remaining > 0) { + player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.partial", needed, remaining), true); + } else { + player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.success", needed), true); + } + return InteractionResult.SUCCESS; + } + +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java index b80d83dccd7..2451c4af372 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java @@ -7,6 +7,7 @@ import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper; import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -1131,5 +1132,16 @@ public static void init(Consumer provider) { .EUt(VA[ZPM])) .duration(600).EUt(100000) .addMaterialInfo(true).save(provider); + + // Insulation Wrapper Start----------------------------------------------------------------------------------------- + VanillaRecipeHelper.addShapedRecipe(provider, true, "asbestos_insulation_wrapper", ASBESTOS_INSULATION_WRAPPER.asStack(), "DDD", "WFW", "DDD", + 'D', new MaterialEntry(dust, Asbestos), 'W', new ItemStack(Items.WHITE_WOOL), 'F', new MaterialEntry(foil, Steel)); + + ASSEMBLER_RECIPES.recipeBuilder("asbestos_insulation_wrapper") + .inputItems(dust, Asbestos, 6) + .inputItems(Items.WHITE_WOOL) + .inputItems(foil, Steel, 1) + .outputItems(ASBESTOS_INSULATION_WRAPPER) + .duration(80).EUt(VA[LV]).save(provider); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java index 425f02b6dbf..7a83bdd9016 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java @@ -46,6 +46,7 @@ public void register(IWailaCommonRegistration registration) { registration.registerBlockDataProvider(new EnergyConverterModeProvider(), BlockEntity.class); registration.registerBlockDataProvider(new BatteryStorageInfoProvider(), BlockEntity.class); registration.registerBlockDataProvider(new LDPEndpointProvider(), BlockEntity.class); + registration.registerBlockDataProvider(new FluidPipeInfoProvider(), BlockEntity.class); if (GTCEu.Mods.isAE2Loaded()) { registration.registerBlockDataProvider(new MEPatternBufferProvider(), BlockEntity.class); registration.registerBlockDataProvider(new MEPatternBufferProxyProvider(), BlockEntity.class); @@ -79,6 +80,7 @@ public void registerClient(IWailaClientRegistration registration) { registration.registerBlockComponent(new LDPEndpointProvider(), Block.class); registration.registerBlockComponent(new EnergyConverterModeProvider(), Block.class); registration.registerBlockComponent(new BatteryStorageInfoProvider(), Block.class); + registration.registerBlockComponent(new FluidPipeInfoProvider(), Block.class); if (GTCEu.Mods.isAE2Loaded()) { registration.registerBlockComponent(new MEPatternBufferProvider(), Block.class); registration.registerBlockComponent(new MEPatternBufferProxyProvider(), Block.class); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/FluidPipeInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/FluidPipeInfoProvider.java new file mode 100644 index 00000000000..3651fffdb73 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/FluidPipeInfoProvider.java @@ -0,0 +1,44 @@ +package com.gregtechceu.gtceu.integration.jade.provider; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.common.block.FluidPipeBlock; +import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.entity.BlockEntity; +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.IBlockComponentProvider; +import snownee.jade.api.IServerDataProvider; +import snownee.jade.api.ITooltip; +import snownee.jade.api.config.IPluginConfig; + +public class FluidPipeInfoProvider implements IBlockComponentProvider, IServerDataProvider { + + @Override + public void appendTooltip(ITooltip tooltip, BlockAccessor blockAccessor, IPluginConfig config) { + BlockEntity be = blockAccessor.getBlockEntity(); + if (be != null) { + CompoundTag data = blockAccessor.getServerData().getCompound(getUid().toString()); + if (data.contains("insulated") && data.getBoolean("insulated")) { + tooltip.add(Component.translatable("gtceu.fluid_pipe.insulated")); + } + } + } + + @Override + public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) { + CompoundTag data = compoundTag.getCompound(getUid().toString()); + if (blockAccessor.getBlock() instanceof FluidPipeBlock fluidPipeBlock) { + FluidPipeBlockEntity pipe = (FluidPipeBlockEntity) fluidPipeBlock.getPipeTile( + blockAccessor.getLevel(), blockAccessor.getPosition()); + if (pipe != null) { + data.putBoolean("insulated", pipe.isInsulated()); + } + } + compoundTag.put(getUid().toString(), data); + } + + @Override + public ResourceLocation getUid() {return GTCEu.id("fluid_pipe_info");} +} \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/textures/item/asbestos_insulation_wrapper.png b/src/main/resources/assets/gtceu/textures/item/asbestos_insulation_wrapper.png new file mode 100644 index 0000000000000000000000000000000000000000..c9fc099e7788f74712ccac163f7f2e310937dc0a GIT binary patch literal 815 zcmV+~1JL}5P)u?7g-TlkNpevkkBUN ziljkg1{FmTp%8{o5z#{!xa+FBdq4Kx>CAv)!#y)|&z#@y{LY!-*fHAMJ4HO+E23R7 zW!IwK2L#&$9i34T?Mt9LnMD7<08&GPNTgC|ZEHuozaO3P z9yByHA#(H>&J7N2lW@t_5$zJETU%l1I;tuwP+J>9eK<^3hdSEVhC*2RyMm^}hp=b& zE*xoY#`)n3ibN6kWgor}2p9oWR#qWI0BP0L)d&R0S7AceG=yrZ@pXP4hM~iCUC6<^ zVllD5u>rmh_z>!_G8lwu7+{Rizkwe=e<9L%km5N!&x08V;`oV^suV6fADf#6_~kMf ziEmcb7-XG%cqa9ZAX!Dk5Y5aVY?12+d`pKLVkS%Yx#9# zb2+#~T(WGGh(J)8Btv}_RF+rvz)jOsOs?aiR4h?8mlSOfNgjn_5jH8ZNRb3H#uQji znx@0`TyWVu+qSV;EWo1RY%YrpD#@a(7Wriv!JsKI|5<=~WRP*r8D+JRe*6dzABn=A}Xd#S0p8S)L@g-^7hO_aJ3EbTcwATpz|7 zJu0~$9~;BW^t58+(jiUb8p2odis18ycX Date: Sun, 17 May 2026 02:21:59 +0700 Subject: [PATCH 2/3] Various fixes, changes and additions + Renamed "Asbestos Insulation Wrapper" to just "Insulation Wrapper" + You can now remove Insulation from a pipe with a crowbar + Pipe blocks get an overlay texture once insulated + .fluidPipeProperties has an extra option to make pipe insulated by default. Currently applied to Naquadah, Duranium, Neutronium pipes + Pipe segments selection during partial insulation should function the same as spray cans instead of being randomized like before --- .../resources/assets/gtceu/lang/en_us.json | 17 ++-- ...n_wrapper.json => insulation_wrapper.json} | 2 +- .../api/blockentity/PipeBlockEntity.java | 12 +++ .../api/data/chemical/material/Material.java | 21 +++++ .../properties/FluidPipeProperties.java | 9 +- .../gtceu/client/model/GTModelProperties.java | 2 + .../client/model/pipe/BakedPipeModel.java | 37 +++++++- .../gtceu/client/model/pipe/PipeModel.java | 18 ++-- .../client/model/pipe/PipeModelLoader.java | 14 ++- .../client/model/pipe/UnbakedPipeModel.java | 21 ++++- .../gtceu/common/block/FluidPipeBlock.java | 2 + .../blockentity/FluidPipeBlockEntity.java | 15 ++- .../gtceu/common/data/GTItems.java | 8 +- .../data/materials/ElementMaterials.java | 6 +- .../behavior/InsulationWrapperBehaviour.java | 59 ++++++------ .../pipelike/fluidpipe/FluidPipeNet.java | 4 +- .../pipelike/fluidpipe/FluidPipeType.java | 18 +++- .../gregtechceu/gtceu/data/lang/ItemLang.java | 7 ++ .../gtceu/data/lang/LangHandler.java | 3 + .../data/model/builder/PipeModelBuilder.java | 87 +++++++++++++++++- .../recipe/misc/AssemblerRecipeLoader.java | 8 ++ .../data/recipe/misc/ComponentRecipes.java | 12 --- .../recipe/misc/CraftingRecipeLoader.java | 4 + .../pipe_insulation_nonuple_side.png | Bin 0 -> 552 bytes .../pipe_insulation_quadruple_side.png | Bin 0 -> 646 bytes .../pipe/insulation/pipe_insulation_side.png | Bin 0 -> 503 bytes ...ion_wrapper.png => insulation_wrapper.png} | Bin 27 files changed, 311 insertions(+), 75 deletions(-) rename src/generated/resources/assets/gtceu/models/item/{asbestos_insulation_wrapper.json => insulation_wrapper.json} (53%) create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_nonuple_side.png create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_quadruple_side.png create mode 100644 src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_side.png rename src/main/resources/assets/gtceu/textures/item/{asbestos_insulation_wrapper.png => insulation_wrapper.png} (100%) diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 9139771e6f5..802a7ebd0e5 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -1957,6 +1957,7 @@ "config.jade.plugin_gtceu.steam_boiler_info": "[GTCEu] Steam Boiler Info", "config.jade.plugin_gtceu.transformer": "[GTCEu] Transformer Info", "config.jade.plugin_gtceu.workable_provider": "[GTCEu] Workable", + "config.screen.gtceu": "GregTechCEu Configuration", "cover.advanced_detector.latch.disabled.0": "Behavior: Continuous", "cover.advanced_detector.latch.disabled.1": "", "cover.advanced_detector.latch.disabled.2": "Change the redstone behavior of this Cover.", @@ -2355,6 +2356,7 @@ "gtceu.fluid_pipe.cryo_proof": "§6Can handle Cryogenics", "gtceu.fluid_pipe.gas_proof": "§6Can handle Gases", "gtceu.fluid_pipe.insulated": "§bInsulated", + "gtceu.fluid_pipe.insulated_by_default": "§6Pre-Insulated", "gtceu.fluid_pipe.max_temperature": "§cTemperature Limit: §f%s", "gtceu.fluid_pipe.not_gas_proof": "§4Gases may leak!", "gtceu.fluid_pipe.plasma_proof": "§6Can handle all Plasmas", @@ -2510,10 +2512,6 @@ "gtceu.io.export": "Export", "gtceu.io.import": "Import", "gtceu.io.none": "None", - "gtceu.insulation_wrapper.already_insulated": "§eAll pipes in this network are already insulated", - "gtceu.insulation_wrapper.invalid_pipe": "§eNot a fluid pipe", - "gtceu.insulation_wrapper.partial": "§aInsulated §f%s pipe(s)§a, §f%s pipe(s) §eremain uninsulated", - "gtceu.insulation_wrapper.success": "§aInsulated §f%s pipe(s)", "gtceu.item_filter.empty_item": "Empty (No Item)", "gtceu.item_filter.footer": "§eClick with item to override", "gtceu.item_list.item_stored": "§7Stored: %d", @@ -4320,9 +4318,14 @@ "item.gtceu.ilc_chip.tooltip": "§7Integrated Logic Circuit", "item.gtceu.ilc_wafer": "ILC Wafer", "item.gtceu.ilc_wafer.tooltip": "§7Raw Integrated Circuit", - "item.gtceu.asbestos_insulation_wrapper": "Asbestos Insulation Wrapper", - "item.gtceu.asbestos_insulation_wrapper.desc": "§bNullify damage from hot/cold fluids", - "item.gtceu.asbestos_insulation_wrapper.usage": "Shift-Right-Click on fluid pipe network", + "item.gtceu.insulation_wrapper": "Insulation Wrapper", + "item.gtceu.insulation_wrapper.desc": "§bNullify damage from thermogenics/cryogenics", + "item.gtceu.insulation_wrapper.message.already_insulated": "§eAll pipes in this network are already insulated", + "item.gtceu.insulation_wrapper.message.invalid_pipe": "§eNot a fluid pipe", + "item.gtceu.insulation_wrapper.message.partial": "§aInsulated §f%s pipe(s)§a, §f%s pipe(s) §eremain uninsulated", + "item.gtceu.insulation_wrapper.message.removed": "§cRemoved Insulation", + "item.gtceu.insulation_wrapper.message.success": "§aInsulated §f%s pipe(s)", + "item.gtceu.insulation_wrapper.usage": "Shift-Right-Click on fluid pipe network", "item.gtceu.image_module": "Image Module", "item.gtceu.impure_bentonite_dust": "Impure Pile of Bentonite", "item.gtceu.impure_cassiterite_sand_dust": "Impure Pile of Cassiterite Sand", diff --git a/src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json b/src/generated/resources/assets/gtceu/models/item/insulation_wrapper.json similarity index 53% rename from src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json rename to src/generated/resources/assets/gtceu/models/item/insulation_wrapper.json index 99bf581f9bb..95f64924a6a 100644 --- a/src/generated/resources/assets/gtceu/models/item/asbestos_insulation_wrapper.json +++ b/src/generated/resources/assets/gtceu/models/item/insulation_wrapper.json @@ -1,6 +1,6 @@ { "parent": "minecraft:item/generated", "textures": { - "layer0": "gtceu:item/asbestos_insulation_wrapper" + "layer0": "gtceu:item/insulation_wrapper" } } \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java index 85160932110..438a7ed48a3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java @@ -14,6 +14,8 @@ import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; +import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.common.data.GTMaterialBlocks; import com.gregtechceu.gtceu.common.data.GTMaterials; import com.gregtechceu.gtceu.utils.ExtendedUseOnContext; @@ -26,6 +28,7 @@ import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionResult; @@ -380,6 +383,15 @@ public ResourceTexture getPipeTexture(boolean isBlock) { } return Pair.of(getPipeTuneTool(), InteractionResult.sidedSuccess(isRemote())); } else if (toolType.contains(GTToolType.CROWBAR)) { + if (this instanceof FluidPipeBlockEntity pipe && pipe.isInsulated() && !pipe.getNodeData().isInsulatedByDefault()) { + if (!isRemote()) { + pipe.setInsulated(false); + player.displayClientMessage(Component.translatable("item.gtceu.insulation_wrapper.message.removed"), true); + Block.popResource(context.getLevel(), this.getBlockPos(), + new ItemStack(GTItems.INSULATION_WRAPPER.get())); + } + return Pair.of(GTToolType.CROWBAR, InteractionResult.sidedSuccess(isRemote())); + } if (!frameMaterial.isNull()) { Block.popResource(context.getLevel(), this.getBlockPos(), GTMaterialBlocks.MATERIAL_BLOCKS.get(TagPrefix.frameGt, frameMaterial).asStack()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/Material.java b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/Material.java index 063d6addcb3..704fa4091f5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/Material.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/Material.java @@ -1808,6 +1808,27 @@ public Builder fluidPipeProperties(int maxTemp, int throughput, boolean gasProof return this; } + /** + * Add Fluid Pipes to this Material. + * + * @param maxTemp The maximum temperature of Fluid that this Pipe can handle before causing damage to the + * Pipe. + * @param throughput The rate at which Fluid can flow through this Pipe. + * @param gasProof Whether this Pipe can hold Gases. If not, some Gas will be lost as it travels through the + * Pipe. + * @param acidProof Whether this Pipe can hold Acids. If not, the Pipe may lose fluid or cause damage. + * @param cryoProof Whether this Pipe can hold Cryogenic Fluids (below 120K). If not, the Pipe may lose fluid + * or cause damage. + * @param plasmaProof Whether this Pipe can hold Plasmas. If not, the Pipe may lose fluid or cause damage. + * @param insulatedByDefault Whether this Pipe is insulated by default. If not, the Pipe may cause damage when storing thermogenics/cryogenics. + */ + public Builder fluidPipeProperties(int maxTemp, int throughput, boolean gasProof, boolean acidProof, + boolean cryoProof, boolean plasmaProof, boolean insulatedByDefault) { + properties.setProperty(PropertyKey.FLUID_PIPE, + new FluidPipeProperties(maxTemp, throughput, gasProof, acidProof, cryoProof, plasmaProof, insulatedByDefault, 1)); + return this; + } + /** * Add Item Pipes to this Material. * diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/properties/FluidPipeProperties.java b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/properties/FluidPipeProperties.java index 5f0f3979a75..1b346bb3aa1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/properties/FluidPipeProperties.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/properties/FluidPipeProperties.java @@ -40,17 +40,21 @@ public class FluidPipeProperties implements IMaterialProperty, IPropertyFluidFil @Getter @Setter private boolean plasmaProof; + @Getter + @Setter + private boolean insulatedByDefault; private final Object2BooleanMap containmentPredicate = new Object2BooleanOpenHashMap<>(); public FluidPipeProperties(int maxFluidTemperature, int throughput, boolean gasProof, boolean acidProof, - boolean cryoProof, boolean plasmaProof, int channels) { + boolean cryoProof, boolean plasmaProof, boolean insulatedByDefault, int channels) { this.maxFluidTemperature = maxFluidTemperature; this.throughput = throughput; this.gasProof = gasProof; if (acidProof) setCanContain(FluidAttributes.ACID, true); this.cryoProof = cryoProof; this.plasmaProof = plasmaProof; + this.insulatedByDefault = insulatedByDefault; this.channels = channels; } @@ -59,7 +63,7 @@ public FluidPipeProperties(int maxFluidTemperature, int throughput, boolean gasP */ public FluidPipeProperties(int maxFluidTemperature, int throughput, boolean gasProof, boolean acidProof, boolean cryoProof, boolean plasmaProof) { - this(maxFluidTemperature, throughput, gasProof, acidProof, cryoProof, plasmaProof, 1); + this(maxFluidTemperature, throughput, gasProof, acidProof, cryoProof, plasmaProof, false, 1); } @Override @@ -98,6 +102,7 @@ public String toString() { ", cryoProof=" + cryoProof + ", plasmaProof=" + plasmaProof + ", channels=" + channels + + ", insulatedByDefault=" + insulatedByDefault + '}'; } diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java index 24f641a3328..d5208bb5eee 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/GTModelProperties.java @@ -20,4 +20,6 @@ public class GTModelProperties { public static final ModelProperty PIPE_BLOCKED_MASK = new ModelProperty<>(); public static final ModelProperty CHILD_MODEL_DATA = new ModelProperty<>(Objects::nonNull); + + public static final ModelProperty PIPE_INSULATED = new ModelProperty<>(); } diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java index d529223d327..cf6439f93ac 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/BakedPipeModel.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.client.model.IBlockEntityRendererBakedModel; import com.gregtechceu.gtceu.client.renderer.cover.ICoverableRenderer; import com.gregtechceu.gtceu.client.util.GTQuadTransformers; +import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; import com.gregtechceu.gtceu.common.data.GTMaterialBlocks; import com.gregtechceu.gtceu.utils.GTUtil; @@ -41,10 +42,13 @@ public class BakedPipeModel extends BaseBakedModel implements ICoverableRenderer private final Map parts; private final Map restrictors; + private final Map insulation; - public BakedPipeModel(Map parts, Map restrictors) { + public BakedPipeModel(Map parts, Map restrictors, + Map insulation) { this.parts = parts; this.restrictors = restrictors; + this.insulation = insulation; } @Override @@ -94,6 +98,12 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction ICoverableRenderer.super.renderCovers(quads, pipeNode.getCoverContainer(), pos, level, side, rand, modelData, renderType); + // render insulation overlay if the pipe is insulated and insulation map is not empty + Boolean insulated = modelData.get(GTModelProperties.PIPE_INSULATED); + if (insulated != null && insulated && !insulation.isEmpty()) { + renderInsulationOverlay(quads, connectionMask, state, side, rand, modelData, renderType); + } + if (pipeNode.getFrameMaterial().isNull()) { return quads; } @@ -143,6 +153,10 @@ public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState var builder = modelData.derive(); + if (level.getBlockEntity(pos) instanceof FluidPipeBlockEntity pipe) { + builder.with(GTModelProperties.PIPE_INSULATED, pipe.isInsulated()); + } + if (level.getBlockEntity(pos) instanceof IPipeNode pipeNode) { Map coverModelData = new EnumMap<>(Direction.class); for (Direction side : GTUtil.DIRECTIONS) { @@ -178,6 +192,25 @@ public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, Mo return ChunkRenderTypeSet.union(renderTypes, coverRenderTypes); } + private void renderInsulationOverlay(List quads, @Nullable Integer connectionMask, @Nullable BlockState state, + @Nullable Direction side, RandomSource rand, ModelData modelData, @Nullable RenderType renderType) { + BakedModel overlayCenter = insulation.get(null); + if (overlayCenter != null && (renderType == null || + (state != null && overlayCenter.getRenderTypes(state, rand, modelData).contains(renderType)))) { + quads.addAll(overlayCenter.getQuads(state, side, rand, modelData, renderType)); + } + if (connectionMask == null) return; + for (Direction dir : GTUtil.DIRECTIONS) { + if (PipeBlockEntity.isConnected(connectionMask, dir)) { + BakedModel overlayArm = insulation.get(dir); + if (overlayArm != null && (renderType == null || + (state != null && overlayArm.getRenderTypes(state, rand, modelData).contains(renderType)))) { + quads.addAll(overlayArm.getQuads(state, side, rand, modelData, renderType)); + } + } + } + } + @SuppressWarnings("deprecation") @Override public TextureAtlasSprite getParticleIcon() { @@ -192,4 +225,4 @@ public TextureAtlasSprite getParticleIcon() { @Override public void render(PipeBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {} -} +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java index 5f440b0214f..7c37d49923b 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java @@ -123,6 +123,8 @@ public static void initDynamicModels() { public @Nullable ResourceLocation sideSecondary, endSecondary; @Setter public @Nullable ResourceLocation sideOverlay, endOverlay; + @Setter + public @Nullable ResourceLocation sideInsulation; /// Use {@link #getOrCreateBlockModel()} instead of referencing this field directly. private BlockModelBuilder blockModel; @@ -184,13 +186,16 @@ protected BlockModelBuilder getOrCreateBlockModel() { return this.blockModel; } // spotless:off - return this.blockModel = this.provider.models().getBuilder(this.blockId.toString()) - // make the "default" model be based on the center part's model + var loader = this.provider.models().getBuilder(this.blockId.toString()) .parent(this.getOrCreateCenterElement()) .customLoader(PipeModelBuilder.begin(this.thickness, this.provider)) .centerModels(this.getOrCreateCenterElement().getLocation()) - .connectionModels(this.getOrCreateConnectionElement().getLocation()) - .end(); + .connectionModels(this.getOrCreateConnectionElement().getLocation()); + if (this.sideInsulation != null) { + loader.insulationTextures(this.sideInsulation); + } + return this.blockModel = loader.end(); + // make the "default" model be based on the center part's model // spotless:on } @@ -408,12 +413,13 @@ public boolean equals(Object o) { Objects.equals(sideSecondary, pipeModel.sideSecondary) && Objects.equals(endSecondary, pipeModel.endSecondary) && Objects.equals(sideOverlay, pipeModel.sideOverlay) && - Objects.equals(endOverlay, pipeModel.endOverlay); + Objects.equals(endOverlay, pipeModel.endOverlay) && + Objects.equals(sideInsulation, pipeModel.sideInsulation); } @Override public int hashCode() { - return Objects.hash(block, side, end, sideSecondary, endSecondary, sideOverlay, endOverlay); + return Objects.hash(block, side, end, sideSecondary, endSecondary, sideOverlay, endOverlay, sideInsulation); } @FunctionalInterface diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java index 9465b8f8471..66ab4bb0059 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModelLoader.java @@ -56,7 +56,19 @@ public class PipeModelLoader implements IGeometryLoader { restrictors.put(direction, MachineModelLoader.GSON.fromJson(entry.getValue(), MultiVariantModel.class)); } } + // and the insulation + final Map insulation = new HashMap<>(); + if (json.has("insulation")) { + JsonObject variantsJson = GsonHelper.getAsJsonObject(json, "insulation"); + for (Map.Entry entry : variantsJson.entrySet()) { + Direction direction = Direction.byName(entry.getKey()); + if (direction == null && !CENTER_KEYS.contains(entry.getKey().toLowerCase(Locale.ROOT))) { + throw new JsonParseException("Invalid pipe model insulation specifier " + entry.getKey()); + } + insulation.put(direction, MachineModelLoader.GSON.fromJson(entry.getValue(), MultiVariantModel.class)); + } + } - return new UnbakedPipeModel(parts, restrictors); + return new UnbakedPipeModel(parts, restrictors, insulation); } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java index 5ea5e68ac76..139c30681f2 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/UnbakedPipeModel.java @@ -21,11 +21,14 @@ public class UnbakedPipeModel implements IUnbakedGeometry { private final Map<@Nullable Direction, UnbakedModel> parts; private final Map<@NotNull Direction, UnbakedModel> restrictors; + private final Map<@Nullable Direction, UnbakedModel> insulation; public UnbakedPipeModel(Map<@Nullable Direction, UnbakedModel> parts, - Map<@NotNull Direction, UnbakedModel> restrictors) { + Map<@NotNull Direction, UnbakedModel> restrictors, + Map<@Nullable Direction, UnbakedModel> insulation) { this.parts = parts; this.restrictors = restrictors; + this.insulation = insulation; } @Override @@ -40,7 +43,11 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, this.restrictors.forEach((direction, unbaked) -> { bakedRestrictors.put(direction, unbaked.bake(baker, spriteGetter, modelState, modelLocation)); }); - return new BakedPipeModel(bakedParts, bakedRestrictors); + Map bakedInsulation = new IdentityHashMap<>(); + this.insulation.forEach((direction, unbaked) -> { + bakedInsulation.put(direction, unbaked.bake(baker, spriteGetter, modelState, modelLocation)); + }); + return new BakedPipeModel(bakedParts, bakedRestrictors, bakedInsulation); } @Override @@ -67,5 +74,15 @@ public void resolveParents(Function resolver, IG this.restrictors.put(side, variant); } }); + copy = new IdentityHashMap<>(this.insulation); + copy.forEach((side, variant) -> { + if (variant == null || variant == MISSING_MARKER) { + // replace null & markers with the actual missing model + this.insulation.put(side, missingModel); + } else { + variant.resolveParents(resolver); + this.insulation.put(side, variant); + } + }); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java index 1bf7864fd7c..58e769fe6ca 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java @@ -114,6 +114,7 @@ public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List 1) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java index c47d701c2b5..36abd1ba0f0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java @@ -14,7 +14,9 @@ import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IDataInfoProvider; import com.gregtechceu.gtceu.api.misc.IOFluidHandlerList; +import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; +import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.CustomFluidTank; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.common.cover.FluidFilterCover; @@ -74,7 +76,8 @@ public class FluidPipeBlockEntity extends PipeBlockEntity getDataInfo(PortableScannerBehavior.DisplayMode mode) { List list = new ArrayList<>(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java index a126274c421..80d167c3144 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java @@ -2554,11 +2554,11 @@ public static ItemEntry createFluidCell(Material mat, int capacit .onRegister(attach(new ImageModuleBehaviour())) .register(); - public static ItemEntry ASBESTOS_INSULATION_WRAPPER = REGISTRATE.item("asbestos_insulation_wrapper", ComponentItem::create) - .lang("Asbestos Insulation Wrapper") + public static ItemEntry INSULATION_WRAPPER = REGISTRATE.item("insulation_wrapper", ComponentItem::create) + .lang("Insulation Wrapper") .onRegister(attach(new TooltipBehavior(lines -> { - lines.add(Component.translatable("item.gtceu.asbestos_insulation_wrapper.desc")); - lines.add(Component.translatable("item.gtceu.asbestos_insulation_wrapper.usage")); + lines.add(Component.translatable("item.gtceu.insulation_wrapper.desc")); + lines.add(Component.translatable("item.gtceu.insulation_wrapper.usage")); }))) .onRegister(attach(new InsulationWrapperBehaviour())) .register(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java b/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java index 432009190f2..8be11c12c10 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/materials/ElementMaterials.java @@ -958,7 +958,7 @@ public static void register() { .element(GTElements.Nq) .rotorStats(160, 105, 4.0f, 1280) .cableProperties(V[ZPM], 2, 2) - .fluidPipeProperties(3776, 200, true, false, true, true) + .fluidPipeProperties(3776, 200, true, false, true, true, true) .blast(b -> b.temp(5000, GasTier.HIGH) .blastStats(VA[IV], 600) .vacuumStats(VA[EV], 150)) @@ -996,7 +996,7 @@ public static void register() { .toolStats(ToolProperty.Builder.of(180.0F, 100.0F, 65535, 6) .attackSpeed(0.5F).enchantability(33).magnetic().unbreakable().build()) .rotorStats(400, 250, 12.0f, 655360) - .fluidPipeProperties(100_000, 5000, true, true, true, true) + .fluidPipeProperties(100_000, 5000, true, true, true, true, true) .radioactiveHazard(10) .buildAndRegister(); @@ -1019,7 +1019,7 @@ public static void register() { .element(GTElements.Dr) .toolStats(ToolProperty.Builder.of(14.0F, 12.0F, 8192, 5) .attackSpeed(0.3F).enchantability(33).magnetic().build()) - .fluidPipeProperties(9625, 500, true, true, true, true) + .fluidPipeProperties(9625, 500, true, true, true, true, true) .buildAndRegister(); Trinium = new Material.Builder(GTCEu.id("trinium")) diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java index 1bab572d102..2a9e442e123 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/InsulationWrapperBehaviour.java @@ -1,13 +1,13 @@ package com.gregtechceu.gtceu.common.item.behavior; import com.gregtechceu.gtceu.api.item.component.IInteractionItem; +import com.gregtechceu.gtceu.api.pipenet.IPipeNode; +import com.gregtechceu.gtceu.utils.BreadthFirstBlockSearch; import com.gregtechceu.gtceu.common.block.FluidPipeBlock; import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; import com.gregtechceu.gtceu.common.data.GTItems; -import com.gregtechceu.gtceu.common.pipelike.fluidpipe.LevelFluidPipeNet; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.context.UseOnContext; @@ -27,43 +27,40 @@ public InteractionResult useOn(UseOnContext context) { } if (!(level.getBlockState(pos).getBlock() instanceof FluidPipeBlock)) { - player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.invalid_pipe"), true); + player.displayClientMessage(Component.translatable("item.gtceu.insulation_wrapper.message.invalid_pipe"), true); return InteractionResult.FAIL; } - if (!(level instanceof ServerLevel serverLevel)) return InteractionResult.PASS; + if (!(level.getBlockEntity(pos) instanceof FluidPipeBlockEntity first)) return InteractionResult.FAIL; - LevelFluidPipeNet levelNet = LevelFluidPipeNet.getOrCreate(serverLevel); - var net = levelNet.getNetFromPos(pos); - if (net == null) return InteractionResult.FAIL; + // count available wrappers in inventory + int available = player.isCreative() ? Integer.MAX_VALUE : player.getInventory().clearOrCountMatchingItems( + itemStack -> itemStack.getItem() == GTItems.INSULATION_WRAPPER.get(), + 0, player.inventoryMenu.getCraftSlots()); - // get all pipes in the network - List toInsulate = new ArrayList<>(); - for (BlockPos pipePos : net.getAllNodes().keySet()) { - if (level.getBlockEntity(pipePos) instanceof FluidPipeBlockEntity pipe) { - if (!pipe.isInsulated()) { - toInsulate.add(pipePos); - } - } + if (!player.isCreative() && available == 0) { + return InteractionResult.FAIL; } - int needed = toInsulate.size(); + // get all pipes in the network with amount of available wrappers as the limit, should function similar to spray cans + var collected = BreadthFirstBlockSearch.conditionalSearch(IPipeNode.class, first, level, IPipeNode::getBlockPos, + (parent, child, dir) -> parent == null || (parent.isConnected(dir) && child.isConnected(dir.getOpposite())), + available, Integer.MAX_VALUE); - if (!player.isCreative()) { - // already fully insulated - if (toInsulate.isEmpty()) { - player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.already_insulated"), true); - return InteractionResult.FAIL; + List toInsulate = new ArrayList<>(); + for (var node : collected) { + if (node instanceof FluidPipeBlockEntity pipe && !pipe.isInsulated()) { + toInsulate.add(pipe.getBlockPos()); } + } - // count available wrappers - int available = player.getInventory().clearOrCountMatchingItems(itemStack -> itemStack.getItem() == GTItems.ASBESTOS_INSULATION_WRAPPER.get(), 0, player.inventoryMenu.getCraftSlots()); - if (available == 0) { - return InteractionResult.FAIL; - } - needed = Math.min(available, toInsulate.size()); + if (toInsulate.isEmpty()) { + player.displayClientMessage(Component.translatable("item.gtceu.insulation_wrapper.message.already_insulated"), true); + return InteractionResult.FAIL; } + int needed = Math.min(available, toInsulate.size()); + // insulate all pipes for (int i = 0; i < needed; i++) { if (level.getBlockEntity(toInsulate.get(i)) instanceof FluidPipeBlockEntity pipe) { @@ -73,15 +70,17 @@ public InteractionResult useOn(UseOnContext context) { // clear needed amount from inventory if (!player.isCreative()){ - player.getInventory().clearOrCountMatchingItems(itemStack -> itemStack.getItem() == GTItems.ASBESTOS_INSULATION_WRAPPER.get(), needed, player.inventoryMenu.getCraftSlots()); + player.getInventory().clearOrCountMatchingItems( + itemStack -> itemStack.getItem() == GTItems.INSULATION_WRAPPER.get(), + needed, player.inventoryMenu.getCraftSlots()); } // inform if its fully insulated or partially insulated; if partial, return uninsulated amount int remaining = toInsulate.size() - needed; if (remaining > 0) { - player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.partial", needed, remaining), true); + player.displayClientMessage(Component.translatable("item.gtceu.insulation_wrapper.message.partial", needed, remaining), true); } else { - player.displayClientMessage(Component.translatable("gtceu.insulation_wrapper.success", needed), true); + player.displayClientMessage(Component.translatable("item.gtceu.insulation_wrapper.message.success", needed), true); } return InteractionResult.SUCCESS; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNet.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNet.java index 1bb6ddef095..614f24bd59c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNet.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNet.java @@ -24,6 +24,7 @@ protected void writeNodeData(FluidPipeProperties nodeData, CompoundTag tagCompou tagCompound.putBoolean("acid_proof", nodeData.isAcidProof()); tagCompound.putBoolean("cryo_proof", nodeData.isCryoProof()); tagCompound.putBoolean("plasma_proof", nodeData.isPlasmaProof()); + tagCompound.putBoolean("insulated_by_default", nodeData.isInsulatedByDefault()); tagCompound.putInt("channels", nodeData.getChannels()); } @@ -35,8 +36,9 @@ protected FluidPipeProperties readNodeData(CompoundTag tagCompound) { boolean acidProof = tagCompound.getBoolean("acid_proof"); boolean cryoProof = tagCompound.getBoolean("cryo_proof"); boolean plasmaProof = tagCompound.getBoolean("plasma_proof"); + boolean insulatedByDefault = tagCompound.getBoolean("insulated_by_default"); int channels = tagCompound.getInt("channels"); - return new FluidPipeProperties(maxTemperature, throughput, gasProof, acidProof, cryoProof, plasmaProof, + return new FluidPipeProperties(maxTemperature, throughput, gasProof, acidProof, cryoProof, plasmaProof, insulatedByDefault, channels); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java index f068dd69236..c8ba7f3116e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeType.java @@ -61,6 +61,7 @@ public FluidPipeProperties modifyProperties(FluidPipeProperties fluidPipeData) { fluidPipeData.isAcidProof(), fluidPipeData.isCryoProof(), fluidPipeData.isPlasmaProof(), + fluidPipeData.isInsulatedByDefault(), channels); } @@ -88,6 +89,19 @@ public PipeModel createPipeModel(PipeBlock block, Material material, GT } else { side = side.formatted(""); } - return new PipeModel(block, provider, thickness, GTCEu.id(side), GTCEu.id(end)); + + // insulation overlays + String insulationSide; + if (channels == 9) { + insulationSide = "block/pipe/insulation/pipe_insulation_nonuple_side"; + } else if (channels == 4) { + insulationSide = "block/pipe/insulation/pipe_insulation_quadruple_side"; + } else { + insulationSide = "block/pipe/insulation/pipe_insulation_side"; + } + + PipeModel model = new PipeModel(block, provider, thickness, GTCEu.id(side), GTCEu.id(end)); + model.setSideInsulation(GTCEu.id(insulationSide)); + return model; } -} +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java b/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java index 9b47bcbb63f..92cb2d255b3 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java @@ -236,6 +236,13 @@ private static void initItemTooltips(RegistrateLangProvider provider) { provider.add("item.gtceu.ram_chip.tooltip", "§7Random Access Memory"); provider.add("item.gtceu.soc.tooltip", "§7System on Chip"); provider.add("item.gtceu.simple_soc.tooltip", "§7Simple System on Chip"); + provider.add("item.gtceu.insulation_wrapper.message.already_insulated", "§eAll pipes in this network are already insulated"); + provider.add("item.gtceu.insulation_wrapper.message.invalid_pipe", "§eNot a fluid pipe"); + provider.add("item.gtceu.insulation_wrapper.message.partial", "§aInsulated §f%s pipe(s)§a, §f%s pipe(s) §eremain uninsulated"); + provider.add("item.gtceu.insulation_wrapper.message.success", "§aInsulated §f%s pipe(s)"); + provider.add("item.gtceu.insulation_wrapper.message.removed", "§cRemoved Insulation"); + provider.add("item.gtceu.insulation_wrapper.desc", "§bNullify damage from thermogenics/cryogenics"); + provider.add("item.gtceu.insulation_wrapper.usage", "Shift-Right-Click on fluid pipe network"); multilineLang(provider, "item.gtceu.basic_electronic_circuit.tooltip", "§7Your First Circuit\n§cLV-Tier Circuit"); multilineLang(provider, "item.gtceu.good_electronic_circuit.tooltip", diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java index 091a1564988..d894d29f076 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java @@ -1146,6 +1146,8 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.fluid_pipe.cryo_proof", "§6Can handle Cryogenics"); provider.add("gtceu.fluid_pipe.plasma_proof", "§6Can handle all Plasmas"); provider.add("gtceu.fluid_pipe.not_gas_proof", "§4Gases may leak!"); + provider.add("gtceu.fluid_pipe.insulated", "§bInsulated"); + provider.add("gtceu.fluid_pipe.insulated_by_default", "§6Pre-Insulated"); provider.add("gtceu.item_pipe.priority", "§9Priority: §f%d"); provider.add("gtceu.duct_pipe.transfer_rate", "§bAir transfer rate: %s"); provider.add("gtceu.multiblock.work_paused", "Work Paused."); @@ -1300,6 +1302,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("config.jade.plugin_gtceu.me_pattern_buffer_proxy", "[GTCEu] Pattern Buffer Proxy Info"); provider.add("config.jade.plugin_gtceu.energy_converter_provider", "[GTCEu] Energy Converter Mode"); provider.add("config.jade.plugin_gtceu.ldp_endpoint", "[GTCEu] Long Distance Pipeline Endpoint Info"); + provider.add("config.jade.plugin_gtceu.fluid_pipe_info", "[GTCEu] Fluid Pipe Info"); // gui provider.add("gtceu.button.ore_veins", "Show GT Ore Veins"); diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java index e9a72cf2c3a..9ed31c8c480 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java @@ -51,6 +51,8 @@ public static > BiFunction> modelsForDirection(@Nullable ImmutableList.of()); } + public PipeModelBuilder insulationTextures(ResourceLocation side) { + this.insulationSideTexture = side; + return this; + } + @Override public T end() { this.restrictors = getOrCreateRestrictorModels(this.provider.models(), this.thickness); + if (this.insulationSideTexture != null) { + this.insulation = makeInsulationModels(this.provider.models(), this.thickness, this.insulationSideTexture); + } return super.end(); } @@ -319,6 +329,21 @@ public JsonObject toJson(JsonObject json) { json.add("restrictors", restrictors); } + // build json for insulation + if (this.insulation != null) { + final JsonObject insulation = new JsonObject(); + for (int i = 0; i < GTUtil.DIRECTIONS.length; i++) { + Direction dir = GTUtil.DIRECTIONS[i]; + insulation.add(dir.getName(), configuredModelToJSON(ConfiguredModel.builder() + .modelFile(new ModelFile.UncheckedModelFile(this.insulation[i].getLocation())) + .buildLast(), false)); + } + insulation.add(PipeModelLoader.PRIMARY_CENTER_KEY, configuredModelToJSON(ConfiguredModel.builder() + .modelFile(new ModelFile.UncheckedModelFile(this.insulation[GTUtil.DIRECTIONS.length].getLocation())) + .buildLast(), false)); + json.add("insulation", insulation); + } + return json; } @@ -331,6 +356,66 @@ private static BlockModelBuilder[] getOrCreateRestrictorModels(BlockModelProvide private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer .memoizeFunctionWeakIdent(PipeModelBuilder::makeRestrictorModels); + private static BlockModelBuilder[] makeInsulationModels(BlockModelProvider provider, float thickness, ResourceLocation sideTexture) { + BlockModelBuilder[] models = new BlockModelBuilder[GTUtil.DIRECTIONS.length + 1]; + + float min = (16.0f - thickness) / 2.0f - 0.003f; + float max = min + thickness + 0.006f; // offset by 0.003 * 2 + + String suffix = sideTexture.getPath().substring(sideTexture.getPath().lastIndexOf('/') + 1); + + for (Direction dir : GTUtil.DIRECTIONS) { + String modelPath = "block/pipe/insulation/" + suffix + "/" + dir.getName() + "/thickness_" + thickness; + ResourceLocation modelName = GTCEu.id(modelPath); + if (provider.generatedModels.containsKey(modelName)) { + models[dir.ordinal()] = provider.generatedModels.get(modelName); + continue; + } + + var coords = GTMath.getCoordinates(dir, min, max); + Vector3f minPos = coords.getLeft(); + Vector3f maxPos = coords.getRight(); + + BlockModelBuilder model = provider.getBuilder(modelPath); + model.texture("insulation_side", sideTexture) + .renderType(new ResourceLocation("translucent")) + .element() + .from(minPos.x, minPos.y, minPos.z) + .to(maxPos.x, maxPos.y, maxPos.z) + .face(getSideAtBorder(dir, Border.BOTTOM)).end() + .face(getSideAtBorder(dir, Border.TOP)).end() + .face(getSideAtBorder(dir, Border.LEFT)).end() + .face(getSideAtBorder(dir, Border.RIGHT)).end() + .faces((face, builder) -> builder.texture("#insulation_side")) + .end(); + models[dir.ordinal()] = model; + } + + // center overlay + String centerPath = "block/pipe/insulation/" + suffix + "/center/thickness_" + thickness; + ResourceLocation centerName = GTCEu.id(centerPath); + if (provider.generatedModels.containsKey(centerName)) { + models[GTUtil.DIRECTIONS.length] = provider.generatedModels.get(centerName); + } else { + BlockModelBuilder center = provider.getBuilder(centerPath); + center.texture("insulation_side", sideTexture) + .renderType(new ResourceLocation("translucent")) + .element() + .from(min, min, min) + .to(max, max, max) + .face(Direction.DOWN).end() + .face(Direction.UP).end() + .face(Direction.NORTH).end() + .face(Direction.SOUTH).end() + .face(Direction.WEST).end() + .face(Direction.EAST).end() + .faces((face, builder) -> builder.texture("#insulation_side")) + .end(); + models[GTUtil.DIRECTIONS.length] = center; + } + return models; + } + private static BlockModelBuilder[] makeRestrictorModels(BlockModelProvider provider, float thickness) { BlockModelBuilder[] models = new BlockModelBuilder[GTUtil.DIRECTIONS.length]; @@ -434,4 +519,4 @@ private enum Border { mask = 1 << this.ordinal(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/AssemblerRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/AssemblerRecipeLoader.java index 7c19fc75c65..5c736dd73fc 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/AssemblerRecipeLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/AssemblerRecipeLoader.java @@ -271,5 +271,13 @@ public static void init(Consumer provider) { .inputItems(ring, PolyvinylChloride, 1) .outputItems(HAZMAT_HELMET) .save(provider); + + // insulation wrapper + ASSEMBLER_RECIPES.recipeBuilder("insulation_wrapper") + .inputItems(dust, Asbestos, 6) + .inputItems(Items.WHITE_WOOL, 2) + .inputItems(foil, Steel, 1) + .outputItems(INSULATION_WRAPPER) + .duration(80).EUt(VA[LV]).save(provider); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java index 2451c4af372..b80d83dccd7 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComponentRecipes.java @@ -7,7 +7,6 @@ import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper; import net.minecraft.data.recipes.FinishedRecipe; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -1132,16 +1131,5 @@ public static void init(Consumer provider) { .EUt(VA[ZPM])) .duration(600).EUt(100000) .addMaterialInfo(true).save(provider); - - // Insulation Wrapper Start----------------------------------------------------------------------------------------- - VanillaRecipeHelper.addShapedRecipe(provider, true, "asbestos_insulation_wrapper", ASBESTOS_INSULATION_WRAPPER.asStack(), "DDD", "WFW", "DDD", - 'D', new MaterialEntry(dust, Asbestos), 'W', new ItemStack(Items.WHITE_WOOL), 'F', new MaterialEntry(foil, Steel)); - - ASSEMBLER_RECIPES.recipeBuilder("asbestos_insulation_wrapper") - .inputItems(dust, Asbestos, 6) - .inputItems(Items.WHITE_WOOL) - .inputItems(foil, Steel, 1) - .outputItems(ASBESTOS_INSULATION_WRAPPER) - .duration(80).EUt(VA[LV]).save(provider); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CraftingRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CraftingRecipeLoader.java index 1d2936362ba..2d0b2a722b2 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CraftingRecipeLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/CraftingRecipeLoader.java @@ -56,6 +56,10 @@ public static void init(Consumer provider) { VanillaRecipeHelper.addShapelessRecipe(provider, "programmed_circuit", PROGRAMMED_CIRCUIT.asStack(), CustomTags.LV_CIRCUITS); + // insulation wrapper + VanillaRecipeHelper.addShapedRecipe(provider, true, "insulation_wrapper", INSULATION_WRAPPER.asStack(), "DDD", "WFW", "DDD", + 'D', new MaterialEntry(dust, Asbestos), 'W', new ItemStack(Items.WHITE_WOOL), 'F', new MaterialEntry(foil, Steel)); + VanillaRecipeHelper.addShapedRecipe(provider, "item_filter", ITEM_FILTER.asStack(), "XXX", "XYX", "XXX", 'X', new MaterialEntry(foil, Zinc), 'Y', new MaterialEntry(plate, Steel)); VanillaRecipeHelper.addShapedRecipe(provider, "fluid_filter_lapis", FLUID_FILTER.asStack(), "XXX", "XYX", "XXX", diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_nonuple_side.png b/src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_nonuple_side.png new file mode 100644 index 0000000000000000000000000000000000000000..f15aa2d5f726454583d30a4405005ecbd20add40 GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP_o1|q9iy!t)x7$D3u`~F*C13&(AeP!Bo#s z&(KJi(Y*wyXh&*iasoR83s9|rk+A{e0*JXFJ6RV%%$f#dg8&oI zWG1l6AWI7%3#!Y|zyKuMT(2)vbm8)SAoGf+i(`m||I%PXzGefSJ+F^MDYl)GJ3Zv-`l&hqW^K=Z`<`5*C=)${@tB{vFI{-zLNOL|-{1h|ll;xS8h$qwcmEb(o1Wk)<$0yF!R3-!%kJejM82h9?o(y#II$&o-p2>n*Th z*VsJ4OmfF>2P65v*{u>P4^HdOkxrdc;}d)Rp^}ofziFSYykFgSi`*>?2eRTGe3 NJzf1=);T3K0RVw~oe%&3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_quadruple_side.png b/src/main/resources/assets/gtceu/textures/block/pipe/insulation/pipe_insulation_quadruple_side.png new file mode 100644 index 0000000000000000000000000000000000000000..0e8e35951b9524b08d4cf0ea53cbe7ae88088195 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP_o1|q9iy!t)x7$D3u`~F*C13&(AeP!Bo#s z&(KJi(Y*wyXh&*iasoR83s9|rk+A{e0*JXFJ6RV%%$f#dg8&oI zWG1l6AWI7%3#!Y|zyKuMT(2)vbm8)SV8|GGx;Tbd_%EHj-;3E%;8^`+>l2!SEo&c5 zOXvHnaFC@Rzs;1sXBU{$ufKn;7noSW`f8QeBo)2|*I!#UxGhfH)Z(}NF~cDP z6NY)uB?V7%|JXNQS@%$dO&M#WMc?D!?Zl$5) znjAK4+sAq{ilag4@?DYlhaY-7DtHP#ue=wec_zuV<(!@wI_k_8T+Q3hxPq&l{kN#1DnnIqwYkP$ zgSG$P9Xb@KH=TL5YOkC8c^#?Lus=SI0s)(@eM|4#FOm8D*LiasoR83s9|rk+A{e0*JXFJ6RV%%$f#dg8&oI zWG1l6AWI7%3#!Y|zyKuMT(2)vbm8)SAak*&i(`m||J=zNxmpc)T+fSg>3#kGe{=VP zg8P#?_^#S)ZfTkK?1B)Z?2VsduZtS_Z~sqeh;`W9yTo+&Q3;1=1{GO`ZK>6pbrYD+ z-TF3duf=VKY1xAB4OL1LZoD&G=`A(g`1ys|2f63e&X5#&@a8-(SHXO#kOwv0D;*i< zNrxodE@t)=dEnkG_*J;ZSl~i~a{juux3)c*8~J|C^Mle~kK1&P0fqo4SFV N?&<31vd$@?2>|u;hHn4> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/item/asbestos_insulation_wrapper.png b/src/main/resources/assets/gtceu/textures/item/insulation_wrapper.png similarity index 100% rename from src/main/resources/assets/gtceu/textures/item/asbestos_insulation_wrapper.png rename to src/main/resources/assets/gtceu/textures/item/insulation_wrapper.png From f81c5d4b5db8257c957ca718c196189d7434050c Mon Sep 17 00:00:00 2001 From: syticchan Date: Mon, 18 May 2026 12:09:22 +0700 Subject: [PATCH 3/3] Delete an excess setChanged() due to oversight --- .../gtceu/common/blockentity/FluidPipeBlockEntity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java index 36abd1ba0f0..85822deb875 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/FluidPipeBlockEntity.java @@ -31,7 +31,6 @@ import com.gregtechceu.gtceu.utils.GTUtil; import lombok.Getter; -import lombok.Setter; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -510,7 +509,6 @@ public static void setNeighboursToFire(Level world, BlockPos selfPos) { public void setInsulated(boolean insulated) { this.insulated = insulated; - setChanged(); syncDataHolder.markClientSyncFieldDirty("insulated"); }