From 0e3c713b30feb6bc578343452cb9336fa75edcab Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Mon, 13 Jul 2026 11:56:06 +0100 Subject: [PATCH 01/61] Change battery buffer jade to show per tick instead of per second (#5094) --- src/generated/resources/assets/gtceu/lang/en_ud.json | 2 +- src/generated/resources/assets/gtceu/lang/en_us.json | 2 +- .../java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java | 2 +- .../integration/jade/provider/BatteryStorageInfoProvider.java | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 9886bffe178..5124360555a 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -2579,7 +2579,7 @@ "gtceu.item_pipe.priority": "%dɟ§ :ʎʇıɹoıɹԀ6§", "gtceu.jade.amperage_use": "Ɐ %s", "gtceu.jade.at": " @ ", - "gtceu.jade.changes_eu_sec": "s/∩Ǝ %s", + "gtceu.jade.changes_eu_tick": "ʇ/∩Ǝ %s", "gtceu.jade.cleaned_this_second": "s/%s :pɹɐzɐɥ pǝuɐǝןƆ", "gtceu.jade.days": "sʎɐp %s", "gtceu.jade.energy_stored": "∩Ǝ %d / %d", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index bd37696835a..2dbe8c0231a 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -2579,7 +2579,7 @@ "gtceu.item_pipe.priority": "§9Priority: §f%d", "gtceu.jade.amperage_use": "%s A", "gtceu.jade.at": " @ ", - "gtceu.jade.changes_eu_sec": "%s EU/s", + "gtceu.jade.changes_eu_tick": "%s EU/t", "gtceu.jade.cleaned_this_second": "Cleaned hazard: %s/s", "gtceu.jade.days": "%s days", "gtceu.jade.energy_stored": "%d / %d EU", diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java b/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java index 6911969bd37..8e2f4d86ce3 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java @@ -105,7 +105,7 @@ private static void initWailaLikeLang(RegistrateLangProvider provider) { provider.add("gtceu.jade.at", " @ "); provider.add("gtceu.jade.remaining_charge_time", "Until charged: %s"); provider.add("gtceu.jade.remaining_discharge_time", "Until empty: %s"); - provider.add("gtceu.jade.changes_eu_sec", "%s EU/s"); + provider.add("gtceu.jade.changes_eu_tick", "%s EU/t"); provider.add("gtceu.jade.seconds", "%s seconds"); provider.add("gtceu.jade.minutes", "%s minutes"); provider.add("gtceu.jade.hours", "%s hours"); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/BatteryStorageInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/BatteryStorageInfoProvider.java index 3e6105f8314..35accf4bb55 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/BatteryStorageInfoProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/BatteryStorageInfoProvider.java @@ -7,6 +7,7 @@ import com.gregtechceu.gtceu.api.capability.IEnergyContainer; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.common.machine.electric.BatteryBufferMachine; +import com.gregtechceu.gtceu.utils.FormattingUtil; import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.nbt.CompoundTag; @@ -51,7 +52,8 @@ protected void addTooltip(CompoundTag data, ITooltip tooltip, Player player, Blo CompoundTag container = data.getCompound("energy"); long changed = container.getLong("changed"), stored = container.getLong("stored"), capacity = container.getLong("capacity"); - tooltip.add(Component.translatable("gtceu.jade.changes_eu_sec", formatLongNumber(changed))); + tooltip.add(Component.translatable("gtceu.jade.changes_eu_tick", + FormattingUtil.formatNumbers(((double) changed) / 20.0))); if (changed > 0L) { tooltip.add(Component .translatable("gtceu.jade.remaining_charge_time", From 1fa0b093385e64404fa34da558efdd96cdc223a9 Mon Sep 17 00:00:00 2001 From: n1xx1 Date: Mon, 13 Jul 2026 12:57:26 +0200 Subject: [PATCH 02/61] Add grid connection info on Jade for ME parts (#4976) --- .../resources/assets/gtceu/lang/en_ud.json | 1 + .../resources/assets/gtceu/lang/en_us.json | 1 + .../gtceu/data/lang/LangHandler.java | 1 + .../gtceu/integration/jade/GTJadePlugin.java | 6 ++- .../provider/MEGridConnectedProvider.java | 41 +++++++++++++++++++ 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEGridConnectedProvider.java diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 5124360555a..106d0cb0343 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -1969,6 +1969,7 @@ "config.jade.plugin_gtceu.ldp_endpoint": "oɟuI ʇuıodpuƎ ǝuıןǝdıԀ ǝɔuɐʇsıᗡ buoꞀ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.machine_mode": "ǝpoW ǝuıɥɔɐW ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.maintenance_info": "oɟuI ǝɔuɐuǝʇuıɐW ]nƎƆ⟘⅁[", + "config.jade.plugin_gtceu.me_grid_connected": "oɟuI ǝuıɥɔɐW pǝʇɔǝuuoƆ pıɹ⅁ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.me_pattern_buffer": "oɟuI ɹǝɟɟnᗺ uɹǝʇʇɐԀ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.me_pattern_buffer_proxy": "oɟuI ʎxoɹԀ ɹǝɟɟnᗺ uɹǝʇʇɐԀ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.multiblock_structure": "ǝɹnʇɔnɹʇS ʞɔoןᗺıʇןnW ]nƎƆ⟘⅁[", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 2dbe8c0231a..6df52a555fa 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -1969,6 +1969,7 @@ "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", + "config.jade.plugin_gtceu.me_grid_connected": "[GTCEu] Grid Connected Machine Info", "config.jade.plugin_gtceu.me_pattern_buffer": "[GTCEu] Pattern Buffer Info", "config.jade.plugin_gtceu.me_pattern_buffer_proxy": "[GTCEu] Pattern Buffer Proxy Info", "config.jade.plugin_gtceu.multiblock_structure": "[GTCEu] MultiBlock Structure", 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 9bbc2a56977..e006a2ef03b 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java @@ -1319,6 +1319,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("config.jade.plugin_gtceu.data_bank", "[GTCEu] Data Bank Info"); provider.add("config.jade.plugin_gtceu.transformer", "[GTCEu] Transformer Info"); provider.add("config.jade.plugin_gtceu.stained_color", "[GTCEu] Stained Block Info"); + provider.add("config.jade.plugin_gtceu.me_grid_connected", "[GTCEu] Grid Connected Machine Info"); provider.add("config.jade.plugin_gtceu.me_pattern_buffer", "[GTCEu] Pattern Buffer Info"); 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"); 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 1e815f64a71..3570040f874 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java @@ -46,7 +46,8 @@ public void register(IWailaCommonRegistration registration) { new LDPEndpointProvider()); if (GTCEu.Mods.isAE2Loaded()) { - register(registration, new MEPatternBufferProvider(), new MEPatternBufferProxyProvider()); + register(registration, new MEGridConnectedProvider(), new MEPatternBufferProvider(), + new MEPatternBufferProxyProvider()); } registration.registerItemStorage(GTItemStorageProvider.INSTANCE, MetaMachine.class); @@ -80,7 +81,8 @@ public void registerClient(IWailaClientRegistration registration) { new CableBlockProvider()); if (GTCEu.Mods.isAE2Loaded()) { - register(registration, new MEPatternBufferProvider(), new MEPatternBufferProxyProvider()); + register(registration, new MEGridConnectedProvider(), new MEPatternBufferProvider(), + new MEPatternBufferProxyProvider()); } registration.registerItemStorageClient(GTItemStorageProvider.INSTANCE); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEGridConnectedProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEGridConnectedProvider.java new file mode 100644 index 00000000000..1373e0504bd --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEGridConnectedProvider.java @@ -0,0 +1,41 @@ +package com.gregtechceu.gtceu.integration.jade.provider; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.feature.IGridConnectedMachine; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.entity.BlockEntity; + +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.ITooltip; +import snownee.jade.api.config.IPluginConfig; + +public class MEGridConnectedProvider extends MachineInfoProvider { + + public MEGridConnectedProvider() { + super(GTCEu.id("me_grid_connected"), MetaMachine.class); + } + + @Override + protected CompoundTag write(MetaMachine machine) { + var tag = new CompoundTag(); + if (!(machine instanceof IGridConnectedMachine gridConnectedMachine)) return tag; + + tag.putBoolean("online", gridConnectedMachine.isOnline()); + return tag; + } + + @Override + protected void addTooltip(CompoundTag data, ITooltip tooltip, Player player, BlockAccessor block, + BlockEntity blockEntity, IPluginConfig config) { + if (!data.contains("online")) return; + + var online = data.getBoolean("online"); + var component = online ? Component.translatable("gtceu.gui.me_network.online") : + Component.translatable("gtceu.gui.me_network.offline"); + tooltip.add(component); + } +} From e90779100cd65a76abd32c2334d38ffe08719a50 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:46:40 +0300 Subject: [PATCH 03/61] Clean up janky worldgen `DeferredRegister`s --- .../generator/veins/VeinedVeinGenerator.java | 11 ++-- .../worldgen/modifier/BiomePlacement.java | 9 +-- .../worldgen/modifier/DimensionFilter.java | 17 ++---- .../worldgen/modifier/FrequencyModifier.java | 10 +--- .../gtceu/api/registry/GTRegistries.java | 27 --------- .../gregtechceu/gtceu/common/CommonProxy.java | 5 +- .../gtceu/common/data/GTBlocks.java | 1 + .../gtceu/common/data/GTFeatures.java | 33 +++-------- .../common/data/GTValueProviderTypes.java | 32 ++++------- .../data/{ => worldgen}/GTBiomeModifiers.java | 10 ++-- .../{ => worldgen}/GTConfiguredFeatures.java | 57 ++++++++++++------- .../GTDensityFunctions.java} | 32 +++++++---- .../GTPlacedFeatures.java} | 19 +++---- .../data/worldgen/GTPlacementModifiers.java | 30 ++++++++++ .../modifier/RubberTreeChancePlacement.java | 11 +--- .../gtceu/data/DataGenerators.java | 10 ++-- 16 files changed, 141 insertions(+), 173 deletions(-) rename src/main/java/com/gregtechceu/gtceu/common/data/{ => worldgen}/GTBiomeModifiers.java (91%) rename src/main/java/com/gregtechceu/gtceu/common/data/{ => worldgen}/GTConfiguredFeatures.java (52%) rename src/main/java/com/gregtechceu/gtceu/common/data/{GTWorldgen.java => worldgen/GTDensityFunctions.java} (51%) rename src/main/java/com/gregtechceu/gtceu/common/data/{GTPlacements.java => worldgen/GTPlacedFeatures.java} (85%) create mode 100644 src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java index 502a12d15e4..0dbb7c6127b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java @@ -7,7 +7,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.ores.OreBlockPlacer; import com.gregtechceu.gtceu.api.data.worldgen.ores.OreVeinUtil; import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.common.data.GTFeatures; +import com.gregtechceu.gtceu.common.data.worldgen.GTDensityFunctions; import com.gregtechceu.gtceu.utils.GTUtil; import com.gregtechceu.gtceu.utils.WeightedEntry; @@ -116,8 +116,7 @@ public Map generate(WorldGenLevel level, RandomSource BlockPos origin) { Map generatedBlocks = new Object2ObjectOpenHashMap<>(); - Registry densityFunctions = level.registryAccess() - .registry(Registries.DENSITY_FUNCTION).get(); + Registry densityFunctions = level.registryAccess().registry(Registries.DENSITY_FUNCTION).get(); RandomState randomState = level.getLevel().getChunkSource().randomState(); Blender blender; @@ -128,15 +127,13 @@ public Map generate(WorldGenLevel level, RandomSource } final Blender finalizedBlender = blender; - DensityFunction veinToggle = mapToNoise(densityFunctions.get(GTFeatures.NEW_ORE_VEIN_TOGGLE), randomState); - DensityFunction veinRidged = mapToNoise(densityFunctions.get(GTFeatures.NEW_ORE_VEIN_RIDGED), randomState); + DensityFunction veinToggle = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_TOGGLE), randomState); + DensityFunction veinRidged = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_RIDGED), randomState); int size = entry.clusterSize().sample(random); int radius = Mth.ceil(size / 2f); - int placedCount = 0; - int randOffsetX = random.nextInt(16); int randOffsetY = random.nextInt(16); int randOffsetZ = random.nextInt(16); diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java index db84648121d..67b8aa7aaf3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java @@ -1,11 +1,9 @@ package com.gregtechceu.gtceu.api.data.worldgen.modifier; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; -import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.util.RandomSource; import net.minecraft.world.level.levelgen.placement.PlacementContext; import net.minecraft.world.level.levelgen.placement.PlacementModifier; @@ -18,9 +16,6 @@ public class BiomePlacement extends PlacementModifier { - public static final PlacementModifierType BIOME_PLACEMENT = GTRegistries.register( - BuiltInRegistries.PLACEMENT_MODIFIER_TYPE, GTCEu.id("biome_placement"), () -> BiomePlacement.CODEC); - public static final Codec CODEC = BiomeWeightModifier.CODEC.listOf().fieldOf("modifiers") .xmap(BiomePlacement::new, placement -> placement.modifiers).codec(); @@ -45,6 +40,6 @@ public Stream getPositions(PlacementContext context, RandomSource rand @Override public PlacementModifierType type() { - return BIOME_PLACEMENT; + return GTPlacementModifiers.BIOME_PLACEMENT.get(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java index 1d2d3269372..ee3640b4ae4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java @@ -1,12 +1,9 @@ package com.gregtechceu.gtceu.api.data.worldgen.modifier; -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.registry.GTRegistries; - +import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryCodecs; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.util.RandomSource; import net.minecraft.world.level.dimension.DimensionType; @@ -19,13 +16,11 @@ public class DimensionFilter extends PlacementFilter { - public static final PlacementModifierType DIMENSION_FILTER = GTRegistries - .register(BuiltInRegistries.PLACEMENT_MODIFIER_TYPE, GTCEu.id("dimension"), () -> DimensionFilter.CODEC); - + // spotless:off public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - RegistryCodecs.homogeneousList(Registries.DIMENSION_TYPE).fieldOf("dimension_id") - .forGetter(filter -> filter.dimensionId)) - .apply(instance, DimensionFilter::new)); + RegistryCodecs.homogeneousList(Registries.DIMENSION_TYPE).fieldOf("dimension_id").forGetter(filter -> filter.dimensionId) + ).apply(instance, DimensionFilter::new)); + // spotless:on public HolderSet dimensionId; @@ -40,6 +35,6 @@ protected boolean shouldPlace(PlacementContext context, RandomSource random, Blo @Override public PlacementModifierType type() { - return DIMENSION_FILTER; + return GTPlacementModifiers.DIMENSION_FILTER.get(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java index f659cb34b01..e38124d0124 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java @@ -1,11 +1,8 @@ package com.gregtechceu.gtceu.api.data.worldgen.modifier; -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.registry.GTRegistries; - +import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; @@ -23,9 +20,6 @@ @MethodsReturnNonnullByDefault public class FrequencyModifier extends PlacementModifier { - public static final PlacementModifierType FREQUENCY_MODIFIER = GTRegistries - .register(BuiltInRegistries.PLACEMENT_MODIFIER_TYPE, GTCEu.id("frequency"), () -> FrequencyModifier.CODEC); - public static final Codec CODEC = ExtraCodecs.POSITIVE_FLOAT.fieldOf("chance") .xmap(FrequencyModifier::new, (modifier) -> modifier.frequency).codec(); @@ -51,6 +45,6 @@ public int getCount(float frequency, RandomSource random) { @Override public PlacementModifierType type() { - return FREQUENCY_MODIFIER; + return GTPlacementModifiers.FREQUENCY_MODIFIER.get(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java index 12117c6427f..e5bc9fd4e7a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java @@ -31,16 +31,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType; -import net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacerType; -import net.minecraft.world.level.levelgen.placement.PlacementModifierType; -import net.minecraftforge.common.loot.IGlobalLootModifier; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; -import com.mojang.serialization.Codec; import org.jetbrains.annotations.ApiStatus; public final class GTRegistries { @@ -83,11 +75,6 @@ public final class GTRegistries { GTCEu.id("pattern_errors")); - - public static final DeferredRegister> TRUNK_PLACER_TYPE = DeferredRegister.create(Registries.TRUNK_PLACER_TYPE, GTCEu.MOD_ID); - public static final DeferredRegister> PLACEMENT_MODIFIER = DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, GTCEu.MOD_ID); - public static final DeferredRegister> GLOBAL_LOOT_MODIFIES = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, GTCEu.MOD_ID); - // spotless:on public static T register(Registry registry, ResourceLocation name, T value) { @@ -97,14 +84,6 @@ public static T register(Registry registry, ResourceLocation ForgeRegistries.RECIPE_TYPES.register(name, (RecipeType) value); } else if (registryKey == Registries.RECIPE_SERIALIZER) { ForgeRegistries.RECIPE_SERIALIZERS.register(name, (RecipeSerializer) value); - } else if (registryKey == Registries.FEATURE) { - ForgeRegistries.FEATURES.register(name, (Feature) value); - } else if (registryKey == Registries.FOLIAGE_PLACER_TYPE) { - ForgeRegistries.FOLIAGE_PLACER_TYPES.register(name, (FoliagePlacerType) value); - } else if (registryKey == Registries.TRUNK_PLACER_TYPE) { - TRUNK_PLACER_TYPE.register(name.getPath(), () -> (TrunkPlacerType) value); - } else if (registryKey == Registries.PLACEMENT_MODIFIER_TYPE) { - PLACEMENT_MODIFIER.register(name.getPath(), () -> (PlacementModifierType) value); } else { return Registry.register(registry, name, value); } @@ -112,12 +91,6 @@ public static T register(Registry registry, ResourceLocation return value; } - public static void init(IEventBus eventBus) { - TRUNK_PLACER_TYPE.register(eventBus); - PLACEMENT_MODIFIER.register(eventBus); - GLOBAL_LOOT_MODIFIES.register(eventBus); - } - private static final RegistryAccess BLANK = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); private static RegistryAccess FROZEN = BLANK; diff --git a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java index 8904d0ba326..6add9e55d08 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java +++ b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java @@ -30,6 +30,7 @@ import com.gregtechceu.gtceu.common.data.machines.GTMachineUtils; import com.gregtechceu.gtceu.common.data.materials.AlloyBlastPropertyAddition; import com.gregtechceu.gtceu.common.data.materials.GTFoods; +import com.gregtechceu.gtceu.common.data.worldgen.*; import com.gregtechceu.gtceu.common.item.tool.rotation.CustomBlockRotations; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FusionReactorMachine; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; @@ -103,7 +104,7 @@ public CommonProxy() { } GTValueProviderTypes.init(eventBus); - GTRegistries.init(eventBus); + GTPlacementModifiers.init(eventBus); GTFeatures.init(eventBus); GTCommandArguments.init(eventBus); GTMobEffects.init(eventBus); @@ -183,8 +184,6 @@ public static void init() { VeinGenerators.registerAddonGenerators(); IndicatorGenerators.registerAddonGenerators(); - GTFeatures.init(); - GTFeatures.register(); CustomBlockRotations.init(); KeyBind.init(); SyncedKeyMappings.init(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java index 18797fb01e5..008e1165264 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java @@ -21,6 +21,7 @@ import com.gregtechceu.gtceu.common.block.explosive.PowderbarrelBlock; import com.gregtechceu.gtceu.common.data.blocks.GTDevBlocks; import com.gregtechceu.gtceu.common.data.models.GTModels; +import com.gregtechceu.gtceu.common.data.worldgen.GTConfiguredFeatures; import com.gregtechceu.gtceu.common.item.LampBlockItem; import com.gregtechceu.gtceu.common.item.LaserPipeBlockItem; import com.gregtechceu.gtceu.common.pipelike.duct.DuctPipeType; diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java index e888a9636f8..f1fa0827b8e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java @@ -1,45 +1,26 @@ package com.gregtechceu.gtceu.common.data; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.DimensionFilter; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.FrequencyModifier; import com.gregtechceu.gtceu.common.worldgen.feature.FluidSproutFeature; import com.gregtechceu.gtceu.common.worldgen.feature.StoneBlobFeature; -import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; public class GTFeatures { + // spotless:off - public static final ResourceLocation NEW_ORE_VEIN_TOGGLE = GTCEu.id("vein_toggle"); - public static final ResourceLocation NEW_ORE_VEIN_RIDGED = GTCEu.id("vein_ridged"); + public static final DeferredRegister> FEATURES = DeferredRegister.create(Registries.FEATURE, GTCEu.MOD_ID); - public static final DeferredRegister> FEATURE_REGISTER = DeferredRegister.create(Registries.FEATURE, - GTCEu.MOD_ID); + public static final RegistryObject STONE_BLOB = FEATURES.register("stone_blob", StoneBlobFeature::new); + public static final RegistryObject FLUID_SPROUT = FEATURES.register("fluid_sprout", FluidSproutFeature::new); - public static final RegistryObject STONE_BLOB = FEATURE_REGISTER.register("stone_blob", - StoneBlobFeature::new); - public static final RegistryObject FLUID_SPROUT = FEATURE_REGISTER.register("fluid_sprout", - FluidSproutFeature::new); + // spotless:on - public static void init() { - Object inst = FrequencyModifier.FREQUENCY_MODIFIER; // seemingly useless access to init the class in time - inst = DimensionFilter.DIMENSION_FILTER; - inst = BiomePlacement.BIOME_PLACEMENT; - inst = RubberTreeChancePlacement.RUBBER_TREE_CHANCE_PLACEMENT; - } - - public static void init(IEventBus modEventBus) { - FEATURE_REGISTER.register(modEventBus); - } - - public static void register() { - // no-op + public static void init(IEventBus modBus) { + FEATURES.register(modBus); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTValueProviderTypes.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTValueProviderTypes.java index f428739d5ca..b9d943c01d1 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTValueProviderTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTValueProviderTypes.java @@ -15,26 +15,18 @@ public class GTValueProviderTypes { - public static final DeferredRegister> INT_PROVIDER_TYPE_REGISTER = DeferredRegister.create( - Registries.INT_PROVIDER_TYPE, - GTCEu.MOD_ID); - public static final DeferredRegister> FLOAT_PROVIDER_TYPE_REGISTER = DeferredRegister.create( - Registries.FLOAT_PROVIDER_TYPE, - GTCEu.MOD_ID); - - public static final RegistryObject> FLOORED = INT_PROVIDER_TYPE_REGISTER.register( - "floored", - () -> () -> FlooredInt.CODEC); - - public static final RegistryObject> MULTIPLIED = FLOAT_PROVIDER_TYPE_REGISTER - .register("multiplied", - () -> () -> MultipliedFloat.CODEC); - public static final RegistryObject> ADDED = FLOAT_PROVIDER_TYPE_REGISTER.register( - "added", - () -> () -> AddedFloat.CODEC); - public static final RegistryObject> CASTED = FLOAT_PROVIDER_TYPE_REGISTER.register( - "casted", - () -> () -> CastedFloat.CODEC); + // spotless:off + public static final DeferredRegister> INT_PROVIDER_TYPE_REGISTER = DeferredRegister.create(Registries.INT_PROVIDER_TYPE, GTCEu.MOD_ID); + public static final DeferredRegister> FLOAT_PROVIDER_TYPE_REGISTER = DeferredRegister.create(Registries.FLOAT_PROVIDER_TYPE, GTCEu.MOD_ID); + + + public static final RegistryObject> FLOORED = INT_PROVIDER_TYPE_REGISTER.register("floored", () -> () -> FlooredInt.CODEC); + + public static final RegistryObject> MULTIPLIED = FLOAT_PROVIDER_TYPE_REGISTER.register("multiplied", () -> () -> MultipliedFloat.CODEC); + public static final RegistryObject> ADDED = FLOAT_PROVIDER_TYPE_REGISTER.register("added", () -> () -> AddedFloat.CODEC); + public static final RegistryObject> CASTED = FLOAT_PROVIDER_TYPE_REGISTER.register("casted", () -> () -> CastedFloat.CODEC); + + // spotless:on public static void init(IEventBus bus) { INT_PROVIDER_TYPE_REGISTER.register(bus); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTBiomeModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTBiomeModifiers.java similarity index 91% rename from src/main/java/com/gregtechceu/gtceu/common/data/GTBiomeModifiers.java rename to src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTBiomeModifiers.java index fa261face25..e118537d9a3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTBiomeModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTBiomeModifiers.java @@ -1,4 +1,4 @@ -package com.gregtechceu.gtceu.common.data; +package com.gregtechceu.gtceu.common.data.worldgen; import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.data.recipe.CustomTags; @@ -29,21 +29,21 @@ public static void bootstrap(BootstapContext ctx) { HolderGetter placedFeatureRegistry = ctx.lookup(Registries.PLACED_FEATURE); HolderSet biomes = biomeLookup.getOrThrow(CustomTags.HAS_RUBBER_TREE); - Holder rubberTree = placedFeatureRegistry.getOrThrow(GTPlacements.RUBBER_CHECKED); + Holder rubberTree = placedFeatureRegistry.getOrThrow(GTPlacedFeatures.RUBBER_CHECKED); ctx.register(RUBBER, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes, HolderSet.direct(rubberTree), GenerationStep.Decoration.VEGETAL_DECORATION)); HolderSet overworld = biomeLookup.getOrThrow(BiomeTags.IS_OVERWORLD); - Holder redGraniteBlob = placedFeatureRegistry.getOrThrow(GTPlacements.RED_GRANITE_BLOB); - Holder marbleBlob = placedFeatureRegistry.getOrThrow(GTPlacements.MARBLE_BLOB); + Holder redGraniteBlob = placedFeatureRegistry.getOrThrow(GTPlacedFeatures.RED_GRANITE_BLOB); + Holder marbleBlob = placedFeatureRegistry.getOrThrow(GTPlacedFeatures.MARBLE_BLOB); ctx.register(STONE_BLOB, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( overworld, HolderSet.direct(redGraniteBlob, marbleBlob), GenerationStep.Decoration.UNDERGROUND_ORES)); - Holder rawOilSprout = placedFeatureRegistry.getOrThrow(GTPlacements.RAW_OIL_SPROUT); + Holder rawOilSprout = placedFeatureRegistry.getOrThrow(GTPlacedFeatures.RAW_OIL_SPROUT); ctx.register(RAW_OIL_SPROUT, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( overworld, HolderSet.direct(rawOilSprout), diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTConfiguredFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java similarity index 52% rename from src/main/java/com/gregtechceu/gtceu/common/data/GTConfiguredFeatures.java rename to src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java index d56a13fd2b3..ff7dd3cfcff 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTConfiguredFeatures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java @@ -1,6 +1,9 @@ -package com.gregtechceu.gtceu.common.data; +package com.gregtechceu.gtceu.common.data.worldgen; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.common.data.GTBlocks; +import com.gregtechceu.gtceu.common.data.GTFeatures; +import com.gregtechceu.gtceu.common.data.GTMaterials; import com.gregtechceu.gtceu.common.worldgen.feature.configurations.FluidSproutConfiguration; import com.gregtechceu.gtceu.common.worldgen.feature.configurations.StoneBlobConfiguration; @@ -23,33 +26,43 @@ public class GTConfiguredFeatures { - public static final ResourceKey> RUBBER = ResourceKey.create(Registries.CONFIGURED_FEATURE, - GTCEu.id("rubber_tree")); - public static final ResourceKey> RED_GRANITE_BLOB = ResourceKey - .create(Registries.CONFIGURED_FEATURE, GTCEu.id("red_granite_blob")); - public static final ResourceKey> MARBLE_BLOB = ResourceKey - .create(Registries.CONFIGURED_FEATURE, GTCEu.id("marble_blob")); - public static final ResourceKey> RAW_OIL_SPROUT = ResourceKey - .create(Registries.CONFIGURED_FEATURE, GTCEu.id("raw_oil_sprout")); + // spotless:off + public static final ResourceKey> RUBBER = ResourceKey.create(Registries.CONFIGURED_FEATURE, GTCEu.id("rubber_tree")); + public static final ResourceKey> RED_GRANITE_BLOB = ResourceKey.create(Registries.CONFIGURED_FEATURE, GTCEu.id("red_granite_blob")); + public static final ResourceKey> MARBLE_BLOB = ResourceKey.create(Registries.CONFIGURED_FEATURE, GTCEu.id("marble_blob")); + public static final ResourceKey> RAW_OIL_SPROUT = ResourceKey.create(Registries.CONFIGURED_FEATURE, GTCEu.id("raw_oil_sprout")); public static void bootstrap(BootstapContext> ctx) { - FeatureUtils.register(ctx, RUBBER, Feature.TREE, new TreeConfiguration.TreeConfigurationBuilder( - BlockStateProvider - .simple(GTBlocks.RUBBER_LOG.get().changeNatural(GTBlocks.RUBBER_LOG.getDefaultState(), true)), - new ForkingTrunkPlacer(5, 1, 3), - BlockStateProvider.simple(GTBlocks.RUBBER_LEAVES.get()), - new MegaJungleFoliagePlacer(ConstantInt.of(1), UniformInt.of(0, 1), 1), - new TwoLayersFeatureSize(1, 0, 2)).ignoreVines().build()); + FeatureUtils.register(ctx, RUBBER, Feature.TREE, + new TreeConfiguration.TreeConfigurationBuilder( + BlockStateProvider.simple(GTBlocks.RUBBER_LOG.get().changeNatural(GTBlocks.RUBBER_LOG.getDefaultState(), true)), + new ForkingTrunkPlacer(5, 1, 3), + BlockStateProvider.simple(GTBlocks.RUBBER_LEAVES.get()), + new MegaJungleFoliagePlacer(ConstantInt.of(1), UniformInt.of(0, 1), 1), + new TwoLayersFeatureSize(1, 0, 2) + ).ignoreVines().build() + ); FeatureUtils.register(ctx, RED_GRANITE_BLOB, GTFeatures.STONE_BLOB.get(), - new StoneBlobConfiguration(OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), - GTBlocks.RED_GRANITE.getDefaultState()), UniformInt.of(20, 30))); + new StoneBlobConfiguration( + OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), + GTBlocks.RED_GRANITE.getDefaultState()), UniformInt.of(20, 30) + ) + ); FeatureUtils.register(ctx, MARBLE_BLOB, GTFeatures.STONE_BLOB.get(), - new StoneBlobConfiguration(OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), - GTBlocks.MARBLE.getDefaultState()), UniformInt.of(20, 30))); + new StoneBlobConfiguration( + OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), + GTBlocks.MARBLE.getDefaultState()), UniformInt.of(20, 30) + ) + ); FeatureUtils.register(ctx, RAW_OIL_SPROUT, GTFeatures.FLUID_SPROUT.get(), - new FluidSproutConfiguration(GTMaterials.RawOil.getFluid(), UniformInt.of(9, 13), UniformInt.of(6, 9), - 0.4f)); + new FluidSproutConfiguration( + GTMaterials.RawOil.getFluid(), + UniformInt.of(9, 13), UniformInt.of(6, 9), + 0.4f + ) + ); } + // spotless:on } diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTWorldgen.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java similarity index 51% rename from src/main/java/com/gregtechceu/gtceu/common/data/GTWorldgen.java rename to src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java index 623d83b2a09..a9974b8c315 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTWorldgen.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java @@ -1,5 +1,6 @@ -package com.gregtechceu.gtceu.common.data; +package com.gregtechceu.gtceu.common.data.worldgen; +import com.gregtechceu.gtceu.GTCEu; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; import net.minecraft.core.registries.Registries; @@ -10,28 +11,35 @@ import net.minecraft.world.level.levelgen.Noises; import net.minecraft.world.level.levelgen.synth.NormalNoise; -import static com.gregtechceu.gtceu.common.data.GTFeatures.NEW_ORE_VEIN_RIDGED; -import static com.gregtechceu.gtceu.common.data.GTFeatures.NEW_ORE_VEIN_TOGGLE; +public class GTDensityFunctions { -public class GTWorldgen { + // spotless:off + public static final ResourceKey NEW_ORE_VEIN_TOGGLE = ResourceKey.create(Registries.DENSITY_FUNCTION, GTCEu.id("vein_toggle")); + public static final ResourceKey NEW_ORE_VEIN_RIDGED = ResourceKey.create(Registries.DENSITY_FUNCTION, GTCEu.id("vein_ridged")); - public static void bootstrapDensityFunctions(BootstapContext ctx) { + public static void bootstrap(BootstapContext ctx) { HolderGetter noises = ctx.lookup(Registries.NOISE); Holder oreVeininess = noises.getOrThrow(Noises.ORE_VEININESS); - ctx.register(ResourceKey.create(Registries.DENSITY_FUNCTION, NEW_ORE_VEIN_TOGGLE), + ctx.register(NEW_ORE_VEIN_TOGGLE, DensityFunctions.interpolated( - DensityFunctions.noise(oreVeininess, 1.5f, 1.5f))); + DensityFunctions.noise(oreVeininess, 1.5f, 1.5f) + ) + ); Holder oreVeinA = noises.getOrThrow(Noises.ORE_VEIN_A); Holder oreVeinB = noises.getOrThrow(Noises.ORE_VEIN_B); - ctx.register(ResourceKey.create(Registries.DENSITY_FUNCTION, NEW_ORE_VEIN_RIDGED), + ctx.register(NEW_ORE_VEIN_RIDGED, DensityFunctions.add( DensityFunctions.constant(-0.08f), DensityFunctions.max( - DensityFunctions.interpolated( - DensityFunctions.noise(oreVeinA, 4.0f, 4.0f)).abs(), - DensityFunctions.interpolated( - DensityFunctions.noise(oreVeinB, 4.0f, 4.0f)).abs()))); + DensityFunctions.interpolated(DensityFunctions.noise(oreVeinA, 4.0f, 4.0f)) + .abs(), + DensityFunctions.interpolated(DensityFunctions.noise(oreVeinB, 4.0f, 4.0f)) + .abs() + ) + ) + ); } + // spotless:on } diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTPlacements.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java similarity index 85% rename from src/main/java/com/gregtechceu/gtceu/common/data/GTPlacements.java rename to src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java index cc8ca11818a..4b340c2bf3a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTPlacements.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java @@ -1,8 +1,9 @@ -package com.gregtechceu.gtceu.common.data; +package com.gregtechceu.gtceu.common.data.worldgen; import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; +import com.gregtechceu.gtceu.common.data.GTBlocks; import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; import com.gregtechceu.gtceu.data.recipe.CustomTags; @@ -18,16 +19,14 @@ import java.util.List; -public class GTPlacements { +public class GTPlacedFeatures { - public static final ResourceKey RUBBER_CHECKED = ResourceKey.create(Registries.PLACED_FEATURE, - GTCEu.id("rubber_checked")); - public static final ResourceKey RED_GRANITE_BLOB = ResourceKey.create(Registries.PLACED_FEATURE, - GTCEu.id("red_granite_blob")); - public static final ResourceKey MARBLE_BLOB = ResourceKey.create(Registries.PLACED_FEATURE, - GTCEu.id("marble_blob")); - public static final ResourceKey RAW_OIL_SPROUT = ResourceKey.create(Registries.PLACED_FEATURE, - GTCEu.id("raw_oil_sprout")); + // spotless:off + public static final ResourceKey RUBBER_CHECKED = ResourceKey.create(Registries.PLACED_FEATURE, GTCEu.id("rubber_checked")); + public static final ResourceKey RED_GRANITE_BLOB = ResourceKey.create(Registries.PLACED_FEATURE, GTCEu.id("red_granite_blob")); + public static final ResourceKey MARBLE_BLOB = ResourceKey.create(Registries.PLACED_FEATURE, GTCEu.id("marble_blob")); + public static final ResourceKey RAW_OIL_SPROUT = ResourceKey.create(Registries.PLACED_FEATURE, GTCEu.id("raw_oil_sprout")); + // spotless:on public static void bootstrap(BootstapContext ctx) { HolderGetter> featureLookup = ctx.lookup(Registries.CONFIGURED_FEATURE); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java new file mode 100644 index 00000000000..1a8013c353e --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java @@ -0,0 +1,30 @@ +package com.gregtechceu.gtceu.common.data.worldgen; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; +import com.gregtechceu.gtceu.api.data.worldgen.modifier.DimensionFilter; +import com.gregtechceu.gtceu.api.data.worldgen.modifier.FrequencyModifier; +import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.levelgen.placement.PlacementModifierType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class GTPlacementModifiers { + // spotless:off + + public static final DeferredRegister> PLACEMENT_MODIFIERS = DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, GTCEu.MOD_ID); + + + public static final RegistryObject> FREQUENCY_MODIFIER = PLACEMENT_MODIFIERS.register("frequency", () -> () -> FrequencyModifier.CODEC); + public static final RegistryObject> DIMENSION_FILTER = PLACEMENT_MODIFIERS.register("dimension", () -> () -> DimensionFilter.CODEC); + public static final RegistryObject> BIOME_PLACEMENT = PLACEMENT_MODIFIERS.register("biome_placement", () -> () -> BiomePlacement.CODEC); + public static final RegistryObject> RUBBER_TREE_CHANCE = PLACEMENT_MODIFIERS.register("rubber_tree_chance", () -> () -> RubberTreeChancePlacement.CODEC); + + // spotless:on + + public static void init(IEventBus modBus) { + PLACEMENT_MODIFIERS.register(modBus); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/RubberTreeChancePlacement.java b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/RubberTreeChancePlacement.java index e468a76fbc1..124d1c02d93 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/RubberTreeChancePlacement.java +++ b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/RubberTreeChancePlacement.java @@ -1,11 +1,9 @@ package com.gregtechceu.gtceu.common.worldgen.modifier; -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; import com.gregtechceu.gtceu.config.ConfigHolder; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.util.RandomSource; import net.minecraft.world.level.levelgen.placement.PlacementModifierType; import net.minecraft.world.level.levelgen.placement.RepeatingPlacement; @@ -14,11 +12,6 @@ public class RubberTreeChancePlacement extends RepeatingPlacement { - public static final PlacementModifierType RUBBER_TREE_CHANCE_PLACEMENT = GTRegistries - .register( - BuiltInRegistries.PLACEMENT_MODIFIER_TYPE, GTCEu.id("rubber_tree_chance"), - () -> RubberTreeChancePlacement.CODEC); - public static final RubberTreeChancePlacement INSTANCE = new RubberTreeChancePlacement(); public static final Codec CODEC = Codec.unit(INSTANCE); @@ -29,6 +22,6 @@ protected int count(RandomSource random, BlockPos pos) { @Override public PlacementModifierType type() { - return RUBBER_TREE_CHANCE_PLACEMENT; + return GTPlacementModifiers.RUBBER_TREE_CHANCE.get(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java index 7ff6a458418..b9b25673e3b 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java +++ b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java @@ -2,11 +2,9 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.registry.registrate.SoundEntryBuilder; -import com.gregtechceu.gtceu.common.data.GTBiomeModifiers; -import com.gregtechceu.gtceu.common.data.GTConfiguredFeatures; +import com.gregtechceu.gtceu.common.data.worldgen.*; import com.gregtechceu.gtceu.common.data.GTDamageTypes; -import com.gregtechceu.gtceu.common.data.GTPlacements; -import com.gregtechceu.gtceu.common.data.GTWorldgen; +import com.gregtechceu.gtceu.data.loot.NewDungeonLootLoader; import com.gregtechceu.gtceu.data.tags.BiomeTagsLoader; import com.gregtechceu.gtceu.data.tags.DamageTagsLoader; @@ -42,8 +40,8 @@ public static void gatherData(GatherDataEvent event) { packOutput, registries, new RegistrySetBuilder() .add(Registries.DAMAGE_TYPE, GTDamageTypes::bootstrap) .add(Registries.CONFIGURED_FEATURE, GTConfiguredFeatures::bootstrap) - .add(Registries.PLACED_FEATURE, GTPlacements::bootstrap) - .add(Registries.DENSITY_FUNCTION, GTWorldgen::bootstrapDensityFunctions) + .add(Registries.PLACED_FEATURE, GTPlacedFeatures::bootstrap) + .add(Registries.DENSITY_FUNCTION, GTDensityFunctions::bootstrap) .add(ForgeRegistries.Keys.BIOME_MODIFIERS, GTBiomeModifiers::bootstrap), set)); generator.addProvider(true, From 18776020909ad2a047544e49ad54f1ecfda73ff6 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:49:48 +0300 Subject: [PATCH 04/61] Also move GTFeatures --- .../gtceu/common/data/worldgen/GTConfiguredFeatures.java | 1 - .../gtceu/common/data/{ => worldgen}/GTFeatures.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) rename src/main/java/com/gregtechceu/gtceu/common/data/{ => worldgen}/GTFeatures.java (95%) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java index ff7dd3cfcff..4066e9bcef7 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTConfiguredFeatures.java @@ -2,7 +2,6 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.common.data.GTBlocks; -import com.gregtechceu.gtceu.common.data.GTFeatures; import com.gregtechceu.gtceu.common.data.GTMaterials; import com.gregtechceu.gtceu.common.worldgen.feature.configurations.FluidSproutConfiguration; import com.gregtechceu.gtceu.common.worldgen.feature.configurations.StoneBlobConfiguration; diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTFeatures.java similarity index 95% rename from src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java rename to src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTFeatures.java index f1fa0827b8e..6169af17af7 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTFeatures.java @@ -1,4 +1,4 @@ -package com.gregtechceu.gtceu.common.data; +package com.gregtechceu.gtceu.common.data.worldgen; import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.common.worldgen.feature.FluidSproutFeature; From 58633d25d0d6c3c42a73f87c13f96aa242776a97 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:50:36 +0300 Subject: [PATCH 05/61] Delete unused placement modifiers --- .../worldgen/modifier/DimensionFilter.java | 40 --------------- .../worldgen/modifier/FrequencyModifier.java | 50 ------------------- .../data/worldgen/GTPlacementModifiers.java | 4 -- 3 files changed, 94 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java deleted file mode 100644 index ee3640b4ae4..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/DimensionFilter.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.gregtechceu.gtceu.api.data.worldgen.modifier; - -import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; -import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryCodecs; -import net.minecraft.core.registries.Registries; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.levelgen.placement.PlacementContext; -import net.minecraft.world.level.levelgen.placement.PlacementFilter; -import net.minecraft.world.level.levelgen.placement.PlacementModifierType; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -public class DimensionFilter extends PlacementFilter { - - // spotless:off - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - RegistryCodecs.homogeneousList(Registries.DIMENSION_TYPE).fieldOf("dimension_id").forGetter(filter -> filter.dimensionId) - ).apply(instance, DimensionFilter::new)); - // spotless:on - - public HolderSet dimensionId; - - public DimensionFilter(HolderSet dimensionId) { - this.dimensionId = dimensionId; - } - - @Override - protected boolean shouldPlace(PlacementContext context, RandomSource random, BlockPos pos) { - return this.dimensionId.contains(context.getLevel().getLevel().dimensionTypeRegistration()); - } - - @Override - public PlacementModifierType type() { - return GTPlacementModifiers.DIMENSION_FILTER.get(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java deleted file mode 100644 index e38124d0124..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/FrequencyModifier.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.gregtechceu.gtceu.api.data.worldgen.modifier; - -import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers; -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.core.BlockPos; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.levelgen.placement.PlacementContext; -import net.minecraft.world.level.levelgen.placement.PlacementModifier; -import net.minecraft.world.level.levelgen.placement.PlacementModifierType; - -import com.mojang.serialization.Codec; - -import java.util.stream.Stream; - -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public class FrequencyModifier extends PlacementModifier { - - public static final Codec CODEC = ExtraCodecs.POSITIVE_FLOAT.fieldOf("chance") - .xmap(FrequencyModifier::new, (modifier) -> modifier.frequency).codec(); - - private final float frequency; - - public FrequencyModifier(float frequency) { - this.frequency = frequency; - } - - @Override - public Stream getPositions(PlacementContext context, RandomSource random, BlockPos pos) { - int count = getCount(frequency, random); - if (count == 0) { - return Stream.empty(); - } - return Stream.of(pos); - } - - public int getCount(float frequency, RandomSource random) { - int floored = Mth.floor(frequency); - return floored + (random.nextFloat() < (frequency - floored) ? 1 : 0); - } - - @Override - public PlacementModifierType type() { - return GTPlacementModifiers.FREQUENCY_MODIFIER.get(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java index 1a8013c353e..65ab05be49e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java @@ -2,8 +2,6 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.DimensionFilter; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.FrequencyModifier; import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.levelgen.placement.PlacementModifierType; @@ -17,8 +15,6 @@ public class GTPlacementModifiers { public static final DeferredRegister> PLACEMENT_MODIFIERS = DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, GTCEu.MOD_ID); - public static final RegistryObject> FREQUENCY_MODIFIER = PLACEMENT_MODIFIERS.register("frequency", () -> () -> FrequencyModifier.CODEC); - public static final RegistryObject> DIMENSION_FILTER = PLACEMENT_MODIFIERS.register("dimension", () -> () -> DimensionFilter.CODEC); public static final RegistryObject> BIOME_PLACEMENT = PLACEMENT_MODIFIERS.register("biome_placement", () -> () -> BiomePlacement.CODEC); public static final RegistryObject> RUBBER_TREE_CHANCE = PLACEMENT_MODIFIERS.register("rubber_tree_chance", () -> () -> RubberTreeChancePlacement.CODEC); From f5d06e0b8fb151a85f6012a111f3b5787b4ac9a9 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:53:25 +0300 Subject: [PATCH 06/61] Rename BiomePlacement to BiomeDependentPlacement and move it to a non-api package --- .../gtceu/common/data/worldgen/GTPlacedFeatures.java | 4 ++-- .../common/data/worldgen/GTPlacementModifiers.java | 4 ++-- .../worldgen/modifier/BiomeDependentPlacement.java} | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) rename src/main/java/com/gregtechceu/gtceu/{api/data/worldgen/modifier/BiomePlacement.java => common/worldgen/modifier/BiomeDependentPlacement.java} (72%) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java index 4b340c2bf3a..4954b4253a0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java @@ -2,7 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; +import com.gregtechceu.gtceu.common.worldgen.modifier.BiomeDependentPlacement; import com.gregtechceu.gtceu.common.data.GTBlocks; import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; import com.gregtechceu.gtceu.data.recipe.CustomTags; @@ -33,7 +33,7 @@ public static void bootstrap(BootstapContext ctx) { HolderGetter biomeLookup = ctx.lookup(Registries.BIOME); PlacementUtils.register(ctx, RUBBER_CHECKED, featureLookup.getOrThrow(GTConfiguredFeatures.RUBBER), - new BiomePlacement(List.of( + new BiomeDependentPlacement(List.of( new BiomeWeightModifier(() -> biomeLookup.getOrThrow(CustomTags.IS_SWAMP), 50))), RubberTreeChancePlacement.INSTANCE, InSquarePlacement.spread(), diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java index 65ab05be49e..bb5eaaaa081 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java @@ -1,7 +1,7 @@ package com.gregtechceu.gtceu.common.data.worldgen; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.data.worldgen.modifier.BiomePlacement; +import com.gregtechceu.gtceu.common.worldgen.modifier.BiomeDependentPlacement; import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.levelgen.placement.PlacementModifierType; @@ -15,7 +15,7 @@ public class GTPlacementModifiers { public static final DeferredRegister> PLACEMENT_MODIFIERS = DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, GTCEu.MOD_ID); - public static final RegistryObject> BIOME_PLACEMENT = PLACEMENT_MODIFIERS.register("biome_placement", () -> () -> BiomePlacement.CODEC); + public static final RegistryObject> BIOME_DEPENDENT = PLACEMENT_MODIFIERS.register("biome_dependent", () -> () -> BiomeDependentPlacement.CODEC); public static final RegistryObject> RUBBER_TREE_CHANCE = PLACEMENT_MODIFIERS.register("rubber_tree_chance", () -> () -> RubberTreeChancePlacement.CODEC); // spotless:on diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java similarity index 72% rename from src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java rename to src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java index 67b8aa7aaf3..a37b4110ae9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/modifier/BiomePlacement.java +++ b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java @@ -1,4 +1,4 @@ -package com.gregtechceu.gtceu.api.data.worldgen.modifier; +package com.gregtechceu.gtceu.common.worldgen.modifier; import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier; @@ -14,14 +14,14 @@ import java.util.List; import java.util.stream.Stream; -public class BiomePlacement extends PlacementModifier { +public class BiomeDependentPlacement extends PlacementModifier { - public static final Codec CODEC = BiomeWeightModifier.CODEC.listOf().fieldOf("modifiers") - .xmap(BiomePlacement::new, placement -> placement.modifiers).codec(); + public static final Codec CODEC = BiomeWeightModifier.CODEC.listOf().fieldOf("modifiers") + .xmap(BiomeDependentPlacement::new, placement -> placement.modifiers).codec(); public final List modifiers; - public BiomePlacement(List modifiers) { + public BiomeDependentPlacement(List modifiers) { this.modifiers = modifiers; } @@ -40,6 +40,6 @@ public Stream getPositions(PlacementContext context, RandomSource rand @Override public PlacementModifierType type() { - return GTPlacementModifiers.BIOME_PLACEMENT.get(); + return GTPlacementModifiers.BIOME_DEPENDENT.get(); } } From 785763e0eca30516bb00ae1557ec41f6643d53bd Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:33:40 +0300 Subject: [PATCH 07/61] Create backend for better chest loot addition --- .../loot/modifier/AddTableLootModifier.java | 73 +++++++++++++++++ .../gtceu/api/loot/modifier/package-info.java | 4 + .../loot/serializer/CodecBasedSerializer.java | 37 +++++++++ .../api/loot/serializer/package-info.java | 4 + .../gregtechceu/gtceu/common/CommonProxy.java | 4 +- .../data/loot/GTGlobalLootModifiers.java | 27 +++++++ .../common/data/loot/GTLootConditions.java | 26 +++++++ .../condition/GTConfigValueCondition.java | 52 +++++++++++++ .../common/loot/condition/package-info.java | 4 + ...BinomialDistributionGeneratorAccessor.java | 15 ++++ .../core/mixins/UniformGeneratorAccessor.java | 15 ++++ .../gtceu/data/DataGenerators.java | 3 + .../gtceu/data/loot/GTLootTables.java | 37 +++++++++ .../gtceu/data/loot/NewDungeonLootLoader.java | 21 +++++ .../data/loot/NumberProviderShortcuts.java | 78 +++++++++++++++++++ .../gtceu/data/loot/package-info.java | 4 + src/main/resources/gtceu.mixins.json | 2 + 17 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java create mode 100644 src/main/java/com/gregtechceu/gtceu/api/loot/modifier/package-info.java create mode 100644 src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java create mode 100644 src/main/java/com/gregtechceu/gtceu/api/loot/serializer/package-info.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/loot/condition/package-info.java create mode 100644 src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java create mode 100644 src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java create mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java create mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java create mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java create mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/package-info.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java new file mode 100644 index 00000000000..088836f7eba --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java @@ -0,0 +1,73 @@ +package com.gregtechceu.gtceu.api.loot.modifier; + +import com.gregtechceu.gtceu.common.data.loot.GTGlobalLootModifiers; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import lombok.Getter; +import lombok.experimental.Accessors; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraftforge.common.loot.IGlobalLootModifier; +import net.minecraftforge.common.loot.LootModifier; +import org.jetbrains.annotations.ApiStatus; + +/** + *

Loot modifier that rolls one loot table (the "subtable" and adds the results to the loot being modified (the "target table"). + * Loot modifiers are not rolled for the subtable, as that could result in the subtables' + * items being modified twice (by downstream loot modifiers modifying the target table).

+ * + *

Json format: + * + *

{@code
+ * {
+ *   "type": "gtceu:add_table",
+ *   "conditions": [], // conditions block to predicate target tables by
+ *   "table": "namespace:loot_table_id" // subtable to roll loot for to add to the target table(s)
+ * }
+ * }
+ * + *

+ */ +// copy of NeoForge's AddTableLootModifier, tweaked slightly to work on 1.20 +@Accessors(fluent = true) +public class AddTableLootModifier extends LootModifier { + /** + * @see GTGlobalLootModifiers#ADD_TABLE_LOOT_MODIFIER + */ + // spotless:off + @ApiStatus.Internal + public static final Codec CODEC = RecordCodecBuilder.create(instance -> LootModifier.codecStart(instance).and( + ResourceLocation.CODEC.fieldOf("table").forGetter(AddTableLootModifier::table) + ).apply(instance, AddTableLootModifier::new)); + // spotless:on + + @Getter + private final ResourceLocation table; + + public AddTableLootModifier(LootItemCondition[] conditionsIn, ResourceLocation table) { + super(conditionsIn); + this.table = table; + } + + @SuppressWarnings("deprecation") + @Override + protected ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { + context.getResolver().getElementOptional(LootDataType.TABLE, this.table).ifPresent(extraTable -> { + // Don't run loot modifiers for subtables; + // the added loot will be modifiable by downstream loot modifiers modifying the target table, + // so if we modify it here then it could get modified twice. + extraTable.getRandomItemsRaw(context, LootTable.createStackSplitter(context.getLevel(), generatedLoot::add)); + }); + return generatedLoot; + } + + @Override + public Codec codec() { + return GTGlobalLootModifiers.ADD_TABLE_LOOT_MODIFIER.get(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/package-info.java b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/package-info.java new file mode 100644 index 00000000000..0dffd93bb72 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.api.loot.modifier; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java new file mode 100644 index 00000000000..4fe813f60f2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java @@ -0,0 +1,37 @@ +package com.gregtechceu.gtceu.api.loot.serializer; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.mojang.serialization.JsonOps; +import com.mojang.serialization.MapCodec; +import net.minecraft.util.GsonHelper; +import net.minecraft.world.level.storage.loot.Serializer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public record CodecBasedSerializer(MapCodec codec) implements Serializer { + + private static final Logger LOGGER = LogManager.getLogger("GTCEu/CodecBasedLootSerializer"); + + @Override + public void serialize(JsonObject json, T value, JsonSerializationContext serializationContext) { + JsonElement newJson = codec.codec().encodeStart(JsonOps.INSTANCE, value) + .promotePartial(CodecBasedSerializer::logErrors) + .getOrThrow(false, LOGGER::error); + JsonObject asObject = GsonHelper.convertToJsonObject(newJson, "serialized value"); + json.asMap().putAll(asObject.asMap()); + } + + @Override + public T deserialize(JsonObject json, JsonDeserializationContext serializationContext) { + return codec.codec().parse(JsonOps.INSTANCE, json) + .promotePartial(CodecBasedSerializer::logErrors) + .getOrThrow(false, LOGGER::error); + } + + private static void logErrors(String errorMessage) { + LOGGER.error("Recoverable errors when parsing loot: {}", errorMessage); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/package-info.java b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/package-info.java new file mode 100644 index 00000000000..74aad1850d3 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.api.loot.serializer; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java index 6add9e55d08..4b4f6b09df4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java +++ b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java @@ -26,7 +26,7 @@ import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; import com.gregtechceu.gtceu.common.data.*; -import com.gregtechceu.gtceu.common.data.GTPlaceholders; +import com.gregtechceu.gtceu.common.data.loot.*; import com.gregtechceu.gtceu.common.data.machines.GTMachineUtils; import com.gregtechceu.gtceu.common.data.materials.AlloyBlastPropertyAddition; import com.gregtechceu.gtceu.common.data.materials.GTFoods; @@ -105,6 +105,8 @@ public CommonProxy() { GTValueProviderTypes.init(eventBus); GTPlacementModifiers.init(eventBus); + GTGlobalLootModifiers.init(eventBus); + GTLootConditions.init(eventBus); GTFeatures.init(eventBus); GTCommandArguments.init(eventBus); GTMobEffects.init(eventBus); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java new file mode 100644 index 00000000000..c9b9fee38c7 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java @@ -0,0 +1,27 @@ +package com.gregtechceu.gtceu.common.data.loot; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.loot.modifier.AddTableLootModifier; +import com.mojang.serialization.Codec; +import net.minecraftforge.common.loot.IGlobalLootModifier; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public class GTGlobalLootModifiers { + // spotless:off + + public static final DeferredRegister> GLOBAL_LOOT_MODIFIER_SERIALIZERS = + DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, GTCEu.MOD_ID); + + + public static final RegistryObject> ADD_TABLE_LOOT_MODIFIER = GLOBAL_LOOT_MODIFIER_SERIALIZERS.register("add_table", () -> AddTableLootModifier.CODEC); + + // spotless:on + + + public static void init(IEventBus modBus) { + GLOBAL_LOOT_MODIFIER_SERIALIZERS.register(modBus); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java new file mode 100644 index 00000000000..eb5d57f93d0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java @@ -0,0 +1,26 @@ +package com.gregtechceu.gtceu.common.data.loot; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.loot.serializer.CodecBasedSerializer; +import com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class GTLootConditions { + // spotless:off + + public static final DeferredRegister LOOT_CONDITION_TYPES = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, GTCEu.MOD_ID); + + + public static final RegistryObject CONFIG_VALUE = LOOT_CONDITION_TYPES.register("config_value", () -> new LootItemConditionType(new CodecBasedSerializer<>(GTConfigValueCondition.CODEC))); + + // spotless:on + + + public static void init(IEventBus modBus) { + LOOT_CONDITION_TYPES.register(modBus); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java new file mode 100644 index 00000000000..8eee7a20834 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java @@ -0,0 +1,52 @@ +package com.gregtechceu.gtceu.common.loot.condition; + +import com.gregtechceu.gtceu.common.data.loot.GTLootConditions; +import com.gregtechceu.gtceu.config.ConfigHolder; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.toma.configuration.config.value.IConfigValue; +import lombok.Getter; +import lombok.experimental.Accessors; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; + +import java.util.Optional; +import java.util.function.BooleanSupplier; + +@Accessors(fluent = true) +public class GTConfigValueCondition implements LootItemCondition { + + // spotless:off + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.STRING.fieldOf("config_field").forGetter(GTConfigValueCondition::configField) + ).apply(instance, GTConfigValueCondition::new)); + // spotless:on + + @Getter + private final String configField; + private final BooleanSupplier configValueGetter; + + protected GTConfigValueCondition(String configField) { + this.configField = configField; + + Optional> configEntry = ConfigHolder.INTERNAL_INSTANCE + .getConfigValue(configField, boolean.class); + this.configValueGetter = () -> configEntry.map(IConfigValue::get).orElse(false); + } + + @Override + public boolean test(LootContext lootContext) { + return configValueGetter.getAsBoolean(); + } + + @Override + public LootItemConditionType getType() { + return GTLootConditions.CONFIG_VALUE.get(); + } + + public static LootItemCondition.Builder configEnabled(String configField) { + return () -> new GTConfigValueCondition(configField); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/package-info.java b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/package-info.java new file mode 100644 index 00000000000..aec8cbea134 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.common.loot.condition; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java new file mode 100644 index 00000000000..26b98aa9108 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java @@ -0,0 +1,15 @@ +package com.gregtechceu.gtceu.core.mixins; + +import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator; +import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(BinomialDistributionGenerator.class) +public interface BinomialDistributionGeneratorAccessor { + + @Invoker("") + static BinomialDistributionGenerator callInit(NumberProvider min, NumberProvider max) { + throw new AssertionError("Mixin didn't apply"); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java new file mode 100644 index 00000000000..9149029eafe --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java @@ -0,0 +1,15 @@ +package com.gregtechceu.gtceu.core.mixins; + +import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(UniformGenerator.class) +public interface UniformGeneratorAccessor { + + @Invoker("") + static UniformGenerator callInit(NumberProvider min, NumberProvider max) { + throw new AssertionError("Mixin didn't apply"); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java index b9b25673e3b..bbe3135dca1 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java +++ b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.registry.registrate.SoundEntryBuilder; import com.gregtechceu.gtceu.common.data.worldgen.*; import com.gregtechceu.gtceu.common.data.GTDamageTypes; +import com.gregtechceu.gtceu.data.loot.GTLootTables; import com.gregtechceu.gtceu.data.loot.NewDungeonLootLoader; import com.gregtechceu.gtceu.data.tags.BiomeTagsLoader; import com.gregtechceu.gtceu.data.tags.DamageTagsLoader; @@ -46,6 +47,8 @@ packOutput, registries, new RegistrySetBuilder() set)); generator.addProvider(true, new DamageTagsLoader(packOutput, provider.getRegistryProvider(), existingFileHelper)); + generator.addProvider(true, new GTLootTables(packOutput)); + generator.addProvider(true, new NewDungeonLootLoader(packOutput)); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java new file mode 100644 index 00000000000..980af1a734c --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java @@ -0,0 +1,37 @@ +package com.gregtechceu.gtceu.data.loot; + +import net.minecraft.data.PackOutput; +import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.data.loot.LootTableSubProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; + +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; + +import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*; +import static net.minecraft.world.level.storage.loot.LootPool.lootPool; +import static net.minecraft.world.level.storage.loot.entries.LootItem.lootTableItem; +import static net.minecraft.world.level.storage.loot.functions.SetItemCountFunction.*; +import static net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition.*; +import static net.minecraft.world.level.storage.loot.providers.number.ConstantValue.*; +import static net.minecraft.world.level.storage.loot.providers.number.UniformGenerator.*; +import static net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator.*; + +public class GTLootTables extends LootTableProvider { + + public GTLootTables(PackOutput output) { + super(output, Set.of(), List.of( + new SubProviderEntry(ChestLoot::new, LootContextParamSets.CHEST) + )); + } + + public static class ChestLoot implements LootTableSubProvider { + + @Override + public void generate(BiConsumer provider) { + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java b/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java new file mode 100644 index 00000000000..bb9b6fd5e51 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java @@ -0,0 +1,21 @@ +package com.gregtechceu.gtceu.data.loot; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition; +import net.minecraft.data.PackOutput; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraftforge.common.data.GlobalLootModifierProvider; +import org.apache.commons.lang3.ArrayUtils; + +public class NewDungeonLootLoader extends GlobalLootModifierProvider { + + public NewDungeonLootLoader(PackOutput output) { + super(output, GTCEu.MOD_ID); + } + + @Override + protected void start() { + final LootItemCondition[] NORMAL_CONDITION = { new GTConfigValueCondition("worldgen.addLoot") }; + final LootItemCondition[] INCREASED_LOOT_CONDITION = ArrayUtils.add(NORMAL_CONDITION, new GTConfigValueCondition("worldgen.increaseDungeonLoot")); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java new file mode 100644 index 00000000000..3671e8664f0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java @@ -0,0 +1,78 @@ +package com.gregtechceu.gtceu.data.loot; + +import com.gregtechceu.gtceu.core.mixins.BinomialDistributionGeneratorAccessor; +import com.gregtechceu.gtceu.core.mixins.UniformGeneratorAccessor; +import lombok.experimental.UtilityClass; +import net.minecraft.world.level.storage.loot.providers.number.*; + +/** + * Utility class for working with loot tables and their number providers. To use this class efficiently, add the + * following static imports to your class: + *
{@code
+ * import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*;
+ * import static net.minecraft.world.level.storage.loot.LootPool.lootPool;
+ * import static net.minecraft.world.level.storage.loot.entries.LootItem.lootTableItem;
+ * import static net.minecraft.world.level.storage.loot.functions.SetItemCountFunction.*;
+ * import static net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition.*;
+ * import static net.minecraft.world.level.storage.loot.providers.number.ConstantValue.*;
+ * import static net.minecraft.world.level.storage.loot.providers.number.UniformGenerator.*;
+ * import static net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator.*;
+ * }
+ */ +@UtilityClass +public class NumberProviderShortcuts { + + // region CONSTANT VALUE + + public static ConstantValue constant(float value) { + return ConstantValue.exactly(value); + } + + // endregion // + // region UNIFORM GENERATOR + + public static UniformGenerator between(NumberProvider min, NumberProvider max) { + return UniformGeneratorAccessor.callInit(min, max); + } + + public static UniformGenerator between(float min, NumberProvider max) { + return between(constant(min), max); + } + + public static UniformGenerator between(NumberProvider min, float max) { + return between(min, constant(max)); + } + + public static UniformGenerator uniform(float min, float max) { + return UniformGenerator.between(min, max); + } + + public static UniformGenerator uniform(NumberProvider min, NumberProvider max) { + return between(min, max); + } + + public static UniformGenerator uniform(float min, NumberProvider max) { + return between(min, max); + } + + public static UniformGenerator uniform(NumberProvider min, float max) { + return between(min, max); + } + + // endregion // + // region BINOMIAL DISTRIBUTION GENERATOR + + public static BinomialDistributionGenerator binomial(NumberProvider n, NumberProvider p) { + return BinomialDistributionGeneratorAccessor.callInit(n, p); + } + + public static BinomialDistributionGenerator binomial(int n, NumberProvider p) { + return binomial(constant(n), p); + } + + public static BinomialDistributionGenerator binomial(NumberProvider n, float p) { + return binomial(n, constant(p)); + } + + // endregion // +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/package-info.java b/src/main/java/com/gregtechceu/gtceu/data/loot/package-info.java new file mode 100644 index 00000000000..96e337c59d5 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.data.loot; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/resources/gtceu.mixins.json b/src/main/resources/gtceu.mixins.json index 21cba8b5880..08b6986a125 100644 --- a/src/main/resources/gtceu.mixins.json +++ b/src/main/resources/gtceu.mixins.json @@ -56,6 +56,7 @@ "mixins": [ "AnvilMenuMixin", "BeehiveBlockAccessor", + "BinomialDistributionGeneratorAccessor", "BlockBehaviourAccessor", "BlockMixin", "BlockPropertiesAccessor", @@ -84,6 +85,7 @@ "TagLoaderMixin", "TagManagerMixin", "TagValueAccessor", + "UniformGeneratorAccessor", "client.ItemEntityMixin", "client.bloom.normal.embeddium.SodiumWorldRendererMixin", "dev.datagen.FixParallelKeyMappingRegistrationMixin", From 9e6294b9a4dfbc44b586e3ccd2d8612725c1591b Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Mon, 13 Jul 2026 18:05:05 +0300 Subject: [PATCH 08/61] Port chest loot additions to Global Loot modifier api --- .../api/data/chemical/ChemicalHelper.java | 11 + .../gregtechceu/gtceu/common/CommonProxy.java | 13 +- .../common/data/loot/GTLootFunctions.java | 25 ++ .../condition/GTConfigValueCondition.java | 14 + .../loot/function/SetEUChargeFunction.java | 50 +++ .../common/loot/function/package-info.java | 4 + .../gtceu/data/DataGenerators.java | 4 +- .../gtceu/data/loot/ChestGenHooks.java | 213 ------------ .../gtceu/data/loot/DungeonLootLoader.java | 168 --------- .../gtceu/data/loot/GTLootModifications.java | 43 +++ .../gtceu/data/loot/GTLootTables.java | 328 ++++++++++++++++++ .../gtceu/data/loot/NewDungeonLootLoader.java | 21 -- .../data/loot/NumberProviderShortcuts.java | 17 +- 13 files changed, 479 insertions(+), 432 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/loot/function/package-info.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/ChestGenHooks.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/DungeonLootLoader.java create mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/ChemicalHelper.java b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/ChemicalHelper.java index 1a347c1b08a..db8493fcd88 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/data/chemical/ChemicalHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/data/chemical/ChemicalHelper.java @@ -20,6 +20,7 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.Block; @@ -240,6 +241,16 @@ public static List getItems(MaterialEntry materialEntry) { }).stream().map(Supplier::get).collect(Collectors.toList()); } + public static Item getItem(MaterialEntry materialEntry) { + List items = getItems(materialEntry); + if (items.isEmpty()) return Items.AIR; + return items.get(0).asItem(); + } + + public static Item getItem(TagPrefix tagPrefix, Material material) { + return getItem(new MaterialEntry(tagPrefix, material)); + } + public static ItemStack get(MaterialEntry materialEntry, int size) { var list = getItems(materialEntry); if (list.isEmpty()) return ItemStack.EMPTY; diff --git a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java index 4b4f6b09df4..f1087e75d0a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java +++ b/src/main/java/com/gregtechceu/gtceu/common/CommonProxy.java @@ -39,8 +39,6 @@ import com.gregtechceu.gtceu.core.mixins.registrate.AbstractRegistrateAccessor; import com.gregtechceu.gtceu.data.GregTechDatagen; import com.gregtechceu.gtceu.data.lang.MaterialLangGenerator; -import com.gregtechceu.gtceu.data.loot.ChestGenHooks; -import com.gregtechceu.gtceu.data.loot.DungeonLootLoader; import com.gregtechceu.gtceu.data.pack.GTDynamicDataPack; import com.gregtechceu.gtceu.data.pack.GTDynamicResourcePack; import com.gregtechceu.gtceu.data.pack.GTPackSource; @@ -54,7 +52,6 @@ import com.gregtechceu.gtceu.utils.input.KeyBind; import com.gregtechceu.gtceu.utils.input.SyncedKeyMappings; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.repository.Pack; import net.minecraft.world.item.ItemStack; @@ -72,7 +69,6 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLConstructModEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.RegisterEvent; import brachy.modularui.factory.GuiManager; import com.google.common.collect.Multimaps; @@ -107,6 +103,7 @@ public CommonProxy() { GTPlacementModifiers.init(eventBus); GTGlobalLootModifiers.init(eventBus); GTLootConditions.init(eventBus); + GTLootFunctions.init(eventBus); GTFeatures.init(eventBus); GTCommandArguments.init(eventBus); GTMobEffects.init(eventBus); @@ -226,12 +223,6 @@ private static void initMaterials() { /* End Material Registration */ } - @SubscribeEvent - public void register(RegisterEvent event) { - if (event.getRegistryKey().equals(BuiltInRegistries.LOOT_FUNCTION_TYPE.key())) - ChestGenHooks.RandomWeightLootFunction.init(); - } - @SubscribeEvent public void modConstruct(FMLConstructModEvent event) { // this is done to delay initialization of content to be after KJS has set up. @@ -306,8 +297,6 @@ public void registerPackFinders(AddPackFindersEvent event) { GTCraftingComponents.init(); GTRecipes.recipeRemoval(); GTRecipes.recipeAddition(GTDynamicDataPack::addRecipe); - // Initialize dungeon loot additions - DungeonLootLoader.init(); GTCEu.LOGGER.info("GregTech Data loading took {}ms", System.currentTimeMillis() - startTime); event.addRepositorySource(new GTPackSource("gtceu:dynamic_data", diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java new file mode 100644 index 00000000000..6301fe93eac --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java @@ -0,0 +1,25 @@ +package com.gregtechceu.gtceu.common.data.loot; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.loot.serializer.CodecBasedSerializer; +import com.gregtechceu.gtceu.common.loot.function.SetEUChargeFunction; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class GTLootFunctions { + // spotless:off + + public static final DeferredRegister LOOT_FUNCTION_TYPES = DeferredRegister.create(Registries.LOOT_FUNCTION_TYPE, GTCEu.MOD_ID); + + + public static final RegistryObject SET_EU_CHARGE = LOOT_FUNCTION_TYPES.register("set_eu_charge", () -> new LootItemFunctionType(new CodecBasedSerializer<>(SetEUChargeFunction.CODEC))); + + // spotless:on + + public static void init(IEventBus modBus) { + LOOT_FUNCTION_TYPES.register(modBus); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java index 8eee7a20834..7cb332d06c4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java @@ -49,4 +49,18 @@ public LootItemConditionType getType() { public static LootItemCondition.Builder configEnabled(String configField) { return () -> new GTConfigValueCondition(configField); } + + /** + * {@return Config value condition that checks the {@code worldgen.addLoot} config} + */ + public static LootItemCondition.Builder addLootConfigEnabled() { + return configEnabled("worldgen.addLoot"); + } + + /** + * {@return Config value condition that checks the {@code worldgen.increaseDungeonLoot} config} + */ + public static LootItemCondition.Builder increaseDungeonLootConfigEnabled() { + return configEnabled("worldgen.increaseDungeonLoot"); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java b/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java new file mode 100644 index 00000000000..a927b4923d6 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java @@ -0,0 +1,50 @@ +package com.gregtechceu.gtceu.common.loot.function; + +import com.google.gson.*; +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.IElectricItem; +import com.gregtechceu.gtceu.common.data.loot.GTLootFunctions; +import com.gregtechceu.gtceu.utils.codec.GTCodecUtils; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.functions.*; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraftforge.common.loot.LootModifier; + +public class SetEUChargeFunction extends LootItemConditionalFunction { + + // spotless:off + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + LootModifier.LOOT_CONDITIONS_CODEC.fieldOf("conditions").forGetter(fn -> fn.predicates), + GTCodecUtils.NON_NEGATIVE_LONG.fieldOf("charge").forGetter(fn -> fn.charge) + ).apply(instance, SetEUChargeFunction::new)); + // spotless:on + + protected final long charge; + + protected SetEUChargeFunction(LootItemCondition[] conditions, long charge) { + super(conditions); + this.charge = charge; + } + + @Override + public LootItemFunctionType getType() { + return GTLootFunctions.SET_EU_CHARGE.get(); + } + + @Override + public ItemStack run(ItemStack stack, LootContext context) { + IElectricItem electricItem = GTCapabilityHelper.getElectricItem(stack); + if (electricItem == null) { + return stack; + } + electricItem.charge(this.charge, Integer.MAX_VALUE, true, false); + return stack; + } + + public static LootItemConditionalFunction.Builder setCharge(long charge) { + return simpleBuilder(conditions -> new SetEUChargeFunction(conditions, charge)); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/function/package-info.java b/src/main/java/com/gregtechceu/gtceu/common/loot/function/package-info.java new file mode 100644 index 00000000000..e82ff307695 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/loot/function/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.common.loot.function; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java index bbe3135dca1..215811d8eff 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java +++ b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java @@ -5,7 +5,7 @@ import com.gregtechceu.gtceu.common.data.worldgen.*; import com.gregtechceu.gtceu.common.data.GTDamageTypes; import com.gregtechceu.gtceu.data.loot.GTLootTables; -import com.gregtechceu.gtceu.data.loot.NewDungeonLootLoader; +import com.gregtechceu.gtceu.data.loot.GTLootModifications; import com.gregtechceu.gtceu.data.tags.BiomeTagsLoader; import com.gregtechceu.gtceu.data.tags.DamageTagsLoader; @@ -48,7 +48,7 @@ packOutput, registries, new RegistrySetBuilder() generator.addProvider(true, new DamageTagsLoader(packOutput, provider.getRegistryProvider(), existingFileHelper)); generator.addProvider(true, new GTLootTables(packOutput)); - generator.addProvider(true, new NewDungeonLootLoader(packOutput)); + generator.addProvider(true, new GTLootModifications(packOutput)); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/ChestGenHooks.java b/src/main/java/com/gregtechceu/gtceu/data/loot/ChestGenHooks.java deleted file mode 100644 index 3cf4e1b8c0c..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/data/loot/ChestGenHooks.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.gregtechceu.gtceu.data.loot; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.config.ConfigHolder; -import com.gregtechceu.gtceu.core.mixins.LootPoolAccessor; -import com.gregtechceu.gtceu.utils.GTMath; -import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.LootPool; -import net.minecraft.world.level.storage.loot.entries.LootItem; -import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; -import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction; -import net.minecraft.world.level.storage.loot.functions.LootItemFunction; -import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; -import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; -import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; -import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.event.LootTableLoadEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.registries.ForgeRegistries; - -import com.google.common.base.Preconditions; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import lombok.Getter; -import org.apache.commons.lang3.ArrayUtils; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Consumer; - -public final class ChestGenHooks { - - private static final Map> lootEntryItems = new Object2ObjectOpenHashMap<>(); - private static final Map rollValues = new Object2ObjectOpenHashMap<>(); - - private static final LootItemCondition[] NO_CONDITIONS = new LootItemCondition[0]; - - private ChestGenHooks() {} - - public static void init() { - MinecraftForge.EVENT_BUS.register(ChestGenHooks.class); - } - - @SubscribeEvent - public static void onWorldLoad(@NotNull LootTableLoadEvent event) { - LootPool mainPool = event.getTable().getPool("main"); - if (mainPool == null) return; - - ResourceLocation name = event.getName(); - if (lootEntryItems.containsKey(name)) { - List entryItems = lootEntryItems.get(name); - for (GTLootEntryItem entry : entryItems) { - if (ConfigHolder.INSTANCE.dev.debug) { - GTCEu.LOGGER.info("adding {} to lootTable {}", entry, name); - } - - try { - LootPoolEntryContainer[] entries = ((LootPoolAccessor) mainPool).getEntries(); - entries = ArrayUtils.add(entries, entry); - ((LootPoolAccessor) mainPool).setEntries(entries); - } catch (RuntimeException e) { - GTCEu.LOGGER.error("Couldn't add {} to lootTable {}: {}", entry, name, e.getMessage()); - } - } - } - - if (rollValues.containsKey(event.getName())) { - NumberProvider rangeAdd = rollValues.get(event.getName()); - NumberProvider range = mainPool.getRolls(); - // mainPool.setRolls(UniformGenerator.between(range.getMin() + rangeAdd.getMin(), range.getMax() + - // rangeAdd.getMax())); TODO additional rolls - } - } - - public static void addItem(@NotNull ResourceLocation lootTable, @NotNull ItemStack stack, int minAmount, - int maxAmount, int weight) { - RandomWeightLootFunction lootFunction = new RandomWeightLootFunction(stack, minAmount, maxAmount); - String modid = Objects.requireNonNull(BuiltInRegistries.ITEM.getKey(stack.getItem())).getNamespace(); - String entryName = createEntryName(stack, modid, weight, lootFunction); - GTLootEntryItem itemEntry = new GTLootEntryItem(stack, weight, lootFunction, entryName); - lootEntryItems.computeIfAbsent(lootTable, $ -> new ArrayList<>()).add(itemEntry); - } - - public static void addRolls(ResourceLocation tableLocation, int minAdd, int maxAdd) { - rollValues.put(tableLocation, UniformGenerator.between(minAdd, maxAdd)); - } - - private static final ItemStackHashStrategy HASH_STRATEGY = ItemStackHashStrategy.comparingAllButCount(); - - private static @NotNull String createEntryName(@NotNull ItemStack stack, @NotNull String modid, int weight, - @NotNull RandomWeightLootFunction function) { - int hashCode = GTMath.hashInts(HASH_STRATEGY.hashCode(stack), modid.hashCode(), weight, function.getMinAmount(), - function.getMaxAmount()); - return String.format("#%s:loot_%s", modid, hashCode); - } - - private static class GTLootEntryItem extends LootItem { - - private final ItemStack stack; - private final String entryName; - - public GTLootEntryItem(@NotNull ItemStack stack, int weight, LootItemFunction lootFunction, - @NotNull String entryName) { - super(stack.getItem(), weight, 1, NO_CONDITIONS, new LootItemFunction[] { lootFunction }); - this.stack = stack; - this.entryName = entryName; - } - - public void createItemStack(Consumer stackConsumer, LootContext lootContext) { - stackConsumer.accept(this.stack.copy()); - } - - @Override - public @NotNull String toString() { - return "GTLootEntryItem{name=" + entryName + ", stack=" + stack.toString() + '}'; - } - } - - public static class RandomWeightLootFunction extends LootItemConditionalFunction implements LootItemFunction { - - public static final LootItemFunctionType TYPE = GTRegistries.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, - GTCEu.id("random_weight"), new LootItemFunctionType(new Serializer())); - - private final ItemStack stack; - @Getter - private final int minAmount; - @Getter - private final int maxAmount; - - public RandomWeightLootFunction(@NotNull ItemStack stack, int minAmount, int maxAmount) { - super(NO_CONDITIONS); - Preconditions.checkArgument(minAmount <= maxAmount, "minAmount must be <= maxAmount"); - this.stack = stack; - this.minAmount = minAmount; - this.maxAmount = maxAmount; - } - - public static void init() { - // Do nothing here. This just ensures that TYPE is being set immediately when called. - } - - @Override - public LootItemFunctionType getType() { - return TYPE; - } - - @Override - protected ItemStack run(ItemStack itemStack, LootContext context) { - if (stack.getDamageValue() != 0) { - itemStack.setDamageValue(stack.getDamageValue()); - } - CompoundTag tagCompound = stack.getTag(); - if (tagCompound != null) { - itemStack.setTag(tagCompound.copy()); - } - - if (minAmount == maxAmount) { - itemStack.setCount(minAmount); - return itemStack; - } - - int count = Math.min(minAmount + context.getRandom().nextInt(maxAmount - minAmount + 1), - stack.getMaxStackSize()); - itemStack.setCount(count); - return itemStack; - } - - public static class Serializer extends LootItemConditionalFunction.Serializer { - - /** - * Serialize the {@link SetItemCountFunction} by putting its data into the JsonObject. - */ - public void serialize(JsonObject json, RandomWeightLootFunction setItemCountFunction, - JsonSerializationContext serializationContext) { - super.serialize(json, setItemCountFunction, serializationContext); - json.add("min", serializationContext.serialize(setItemCountFunction.minAmount)); - json.add("max", serializationContext.serialize(setItemCountFunction.maxAmount)); - JsonObject stack = new JsonObject(); - stack.addProperty("item", - ForgeRegistries.ITEMS.getKey(setItemCountFunction.stack.getItem()).toString()); - stack.addProperty("count", setItemCountFunction.stack.getCount()); - if (setItemCountFunction.stack.hasTag()) - stack.addProperty("nbt", setItemCountFunction.stack.getTag().toString()); - json.add("stack", stack); - } - - public RandomWeightLootFunction deserialize(JsonObject object, - JsonDeserializationContext deserializationContext, - LootItemCondition[] conditions) { - ItemStack stack = CraftingHelper.getItemStack(object.getAsJsonObject("stack"), true); - int min = GsonHelper.getAsInt(object, "min"); - int max = GsonHelper.getAsInt(object, "max"); - return new RandomWeightLootFunction(stack, min, max); - } - } - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/DungeonLootLoader.java b/src/main/java/com/gregtechceu/gtceu/data/loot/DungeonLootLoader.java deleted file mode 100644 index 6678c7d23b3..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/data/loot/DungeonLootLoader.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.gregtechceu.gtceu.data.loot; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.data.chemical.ChemicalHelper; -import com.gregtechceu.gtceu.api.data.tag.TagPrefix; -import com.gregtechceu.gtceu.common.data.GTItems; -import com.gregtechceu.gtceu.common.data.GTMaterials; -import com.gregtechceu.gtceu.config.ConfigHolder; - -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.storage.loot.BuiltInLootTables; - -public class DungeonLootLoader { - - private DungeonLootLoader() {} - - public static void init() { - if (ConfigHolder.INSTANCE.worldgen.addLoot || ConfigHolder.INSTANCE.worldgen.increaseDungeonLoot) { - GTCEu.LOGGER.info("Registering dungeon loot..."); - ChestGenHooks.init(); - } - if (ConfigHolder.INSTANCE.worldgen.addLoot) { - ChestGenHooks.addItem(BuiltInLootTables.SPAWN_BONUS_CHEST, GTItems.BOTTLE_PURPLE_DRINK.asStack(), 8, 16, 2); - - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, GTItems.BOTTLE_PURPLE_DRINK.asStack(), 4, 8, 80); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Silver), 1, 6, 120); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Lead), 1, 6, 30); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Steel), 1, 6, 60); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Bronze), 1, 6, 60); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Manganese), 1, 6, 60); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 1, 6, 10); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Emerald), 1, 6, 20); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, ChemicalHelper.get(TagPrefix.gem, GTMaterials.Ruby), - 1, 6, 20); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Sapphire), 1, 6, 20); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GreenSapphire), 1, 6, 20); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Olivine), 1, 6, 20); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetRed), 1, 6, 40); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetYellow), 1, 6, 40); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Neodymium), 1, 6, 40); - ChestGenHooks.addItem(BuiltInLootTables.SIMPLE_DUNGEON, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Chromium), 1, 3, 40); - - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Silver), 4, 16, 12); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Platinum), 2, 8, 4); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, ChemicalHelper.get(TagPrefix.gem, GTMaterials.Ruby), - 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Sapphire), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GreenSapphire), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Olivine), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetRed), 2, 8, 4); - ChestGenHooks.addItem(BuiltInLootTables.DESERT_PYRAMID, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetYellow), 2, 8, 4); - - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - GTItems.ZERO_POINT_MODULE.get().getChargedStack(Long.MAX_VALUE), 1, 1, 1); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Bronze), 4, 16, 12); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, ChemicalHelper.get(TagPrefix.gem, GTMaterials.Ruby), - 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Sapphire), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GreenSapphire), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Olivine), 2, 8, 2); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetRed), 2, 8, 4); - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetYellow), 2, 8, 4); - - ChestGenHooks.addItem(BuiltInLootTables.JUNGLE_TEMPLE_DISPENSER, new ItemStack(Items.FIRE_CHARGE, 1), 2, 8, - 30); - - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Silver), 1, 4, 12); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Lead), 1, 4, 3); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Steel), 1, 4, 6); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Bronze), 1, 4, 6); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Sapphire), 1, 4, 2); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GreenSapphire), 1, 4, 2); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Olivine), 1, 4, 2); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetRed), 1, 4, 4); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.GarnetYellow), 1, 4, 4); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Ruby), 1, 4, 2); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.gem, GTMaterials.Emerald), 1, 4, 2); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 3, 12, 1); - ChestGenHooks.addItem(BuiltInLootTables.ABANDONED_MINESHAFT, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 1, 4, 1); - - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Chromium), 1, 4, 6); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Neodymium), 2, 8, 6); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Manganese), 2, 8, 12); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Steel), 4, 12, 12); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Bronze), 4, 12, 12); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Brass), 4, 12, 12); - ChestGenHooks.addItem(BuiltInLootTables.VILLAGE_WEAPONSMITH, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 4, 12, 1); - - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 4, 8, 6); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Steel), 8, 16, 12); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Bronze), 8, 16, 12); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.Manganese), 4, 8, 12); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Neodymium), 4, 8, 6); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CROSSING, - ChemicalHelper.get(TagPrefix.dust, GTMaterials.Chromium), 2, 4, 6); - - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CORRIDOR, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 2, 8, 6); - ChestGenHooks.addItem(BuiltInLootTables.STRONGHOLD_CORRIDOR, - ChemicalHelper.get(TagPrefix.ingot, GTMaterials.DamascusSteel), 3, 12, 6); - } - if (ConfigHolder.INSTANCE.worldgen.increaseDungeonLoot) { - ChestGenHooks.addRolls(BuiltInLootTables.SPAWN_BONUS_CHEST, 2, 4); - ChestGenHooks.addRolls(BuiltInLootTables.SIMPLE_DUNGEON, 1, 3); - ChestGenHooks.addRolls(BuiltInLootTables.DESERT_PYRAMID, 2, 4); - ChestGenHooks.addRolls(BuiltInLootTables.JUNGLE_TEMPLE, 4, 8); - ChestGenHooks.addRolls(BuiltInLootTables.JUNGLE_TEMPLE_DISPENSER, 0, 2); - ChestGenHooks.addRolls(BuiltInLootTables.ABANDONED_MINESHAFT, 1, 3); - ChestGenHooks.addRolls(BuiltInLootTables.VILLAGE_WEAPONSMITH, 2, 6); - ChestGenHooks.addRolls(BuiltInLootTables.STRONGHOLD_CROSSING, 2, 4); - ChestGenHooks.addRolls(BuiltInLootTables.STRONGHOLD_CORRIDOR, 2, 4); - ChestGenHooks.addRolls(BuiltInLootTables.STRONGHOLD_LIBRARY, 4, 8); - } - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java new file mode 100644 index 00000000000..ced74e00842 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java @@ -0,0 +1,43 @@ +package com.gregtechceu.gtceu.data.loot; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.loot.modifier.AddTableLootModifier; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.BuiltInLootTables; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraftforge.common.data.GlobalLootModifierProvider; +import net.minecraftforge.common.loot.LootTableIdCondition; +import org.apache.commons.lang3.ArrayUtils; + +import static com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition.*; + +public class GTLootModifications extends GlobalLootModifierProvider { + + private static final LootItemCondition[] LOOT_CONFIG_ENABLED_CONDITION = { addLootConfigEnabled().build() }; + + public GTLootModifications(PackOutput output) { + super(output, GTCEu.MOD_ID); + } + + @Override + protected void start() { + addAddTableModifier(BuiltInLootTables.SPAWN_BONUS_CHEST, GTLootTables.SPAWN_BONUS_CHEST_EXTRA); + addAddTableModifier(BuiltInLootTables.SIMPLE_DUNGEON, GTLootTables.SIMPLE_DUNGEON_EXTRA); + addAddTableModifier(BuiltInLootTables.DESERT_PYRAMID, GTLootTables.DESERT_PYRAMID_EXTRA); + addAddTableModifier(BuiltInLootTables.JUNGLE_TEMPLE, GTLootTables.JUNGLE_TEMPLE_EXTRA); + addAddTableModifier(BuiltInLootTables.JUNGLE_TEMPLE_DISPENSER, GTLootTables.JUNGLE_TEMPLE_DISPENSER_EXTRA); + addAddTableModifier(BuiltInLootTables.ABANDONED_MINESHAFT, GTLootTables.ABANDONED_MINESHAFT_EXTRA); + addAddTableModifier(BuiltInLootTables.VILLAGE_WEAPONSMITH, GTLootTables.VILLAGE_WEAPONSMITH_EXTRA); + addAddTableModifier(BuiltInLootTables.STRONGHOLD_CROSSING, GTLootTables.STRONGHOLD_CROSSING_EXTRA); + addAddTableModifier(BuiltInLootTables.STRONGHOLD_CORRIDOR, GTLootTables.STRONGHOLD_CORRIDOR_EXTRA); + } + + protected void addAddTableModifier(ResourceLocation targetLootTableId, ResourceLocation addedLootTableId) { + final LootItemCondition[] conditions = ArrayUtils.add( + LOOT_CONFIG_ENABLED_CONDITION, + LootTableIdCondition.builder(targetLootTableId).build() + ); + add(addedLootTableId.getPath(), new AddTableLootModifier(conditions, addedLootTableId)); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java index 980af1a734c..513de7a0298 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java @@ -1,9 +1,16 @@ package com.gregtechceu.gtceu.data.loot; +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.data.chemical.ChemicalHelper; +import com.gregtechceu.gtceu.api.data.tag.TagPrefix; +import com.gregtechceu.gtceu.common.data.GTItems; +import com.gregtechceu.gtceu.common.data.GTMaterials; import net.minecraft.data.PackOutput; import net.minecraft.data.loot.LootTableProvider; import net.minecraft.data.loot.LootTableSubProvider; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; @@ -11,8 +18,13 @@ import java.util.Set; import java.util.function.BiConsumer; +// spotless:off + +import static com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition.*; +import static com.gregtechceu.gtceu.common.loot.function.SetEUChargeFunction.setCharge; import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*; import static net.minecraft.world.level.storage.loot.LootPool.lootPool; +import static net.minecraft.world.level.storage.loot.LootTable.lootTable; import static net.minecraft.world.level.storage.loot.entries.LootItem.lootTableItem; import static net.minecraft.world.level.storage.loot.functions.SetItemCountFunction.*; import static net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition.*; @@ -22,16 +34,332 @@ public class GTLootTables extends LootTableProvider { + public static final ResourceLocation SPAWN_BONUS_CHEST_EXTRA = GTCEu.id("chests/extra/spawn_bonus_chest"); + public static final ResourceLocation SIMPLE_DUNGEON_EXTRA = GTCEu.id("chests/extra/simple_dungeon"); + public static final ResourceLocation DESERT_PYRAMID_EXTRA = GTCEu.id("chests/extra/desert_pyramid"); + public static final ResourceLocation JUNGLE_TEMPLE_EXTRA = GTCEu.id("chests/extra/jungle_temple"); + public static final ResourceLocation JUNGLE_TEMPLE_DISPENSER_EXTRA = GTCEu.id("chests/extra/jungle_temple_dispenser"); + public static final ResourceLocation ABANDONED_MINESHAFT_EXTRA = GTCEu.id("chests/extra/abandoned_mineshaft"); + public static final ResourceLocation VILLAGE_WEAPONSMITH_EXTRA = GTCEu.id("chests/extra/village_weaponsmith"); + public static final ResourceLocation STRONGHOLD_CROSSING_EXTRA = GTCEu.id("chests/extra/stronghold_crossing"); + public static final ResourceLocation STRONGHOLD_CORRIDOR_EXTRA = GTCEu.id("chests/extra/stronghold_corridor"); + public GTLootTables(PackOutput output) { super(output, Set.of(), List.of( new SubProviderEntry(ChestLoot::new, LootContextParamSets.CHEST) )); } + /** + *

ALL FORMATTING IS INTENTIONAL! DO NOT CHANGE IT!!

+ * @author screret + */ public static class ChestLoot implements LootTableSubProvider { + // Additional chest loot tables to inject. Note that all roll amounts are lower than in 1.12 because these + // aren't added into the loot tables' existing pools (they're new pools). + // That means we must take some care to avoid overfilling loot chests. @Override public void generate(BiConsumer provider) { + // Negative roll values are skipped, so most rolls' minimums are weighed toward 0. That's intentional and + // is done to limit the amount of items added to chests. + + provider.accept(SPAWN_BONUS_CHEST_EXTRA, lootTable() + .withPool(spawnBonusChestLoot().setRolls(between(0, 1))) + .withPool(spawnBonusChestLoot().setRolls(between(1, 2)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(SIMPLE_DUNGEON_EXTRA, lootTable() + // purple drink/sus record loot pool + // usually gives nothing, sometimes purple drink and very rarely the sus record + .withPool(lootPool() + .setRolls(between(-2, 1)) + .add(lootTableItem(GTItems.BOTTLE_PURPLE_DRINK) + .setWeight(15) + .apply(setCount(between(4, 8)))) + .add(lootTableItem(GTItems.SUS_RECORD) + .setWeight(1)) // this should appear in 1/64 dungeon chests on average + ) + // basic loot pool + .withPool(simpleDungeonLoot().setRolls(between(-1, 2))) + // same loot pool again but with the extra rolls condition this time + .withPool(simpleDungeonLoot().setRolls(between(-1, 2)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(DESERT_PYRAMID_EXTRA, lootTable() + .withPool(desertPyramidLoot().setRolls(between(-1, 3))) + .withPool(desertPyramidLoot().setRolls(between(-1, 3)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(JUNGLE_TEMPLE_EXTRA, lootTable() + .withPool(lootPool() + .setRolls(exactly(1)) + .add(lootTableItem(GTItems.ZERO_POINT_MODULE).apply(setCharge(Long.MAX_VALUE))) + .when(randomChance(0.01f)) + ) + .withPool(jungleTempleLoot().setRolls(between(-1, 4))) + .withPool(jungleTempleLoot().setRolls(between(-1, 4)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(JUNGLE_TEMPLE_DISPENSER_EXTRA, lootTable() + .withPool(lootPool() + .setRolls(between(0, 1)) + .add(lootTableItem(Items.FIRE_CHARGE) + .apply(setCount(between(2, 8))) + ) + ) + ); + + provider.accept(ABANDONED_MINESHAFT_EXTRA, lootTable() + .withPool(abandonedMineshaftLoot().setRolls(between(-1, 2))) + .withPool(abandonedMineshaftLoot().setRolls(between(-1, 2)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(VILLAGE_WEAPONSMITH_EXTRA, lootTable() + .withPool(villageWeaponsmithLoot().setRolls(between(-1, 4))) + .withPool(villageWeaponsmithLoot().setRolls(between(-1, 4)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(STRONGHOLD_CROSSING_EXTRA, lootTable() + .withPool(strongholdCrossingLoot().setRolls(between(-1, 3))) + .withPool(strongholdCrossingLoot().setRolls(between(-1, 3)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + + provider.accept(STRONGHOLD_CORRIDOR_EXTRA, lootTable() + .withPool(strongholdCorridorLoot().setRolls(between(-2, 2))) + .withPool(strongholdCorridorLoot().setRolls(between(-2, 2)) + .when(increaseDungeonLootConfigEnabled()) + ) + ); + } + + private static LootPool.Builder spawnBonusChestLoot() { + return lootPool() + .add(lootTableItem(GTItems.BOTTLE_PURPLE_DRINK) + .apply(setCount(between(8, 16)))); + } + + private static LootPool.Builder simpleDungeonLoot() { + return lootPool() + .add(lootTableItem(GTItems.BOTTLE_PURPLE_DRINK) + .setWeight(8) + .apply(setCount(between(4, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Silver)) + .setWeight(12) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Lead)) + .setWeight(3) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Steel)) + .setWeight(6) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Bronze)) + .setWeight(6) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Manganese)) + .setWeight(6) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Emerald)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Ruby)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Sapphire)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GreenSapphire)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Olivine)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetRed)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetYellow)) + .setWeight(2) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Neodymium)) + .setWeight(4) + .apply(setCount(between(1, 6)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Chromium)) + .setWeight(4) + .apply(setCount(between(1, 6)))); + } + + private static LootPool.Builder desertPyramidLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Silver)) + .setWeight(12) + .apply(setCount(between(4, 16)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Platinum)) + .setWeight(4) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Ruby)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Sapphire)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GreenSapphire)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Olivine)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetRed)) + .setWeight(4) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetYellow)) + .setWeight(4) + .apply(setCount(between(2, 8)))); + } + + private static LootPool.Builder jungleTempleLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Bronze)) + .setWeight(12) + .apply(setCount(between(4, 16)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Ruby)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Sapphire)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GreenSapphire)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Olivine)) + .setWeight(2) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetRed)) + .setWeight(4) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetYellow)) + .setWeight(4) + .apply(setCount(between(2, 8)))); + } + + private static LootPool.Builder abandonedMineshaftLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Silver)) + .setWeight(12) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Lead)) + .setWeight(3) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Steel)) + .setWeight(6) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Bronze)) + .setWeight(6) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Manganese)) + .setWeight(6) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Sapphire)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GreenSapphire)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Olivine)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetRed)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.GarnetYellow)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Ruby)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.gem, GTMaterials.Emerald)) + .setWeight(2) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(3, 12)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(1, 4)))); + } + + private static LootPool.Builder villageWeaponsmithLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Chromium)) + .setWeight(6) + .apply(setCount(between(1, 4)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Neodymium)) + .setWeight(6) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Manganese)) + .setWeight(12) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Steel)) + .setWeight(12) + .apply(setCount(between(4, 12)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Bronze)) + .setWeight(12) + .apply(setCount(between(4, 12)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Brass)) + .setWeight(12) + .apply(setCount(between(4, 12)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(4, 12)))); + } + + private static LootPool.Builder strongholdCrossingLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(6) + .apply(setCount(between(4, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Steel)) + .setWeight(12) + .apply(setCount(between(8, 16)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Bronze)) + .setWeight(12) + .apply(setCount(between(8, 16)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.Manganese)) + .setWeight(12) + .apply(setCount(between(4, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Neodymium)) + .setWeight(6) + .apply(setCount(between(4, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.dust, GTMaterials.Chromium)) + .setWeight(6) + .apply(setCount(between(2, 4)))); + } + + private static LootPool.Builder strongholdCorridorLoot() { + return lootPool() + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(2, 8)))) + .add(lootTableItem(ChemicalHelper.getItem(TagPrefix.ingot, GTMaterials.DamascusSteel)) + .setWeight(1) + .apply(setCount(between(3, 12)))); } } } +// spotless:on diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java b/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java deleted file mode 100644 index bb9b6fd5e51..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/data/loot/NewDungeonLootLoader.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.gregtechceu.gtceu.data.loot; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition; -import net.minecraft.data.PackOutput; -import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraftforge.common.data.GlobalLootModifierProvider; -import org.apache.commons.lang3.ArrayUtils; - -public class NewDungeonLootLoader extends GlobalLootModifierProvider { - - public NewDungeonLootLoader(PackOutput output) { - super(output, GTCEu.MOD_ID); - } - - @Override - protected void start() { - final LootItemCondition[] NORMAL_CONDITION = { new GTConfigValueCondition("worldgen.addLoot") }; - final LootItemCondition[] INCREASED_LOOT_CONDITION = ArrayUtils.add(NORMAL_CONDITION, new GTConfigValueCondition("worldgen.increaseDungeonLoot")); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java index 3671e8664f0..990ffc587dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java +++ b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java @@ -10,6 +10,7 @@ * following static imports to your class: *
{@code
  * import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*;
+ * import static net.minecraft.world.level.storage.loot.LootTable.lootTable;
  * import static net.minecraft.world.level.storage.loot.LootPool.lootPool;
  * import static net.minecraft.world.level.storage.loot.entries.LootItem.lootTableItem;
  * import static net.minecraft.world.level.storage.loot.functions.SetItemCountFunction.*;
@@ -43,22 +44,6 @@ public static UniformGenerator between(NumberProvider min, float max) {
         return between(min, constant(max));
     }
 
-    public static UniformGenerator uniform(float min, float max) {
-        return UniformGenerator.between(min, max);
-    }
-
-    public static UniformGenerator uniform(NumberProvider min, NumberProvider max) {
-        return between(min, max);
-    }
-
-    public static UniformGenerator uniform(float min, NumberProvider max) {
-        return between(min, max);
-    }
-
-    public static UniformGenerator uniform(NumberProvider min, float max) {
-        return between(min, max);
-    }
-
     // endregion //
     // region BINOMIAL DISTRIBUTION GENERATOR
 

From 7b3aeb0a5bb6f056c9a6b991d95ec7cc85ddb7be Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Mon, 13 Jul 2026 18:14:42 +0300
Subject: [PATCH 09/61] spotless

---
 .../generator/veins/VeinedVeinGenerator.java  |  6 +-
 .../loot/modifier/AddTableLootModifier.java   | 26 ++++---
 .../loot/serializer/CodecBasedSerializer.java |  5 +-
 .../data/loot/GTGlobalLootModifiers.java      |  5 +-
 .../common/data/loot/GTLootConditions.java    |  2 +-
 .../common/data/loot/GTLootFunctions.java     |  1 +
 .../data/worldgen/GTDensityFunctions.java     |  1 +
 .../data/worldgen/GTPlacedFeatures.java       |  2 +-
 .../data/worldgen/GTPlacementModifiers.java   |  1 +
 .../condition/GTConfigValueCondition.java     |  8 ++-
 .../loot/function/SetEUChargeFunction.java    | 72 ++++++++++---------
 .../modifier/BiomeDependentPlacement.java     |  2 +-
 ...BinomialDistributionGeneratorAccessor.java |  1 +
 .../core/mixins/UniformGeneratorAccessor.java |  1 +
 .../gtceu/data/DataGenerators.java            |  4 +-
 .../gtceu/data/loot/GTLootModifications.java  |  8 +--
 .../gtceu/data/loot/GTLootTables.java         |  6 +-
 .../data/loot/NumberProviderShortcuts.java    |  5 +-
 18 files changed, 90 insertions(+), 66 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java
index 0dbb7c6127b..ca5ef8a0746 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/VeinedVeinGenerator.java
@@ -127,8 +127,10 @@ public Map generate(WorldGenLevel level, RandomSource
         }
 
         final Blender finalizedBlender = blender;
-        DensityFunction veinToggle = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_TOGGLE), randomState);
-        DensityFunction veinRidged = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_RIDGED), randomState);
+        DensityFunction veinToggle = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_TOGGLE),
+                randomState);
+        DensityFunction veinRidged = mapToNoise(densityFunctions.get(GTDensityFunctions.NEW_ORE_VEIN_RIDGED),
+                randomState);
 
         int size = entry.clusterSize().sample(random);
 
diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java
index 088836f7eba..758ffc181cc 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/loot/modifier/AddTableLootModifier.java
@@ -1,11 +1,7 @@
 package com.gregtechceu.gtceu.api.loot.modifier;
 
 import com.gregtechceu.gtceu.common.data.loot.GTGlobalLootModifiers;
-import com.mojang.serialization.Codec;
-import com.mojang.serialization.codecs.RecordCodecBuilder;
-import it.unimi.dsi.fastutil.objects.ObjectArrayList;
-import lombok.Getter;
-import lombok.experimental.Accessors;
+
 import net.minecraft.resources.ResourceLocation;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.level.storage.loot.LootContext;
@@ -14,14 +10,24 @@
 import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
 import net.minecraftforge.common.loot.IGlobalLootModifier;
 import net.minecraftforge.common.loot.LootModifier;
+
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import lombok.Getter;
+import lombok.experimental.Accessors;
 import org.jetbrains.annotations.ApiStatus;
 
 /**
- * 

Loot modifier that rolls one loot table (the "subtable" and adds the results to the loot being modified (the "target table"). + *

+ * Loot modifier that rolls one loot table (the "subtable" and adds the results to the loot being modified (the "target + * table"). * Loot modifiers are not rolled for the subtable, as that could result in the subtables' - * items being modified twice (by downstream loot modifiers modifying the target table).

+ * items being modified twice (by downstream loot modifiers modifying the target table). + *

* - *

Json format: + *

+ * Json format: * *

{@code
  * {
@@ -36,6 +42,7 @@
 // copy of NeoForge's AddTableLootModifier, tweaked slightly to work on 1.20
 @Accessors(fluent = true)
 public class AddTableLootModifier extends LootModifier {
+
     /**
      * @see GTGlobalLootModifiers#ADD_TABLE_LOOT_MODIFIER
      */
@@ -61,7 +68,8 @@ protected ObjectArrayList doApply(ObjectArrayList generate
             // Don't run loot modifiers for subtables;
             // the added loot will be modifiable by downstream loot modifiers modifying the target table,
             // so if we modify it here then it could get modified twice.
-            extraTable.getRandomItemsRaw(context, LootTable.createStackSplitter(context.getLevel(), generatedLoot::add));
+            extraTable.getRandomItemsRaw(context,
+                    LootTable.createStackSplitter(context.getLevel(), generatedLoot::add));
         });
         return generatedLoot;
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java
index 4fe813f60f2..21bf755cf28 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/loot/serializer/CodecBasedSerializer.java
@@ -1,13 +1,14 @@
 package com.gregtechceu.gtceu.api.loot.serializer;
 
+import net.minecraft.util.GsonHelper;
+import net.minecraft.world.level.storage.loot.Serializer;
+
 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonSerializationContext;
 import com.mojang.serialization.JsonOps;
 import com.mojang.serialization.MapCodec;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.world.level.storage.loot.Serializer;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java
index c9b9fee38c7..b6a1ee5f427 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTGlobalLootModifiers.java
@@ -2,13 +2,15 @@
 
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.loot.modifier.AddTableLootModifier;
-import com.mojang.serialization.Codec;
+
 import net.minecraftforge.common.loot.IGlobalLootModifier;
 import net.minecraftforge.eventbus.api.IEventBus;
 import net.minecraftforge.registries.DeferredRegister;
 import net.minecraftforge.registries.ForgeRegistries;
 import net.minecraftforge.registries.RegistryObject;
 
+import com.mojang.serialization.Codec;
+
 public class GTGlobalLootModifiers {
     // spotless:off
 
@@ -20,7 +22,6 @@ public class GTGlobalLootModifiers {
 
     // spotless:on
 
-
     public static void init(IEventBus modBus) {
         GLOBAL_LOOT_MODIFIER_SERIALIZERS.register(modBus);
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java
index eb5d57f93d0..c7fc82ccd55 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootConditions.java
@@ -3,6 +3,7 @@
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.loot.serializer.CodecBasedSerializer;
 import com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition;
+
 import net.minecraft.core.registries.Registries;
 import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
 import net.minecraftforge.eventbus.api.IEventBus;
@@ -19,7 +20,6 @@ public class GTLootConditions {
 
     // spotless:on
 
-
     public static void init(IEventBus modBus) {
         LOOT_CONDITION_TYPES.register(modBus);
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java
index 6301fe93eac..e191c1d1857 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/loot/GTLootFunctions.java
@@ -3,6 +3,7 @@
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.loot.serializer.CodecBasedSerializer;
 import com.gregtechceu.gtceu.common.loot.function.SetEUChargeFunction;
+
 import net.minecraft.core.registries.Registries;
 import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType;
 import net.minecraftforge.eventbus.api.IEventBus;
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java
index a9974b8c315..5749ba368b5 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTDensityFunctions.java
@@ -1,6 +1,7 @@
 package com.gregtechceu.gtceu.common.data.worldgen;
 
 import com.gregtechceu.gtceu.GTCEu;
+
 import net.minecraft.core.Holder;
 import net.minecraft.core.HolderGetter;
 import net.minecraft.core.registries.Registries;
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java
index 4954b4253a0..8a6e3a6e3f6 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacedFeatures.java
@@ -2,8 +2,8 @@
 
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier;
-import com.gregtechceu.gtceu.common.worldgen.modifier.BiomeDependentPlacement;
 import com.gregtechceu.gtceu.common.data.GTBlocks;
+import com.gregtechceu.gtceu.common.worldgen.modifier.BiomeDependentPlacement;
 import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement;
 import com.gregtechceu.gtceu.data.recipe.CustomTags;
 
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java
index bb5eaaaa081..22576b9c5d9 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/worldgen/GTPlacementModifiers.java
@@ -3,6 +3,7 @@
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.common.worldgen.modifier.BiomeDependentPlacement;
 import com.gregtechceu.gtceu.common.worldgen.modifier.RubberTreeChancePlacement;
+
 import net.minecraft.core.registries.Registries;
 import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
 import net.minecraftforge.eventbus.api.IEventBus;
diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java
index 7cb332d06c4..d104ffbb584 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/loot/condition/GTConfigValueCondition.java
@@ -2,15 +2,17 @@
 
 import com.gregtechceu.gtceu.common.data.loot.GTLootConditions;
 import com.gregtechceu.gtceu.config.ConfigHolder;
+
+import net.minecraft.world.level.storage.loot.LootContext;
+import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
+import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
+
 import com.mojang.serialization.Codec;
 import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 import dev.toma.configuration.config.value.IConfigValue;
 import lombok.Getter;
 import lombok.experimental.Accessors;
-import net.minecraft.world.level.storage.loot.LootContext;
-import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
-import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
 
 import java.util.Optional;
 import java.util.function.BooleanSupplier;
diff --git a/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java b/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java
index a927b4923d6..677a0325133 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/loot/function/SetEUChargeFunction.java
@@ -1,50 +1,52 @@
 package com.gregtechceu.gtceu.common.loot.function;
 
-import com.google.gson.*;
 import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper;
 import com.gregtechceu.gtceu.api.capability.IElectricItem;
 import com.gregtechceu.gtceu.common.data.loot.GTLootFunctions;
 import com.gregtechceu.gtceu.utils.codec.GTCodecUtils;
-import com.mojang.serialization.MapCodec;
-import com.mojang.serialization.codecs.RecordCodecBuilder;
+
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.level.storage.loot.LootContext;
 import net.minecraft.world.level.storage.loot.functions.*;
 import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
 import net.minecraftforge.common.loot.LootModifier;
 
+import com.google.gson.*;
+import com.mojang.serialization.MapCodec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
 public class SetEUChargeFunction extends LootItemConditionalFunction {
 
-   // spotless:off
-   public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
-           LootModifier.LOOT_CONDITIONS_CODEC.fieldOf("conditions").forGetter(fn -> fn.predicates),
-           GTCodecUtils.NON_NEGATIVE_LONG.fieldOf("charge").forGetter(fn -> fn.charge)
-   ).apply(instance, SetEUChargeFunction::new));
-   // spotless:on
-
-   protected final long charge;
-
-   protected SetEUChargeFunction(LootItemCondition[] conditions, long charge) {
-      super(conditions);
-      this.charge = charge;
-   }
-
-   @Override
-   public LootItemFunctionType getType() {
-      return GTLootFunctions.SET_EU_CHARGE.get();
-   }
-
-   @Override
-   public ItemStack run(ItemStack stack, LootContext context) {
-      IElectricItem electricItem = GTCapabilityHelper.getElectricItem(stack);
-      if (electricItem == null) {
-         return stack;
-      }
-      electricItem.charge(this.charge, Integer.MAX_VALUE, true, false);
-      return stack;
-   }
-
-   public static LootItemConditionalFunction.Builder setCharge(long charge) {
-      return simpleBuilder(conditions -> new SetEUChargeFunction(conditions, charge));
-   }
+    // spotless:off
+    public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
+             LootModifier.LOOT_CONDITIONS_CODEC.fieldOf("conditions").forGetter(fn -> fn.predicates),
+             GTCodecUtils.NON_NEGATIVE_LONG.fieldOf("charge").forGetter(fn -> fn.charge)
+    ).apply(instance, SetEUChargeFunction::new));
+    // spotless:on
+
+    protected final long charge;
+
+    protected SetEUChargeFunction(LootItemCondition[] conditions, long charge) {
+        super(conditions);
+        this.charge = charge;
+    }
+
+    @Override
+    public LootItemFunctionType getType() {
+        return GTLootFunctions.SET_EU_CHARGE.get();
+    }
+
+    @Override
+    public ItemStack run(ItemStack stack, LootContext context) {
+        IElectricItem electricItem = GTCapabilityHelper.getElectricItem(stack);
+        if (electricItem == null) {
+            return stack;
+        }
+        electricItem.charge(this.charge, Integer.MAX_VALUE, true, false);
+        return stack;
+    }
+
+    public static LootItemConditionalFunction.Builder setCharge(long charge) {
+        return simpleBuilder(conditions -> new SetEUChargeFunction(conditions, charge));
+    }
 }
diff --git a/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java
index a37b4110ae9..b88d8bb4a4a 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/worldgen/modifier/BiomeDependentPlacement.java
@@ -1,8 +1,8 @@
 package com.gregtechceu.gtceu.common.worldgen.modifier;
 
 import com.gregtechceu.gtceu.api.data.worldgen.BiomeWeightModifier;
-
 import com.gregtechceu.gtceu.common.data.worldgen.GTPlacementModifiers;
+
 import net.minecraft.core.BlockPos;
 import net.minecraft.util.RandomSource;
 import net.minecraft.world.level.levelgen.placement.PlacementContext;
diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java
index 26b98aa9108..07b834faa04 100644
--- a/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java
+++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/BinomialDistributionGeneratorAccessor.java
@@ -2,6 +2,7 @@
 
 import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator;
 import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.gen.Invoker;
 
diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java
index 9149029eafe..4d7b626e2ff 100644
--- a/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java
+++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/UniformGeneratorAccessor.java
@@ -2,6 +2,7 @@
 
 import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
 import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
+
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.gen.Invoker;
 
diff --git a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java
index 215811d8eff..8c7e4b83288 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/DataGenerators.java
@@ -2,10 +2,10 @@
 
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.registry.registrate.SoundEntryBuilder;
-import com.gregtechceu.gtceu.common.data.worldgen.*;
 import com.gregtechceu.gtceu.common.data.GTDamageTypes;
-import com.gregtechceu.gtceu.data.loot.GTLootTables;
+import com.gregtechceu.gtceu.common.data.worldgen.*;
 import com.gregtechceu.gtceu.data.loot.GTLootModifications;
+import com.gregtechceu.gtceu.data.loot.GTLootTables;
 import com.gregtechceu.gtceu.data.tags.BiomeTagsLoader;
 import com.gregtechceu.gtceu.data.tags.DamageTagsLoader;
 
diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java
index ced74e00842..978fc687f83 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootModifications.java
@@ -2,12 +2,14 @@
 
 import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.loot.modifier.AddTableLootModifier;
+
 import net.minecraft.data.PackOutput;
 import net.minecraft.resources.ResourceLocation;
 import net.minecraft.world.level.storage.loot.BuiltInLootTables;
 import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
 import net.minecraftforge.common.data.GlobalLootModifierProvider;
 import net.minecraftforge.common.loot.LootTableIdCondition;
+
 import org.apache.commons.lang3.ArrayUtils;
 
 import static com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition.*;
@@ -34,10 +36,8 @@ protected void start() {
     }
 
     protected void addAddTableModifier(ResourceLocation targetLootTableId, ResourceLocation addedLootTableId) {
-        final LootItemCondition[] conditions = ArrayUtils.add(
-                LOOT_CONFIG_ENABLED_CONDITION,
-                LootTableIdCondition.builder(targetLootTableId).build()
-        );
+        final LootItemCondition[] conditions = ArrayUtils.add(LOOT_CONFIG_ENABLED_CONDITION,
+                LootTableIdCondition.builder(targetLootTableId).build());
         add(addedLootTableId.getPath(), new AddTableLootModifier(conditions, addedLootTableId));
     }
 }
diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java
index 513de7a0298..3b2073c460e 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/loot/GTLootTables.java
@@ -5,6 +5,7 @@
 import com.gregtechceu.gtceu.api.data.tag.TagPrefix;
 import com.gregtechceu.gtceu.common.data.GTItems;
 import com.gregtechceu.gtceu.common.data.GTMaterials;
+
 import net.minecraft.data.PackOutput;
 import net.minecraft.data.loot.LootTableProvider;
 import net.minecraft.data.loot.LootTableSubProvider;
@@ -18,8 +19,6 @@
 import java.util.Set;
 import java.util.function.BiConsumer;
 
-// spotless:off
-
 import static com.gregtechceu.gtceu.common.loot.condition.GTConfigValueCondition.*;
 import static com.gregtechceu.gtceu.common.loot.function.SetEUChargeFunction.setCharge;
 import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*;
@@ -28,10 +27,11 @@
 import static net.minecraft.world.level.storage.loot.entries.LootItem.lootTableItem;
 import static net.minecraft.world.level.storage.loot.functions.SetItemCountFunction.*;
 import static net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition.*;
+import static net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator.*;
 import static net.minecraft.world.level.storage.loot.providers.number.ConstantValue.*;
 import static net.minecraft.world.level.storage.loot.providers.number.UniformGenerator.*;
-import static net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator.*;
 
+// spotless:off
 public class GTLootTables extends LootTableProvider {
 
     public static final ResourceLocation SPAWN_BONUS_CHEST_EXTRA = GTCEu.id("chests/extra/spawn_bonus_chest");
diff --git a/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java
index 990ffc587dd..8b92cad24b8 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/loot/NumberProviderShortcuts.java
@@ -2,12 +2,15 @@
 
 import com.gregtechceu.gtceu.core.mixins.BinomialDistributionGeneratorAccessor;
 import com.gregtechceu.gtceu.core.mixins.UniformGeneratorAccessor;
-import lombok.experimental.UtilityClass;
+
 import net.minecraft.world.level.storage.loot.providers.number.*;
 
+import lombok.experimental.UtilityClass;
+
 /**
  * Utility class for working with loot tables and their number providers. To use this class efficiently, add the
  * following static imports to your class:
+ * 
  * 
{@code
  * import static com.gregtechceu.gtceu.data.loot.NumberProviderShortcuts.*;
  * import static net.minecraft.world.level.storage.loot.LootTable.lootTable;

From 8fbb7e7b477736fc40c49ad633f78cea968c17cc Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Mon, 13 Jul 2026 19:01:22 +0300
Subject: [PATCH 10/61] datagen

---
 .../loot_modifiers/global_loot_modifiers.json |  14 +
 .../chests/extra/abandoned_mineshaft.json     |  14 +
 .../chests/extra/desert_pyramid.json          |  14 +
 .../chests/extra/jungle_temple.json           |  14 +
 .../chests/extra/jungle_temple_dispenser.json |  14 +
 .../chests/extra/simple_dungeon.json          |  14 +
 .../chests/extra/spawn_bonus_chest.json       |  14 +
 .../chests/extra/stronghold_corridor.json     |  14 +
 .../chests/extra/stronghold_crossing.json     |  14 +
 .../chests/extra/village_weaponsmith.json     |  14 +
 .../chests/extra/abandoned_mineshaft.json     | 476 +++++++++++++++
 .../chests/extra/desert_pyramid.json          | 288 +++++++++
 .../chests/extra/jungle_temple.json           | 279 +++++++++
 .../chests/extra/jungle_temple_dispenser.json |  31 +
 .../chests/extra/simple_dungeon.json          | 572 ++++++++++++++++++
 .../chests/extra/spawn_bonus_chest.json       |  62 ++
 .../chests/extra/stronghold_corridor.json     |  92 +++
 .../chests/extra/stronghold_crossing.json     | 224 +++++++
 .../chests/extra/village_weaponsmith.json     | 254 ++++++++
 .../placed_feature/rubber_checked.json        |   2 +-
 20 files changed, 2419 insertions(+), 1 deletion(-)
 create mode 100644 src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/abandoned_mineshaft.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/desert_pyramid.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple_dispenser.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/simple_dungeon.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/spawn_bonus_chest.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_corridor.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_crossing.json
 create mode 100644 src/generated/resources/data/gtceu/loot_modifiers/chests/extra/village_weaponsmith.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/abandoned_mineshaft.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/desert_pyramid.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple_dispenser.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/simple_dungeon.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/spawn_bonus_chest.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_corridor.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_crossing.json
 create mode 100644 src/generated/resources/data/gtceu/loot_tables/chests/extra/village_weaponsmith.json

diff --git a/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json
new file mode 100644
index 00000000000..cccc0d195c6
--- /dev/null
+++ b/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json
@@ -0,0 +1,14 @@
+{
+  "entries": [
+    "gtceu:chests/extra/stronghold_corridor",
+    "gtceu:chests/extra/stronghold_crossing",
+    "gtceu:chests/extra/spawn_bonus_chest",
+    "gtceu:chests/extra/simple_dungeon",
+    "gtceu:chests/extra/village_weaponsmith",
+    "gtceu:chests/extra/desert_pyramid",
+    "gtceu:chests/extra/jungle_temple",
+    "gtceu:chests/extra/abandoned_mineshaft",
+    "gtceu:chests/extra/jungle_temple_dispenser"
+  ],
+  "replace": false
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/abandoned_mineshaft.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/abandoned_mineshaft.json
new file mode 100644
index 00000000000..a90b0aa4d54
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/abandoned_mineshaft.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/abandoned_mineshaft"
+    }
+  ],
+  "table": "gtceu:chests/extra/abandoned_mineshaft"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/desert_pyramid.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/desert_pyramid.json
new file mode 100644
index 00000000000..0c6c95f3a6e
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/desert_pyramid.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/desert_pyramid"
+    }
+  ],
+  "table": "gtceu:chests/extra/desert_pyramid"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple.json
new file mode 100644
index 00000000000..a7b1b4995f4
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/jungle_temple"
+    }
+  ],
+  "table": "gtceu:chests/extra/jungle_temple"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple_dispenser.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple_dispenser.json
new file mode 100644
index 00000000000..d44bd379092
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/jungle_temple_dispenser.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/jungle_temple_dispenser"
+    }
+  ],
+  "table": "gtceu:chests/extra/jungle_temple_dispenser"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/simple_dungeon.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/simple_dungeon.json
new file mode 100644
index 00000000000..6cfdf492cb2
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/simple_dungeon.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/simple_dungeon"
+    }
+  ],
+  "table": "gtceu:chests/extra/simple_dungeon"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/spawn_bonus_chest.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/spawn_bonus_chest.json
new file mode 100644
index 00000000000..3ba88f43632
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/spawn_bonus_chest.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/spawn_bonus_chest"
+    }
+  ],
+  "table": "gtceu:chests/extra/spawn_bonus_chest"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_corridor.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_corridor.json
new file mode 100644
index 00000000000..627aa7df29b
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_corridor.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/stronghold_corridor"
+    }
+  ],
+  "table": "gtceu:chests/extra/stronghold_corridor"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_crossing.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_crossing.json
new file mode 100644
index 00000000000..34103e089b2
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/stronghold_crossing.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/stronghold_crossing"
+    }
+  ],
+  "table": "gtceu:chests/extra/stronghold_crossing"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/village_weaponsmith.json b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/village_weaponsmith.json
new file mode 100644
index 00000000000..aba07e619a7
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_modifiers/chests/extra/village_weaponsmith.json
@@ -0,0 +1,14 @@
+{
+  "type": "gtceu:add_table",
+  "conditions": [
+    {
+      "condition": "gtceu:config_value",
+      "config_field": "worldgen.addLoot"
+    },
+    {
+      "condition": "forge:loot_table_id",
+      "loot_table_id": "minecraft:chests/village/village_weaponsmith"
+    }
+  ],
+  "table": "gtceu:chests/extra/village_weaponsmith"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/abandoned_mineshaft.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/abandoned_mineshaft.json
new file mode 100644
index 00000000000..5491fe7466d
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/abandoned_mineshaft.json
@@ -0,0 +1,476 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:lead_ingot",
+          "weight": 3
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "minecraft:emerald",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 3.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:lead_ingot",
+          "weight": 3
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "minecraft:emerald",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 3.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/abandoned_mineshaft"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/desert_pyramid.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/desert_pyramid.json
new file mode 100644
index 00000000000..5bdc32b9c4d
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/desert_pyramid.json
@@ -0,0 +1,288 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:platinum_ingot",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 3.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:platinum_ingot",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 3.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/desert_pyramid"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple.json
new file mode 100644
index 00000000000..69e3e5fa381
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple.json
@@ -0,0 +1,279 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "chance": 0.01,
+          "condition": "minecraft:random_chance"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "charge": 9223372036854775807,
+              "conditions": [],
+              "function": "gtceu:set_eu_charge"
+            }
+          ],
+          "name": "gtceu:zero_point_module"
+        }
+      ],
+      "rolls": 1.0
+    },
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 4.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 4.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/jungle_temple"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple_dispenser.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple_dispenser.json
new file mode 100644
index 00000000000..128d34d4d70
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/jungle_temple_dispenser.json
@@ -0,0 +1,31 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "minecraft:fire_charge"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 1.0,
+        "min": 0.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/jungle_temple_dispenser"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/simple_dungeon.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/simple_dungeon.json
new file mode 100644
index 00000000000..73c10d2aac7
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/simple_dungeon.json
@@ -0,0 +1,572 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:purple_drink",
+          "weight": 15
+        },
+        {
+          "type": "minecraft:item",
+          "name": "gtceu:sus_record"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 1.0,
+        "min": -2.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:purple_drink",
+          "weight": 8
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:lead_ingot",
+          "weight": 3
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "minecraft:emerald",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:purple_drink",
+          "weight": 8
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:silver_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:lead_ingot",
+          "weight": 3
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "minecraft:emerald",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:ruby_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:green_sapphire_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:olivine_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:red_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:yellow_garnet_gem",
+          "weight": 2
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 4
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 6.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 4
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/simple_dungeon"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/spawn_bonus_chest.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/spawn_bonus_chest.json
new file mode 100644
index 00000000000..c142ab4e1eb
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/spawn_bonus_chest.json
@@ -0,0 +1,62 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:purple_drink"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 1.0,
+        "min": 0.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:purple_drink"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": 1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/spawn_bonus_chest"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_corridor.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_corridor.json
new file mode 100644
index 00000000000..7b9bb9aee45
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_corridor.json
@@ -0,0 +1,92 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 3.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -2.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 3.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 2.0,
+        "min": -2.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/stronghold_corridor"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_crossing.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_crossing.json
new file mode 100644
index 00000000000..d260b8cd418
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/stronghold_crossing.json
@@ -0,0 +1,224 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 6
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 3.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 16.0,
+                "min": 8.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 6
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 3.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/stronghold_crossing"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/loot_tables/chests/extra/village_weaponsmith.json b/src/generated/resources/data/gtceu/loot_tables/chests/extra/village_weaponsmith.json
new file mode 100644
index 00000000000..60f13ce5aaa
--- /dev/null
+++ b/src/generated/resources/data/gtceu/loot_tables/chests/extra/village_weaponsmith.json
@@ -0,0 +1,254 @@
+{
+  "type": "minecraft:chest",
+  "pools": [
+    {
+      "bonus_rolls": 0.0,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:brass_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 4.0,
+        "min": -1.0
+      }
+    },
+    {
+      "bonus_rolls": 0.0,
+      "conditions": [
+        {
+          "condition": "gtceu:config_value",
+          "config_field": "worldgen.increaseDungeonLoot"
+        }
+      ],
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 4.0,
+                "min": 1.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:chromium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:neodymium_dust",
+          "weight": 6
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 8.0,
+                "min": 2.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:manganese_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:steel_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:bronze_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:brass_ingot",
+          "weight": 12
+        },
+        {
+          "type": "minecraft:item",
+          "functions": [
+            {
+              "add": false,
+              "count": {
+                "type": "minecraft:uniform",
+                "max": 12.0,
+                "min": 4.0
+              },
+              "function": "minecraft:set_count"
+            }
+          ],
+          "name": "gtceu:damascus_steel_ingot"
+        }
+      ],
+      "rolls": {
+        "type": "minecraft:uniform",
+        "max": 4.0,
+        "min": -1.0
+      }
+    }
+  ],
+  "random_sequence": "gtceu:chests/extra/village_weaponsmith"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/gtceu/worldgen/placed_feature/rubber_checked.json b/src/generated/resources/data/gtceu/worldgen/placed_feature/rubber_checked.json
index d4bc779df73..008adad79d5 100644
--- a/src/generated/resources/data/gtceu/worldgen/placed_feature/rubber_checked.json
+++ b/src/generated/resources/data/gtceu/worldgen/placed_feature/rubber_checked.json
@@ -2,7 +2,7 @@
   "feature": "gtceu:rubber_tree",
   "placement": [
     {
-      "type": "gtceu:biome_placement",
+      "type": "gtceu:biome_dependent",
       "modifiers": [
         {
           "added_weight": 50,

From 794973a5a1a1126c2cafa2ce8c06a2744bd59f53 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk 
Date: Mon, 13 Jul 2026 17:04:17 +0000
Subject: [PATCH 11/61] Misc Prospector Fixes (#5098)

---
 .../behavior/ProspectorScannerBehavior.java   |  7 ++--
 .../prospector/ProspectorMapHandler.java      | 31 ++++++++++++----
 .../prospector/ProspectorMapTexture.java      | 36 ++++++++-----------
 3 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
index fcef5ba3df2..a9a4d3c9ff3 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
@@ -118,15 +118,16 @@ public ModularPanel buildUI(PlayerInventoryGuiData guiData, PanelSyncManag
         ProspectorMapHandler mapHandler = new ProspectorMapHandler<>(mode, this.radius, 1, searchValue, searchList,
                 panelSyncManager, guiData.getPlayer());
 
-        return ModularPanel.defaultPanel("prospector_scanner", 332, 200)
+        int mapSize = (this.radius * 2 - 1) * 16 + 1;
+        return ModularPanel.defaultPanel("prospector_scanner", mapSize + 156, mapSize + 24)
                 .margin(4)
                 .child(new ToggleButton()
                         .size(18)
                         .top(4).leftRelAnchor(0f, 1f)
                         .decoration()
                         .stateBackground(GTGuiTextures.PROGRESS_BAR_SOLAR_STEEL)
-                        .value(new BoolValue.Dynamic(mapHandler.getTexture()::isDarkMode,
-                                mapHandler.getTexture()::setDarkMode)))
+                        .value(new BoolValue.Dynamic(mapHandler::isDarkMode,
+                                mapHandler::setDarkMode)))
                 .child(Flow.row()
                         .childPadding(10)
                         .margin(6)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
index d799622337d..1b41228962d 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
@@ -1,5 +1,6 @@
 package com.gregtechceu.gtceu.common.mui.widgets.prospector;
 
+import com.gregtechceu.gtceu.GTCEu;
 import com.gregtechceu.gtceu.api.data.chemical.material.Material;
 import com.gregtechceu.gtceu.api.item.component.prospector.ProspectingUpdatePacket;
 import com.gregtechceu.gtceu.api.item.component.prospector.ProspectorMode;
@@ -55,8 +56,11 @@ public class ProspectorMapHandler extends Widget> imp
 
     private final StringValue searchValue;
     private final DynamicSyncHandler syncHandler;
+
+    // client-only; null on server side
+    private @Nullable ProspectorMapTexture texture;
     @Getter
-    private final ProspectorMapTexture texture;
+    private boolean darkMode = true;
 
     // runtime
     @Getter
@@ -79,9 +83,14 @@ public ProspectorMapHandler(ProspectorMode mode, int chunkRadius, int scanInt
         this.player = player;
         this.playerChunkPos = player.chunkPosition();
 
-        this.texture = new ProspectorMapTexture<>(this);
-        background(this.texture);
-        size(this.texture.getImageWidth(), this.texture.getImageHeight());
+        if (GTCEu.isClientSide()) {
+            this.texture = new ProspectorMapTexture<>(this);
+            background(this.texture);
+            size(this.texture.getImageWidth(), this.texture.getImageHeight());
+        } else {
+            int diameter = (chunkRadius * 2 - 1) * 16 + 1;
+            size(diameter, diameter);
+        }
 
         panelSyncManager.onServerTick(this::scanOres);
     }
@@ -90,7 +99,7 @@ private DynamicSyncHandler createListSyncHandler() {
         return new DynamicSyncHandler()
                 .widgetProvider((syncManager, buf) -> {
                     ProspectingUpdatePacket packet = ProspectingUpdatePacket.read(this.mode, buf);
-                    if (syncManager.isClient()) {
+                    if (syncManager.isClient() && this.texture != null) {
                         this.texture.updateTexture(packet);
                     }
                     this.addOresToList(packet.data);
@@ -178,7 +187,16 @@ public void setSelected(@Nullable String uniqueID, boolean isClient) {
         if (!Objects.equals(this.selected, uniqueID)) {
             this.selected = uniqueID;
 
-            if (isClient) {
+            if (isClient && this.texture != null) {
+                this.texture.loadToImage();
+            }
+        }
+    }
+
+    public void setDarkMode(boolean darkMode) {
+        if (this.darkMode != darkMode) {
+            this.darkMode = darkMode;
+            if (this.texture != null) {
                 this.texture.loadToImage();
             }
         }
@@ -207,6 +225,7 @@ public void setSelected(@Nullable String uniqueID, boolean isClient) {
     }
 
     private @Nullable WaypointItem getClickedVein(double mouseX, double mouseY) {
+        if (this.texture == null) return null;
         int chunkX = (int) (mouseX - getArea().x()) / 16;
         int chunkZ = (int) (mouseY - getArea().y()) / 16;
         int offsetX = (int) (mouseX - getArea().x()) % 16;
diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapTexture.java b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapTexture.java
index fbd012b3a45..2f21a0c4906 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapTexture.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapTexture.java
@@ -47,16 +47,13 @@ public class ProspectorMapTexture extends AbstractTexture implements IDrawabl
     private final int imageHeight;
     public final T[][][] data;
 
-    @Getter
-    private boolean darkMode = true;
-
     public ProspectorMapTexture(ProspectorMapHandler mapHandler) {
         this.mapHandler = mapHandler;
 
         ProspectorMode mode = mapHandler.getMode();
         int diameter = mapHandler.getChunkRadius() * 2 - 1;
 
-        this.imageWidth = this.imageHeight = diameter * 16;
+        this.imageWidth = this.imageHeight = diameter * 16 + 1;
         // noinspection unchecked
         this.data = (T[][][]) Array.newInstance(mode.getItemClass(),
                 diameter * mode.cellSize, diameter * mode.cellSize, 0);
@@ -87,24 +84,28 @@ private NativeImage getImage() {
 
         for (int x = 0; x < this.imageWidth; x++) {
             for (int z = 0; z < this.imageHeight; z++) {
-                T[] items = this.data[x * mode.cellSize / 16][z * mode.cellSize / 16];
+                // the last row/column is the closing grid line, past the end of the data
+                boolean edge = x == this.imageWidth - 1 || z == this.imageHeight - 1;
 
                 boolean drewColor = false;
                 // draw items
-                for (T item : items) {
-                    if (mapHandler.getSelected() == null || mapHandler.getSelected().equals(mode.getUniqueId(item))) {
-                        int color = mode.getItemColor(item);
-                        image.setPixelRGBA(x, z, GradientUtil.argbToAbgr(color) | 0xFF000000);
-
-                        drewColor = true;
-                        break;
+                if (!edge) {
+                    T[] items = this.data[x * mode.cellSize / 16][z * mode.cellSize / 16];
+                    for (T item : items) {
+                        if (mapHandler.getSelected() == null ||
+                                mapHandler.getSelected().equals(mode.getUniqueId(item))) {
+                            int color = mode.getItemColor(item);
+                            image.setPixelRGBA(x, z, GradientUtil.argbToAbgr(color) | 0xFF000000);
+
+                            drewColor = true;
+                            break;
+                        }
                     }
                 }
                 if (!drewColor) {
                     // draw background color
-                    image.setPixelRGBA(x, z, (darkMode ? 0xFF666666 : 0xFFFFFFFF));
+                    image.setPixelRGBA(x, z, (mapHandler.isDarkMode() ? 0xFF666666 : 0xFFFFFFFF));
                 }
-                // draw grid
                 if (x % 16 == 0 || z % 16 == 0) {
                     image.blendPixel(x, z, 0xFF000000);
                 }
@@ -169,11 +170,4 @@ public void draw(GuiContext context, int x, int y, int width, int height, Widget
 
     @Override
     public void load(ResourceManager resourceManager) throws IOException {}
-
-    public void setDarkMode(boolean darkMode) {
-        if (this.darkMode != darkMode) {
-            this.darkMode = darkMode;
-            loadToImage();
-        }
-    }
 }

From 746c22080fb4a03b9db4fb5316f6baf301475100 Mon Sep 17 00:00:00 2001
From: Gustavo <77560533+gustovafing@users.noreply.github.com>
Date: Tue, 14 Jul 2026 12:35:03 +1000
Subject: [PATCH 12/61] Fix ae2 stocking bus (#5102)

---
 .../gtceu/common/cover/detector/MaintenanceDetectorCover.java | 2 +-
 .../integration/ae2/machine/MEStockingBusPartMachine.java     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
index 0a029830b29..c10faa71967 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
@@ -28,7 +28,7 @@ protected void update() {
             return;
         }
 
-        MaintenanceHatchPartMachine maintenance = (MaintenanceHatchPartMachine) coverHolder;
+        MaintenanceHatchPartMachine maintenance = (MaintenanceHatchPartMachine) coverHolder.getHolder();
 
         int signal = getRedstoneSignalOutput();
         boolean shouldSignal = isInverted() != maintenance.hasMaintenanceProblems();
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java
index 02d5395a278..54ac3c9a4f1 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java
@@ -309,8 +309,8 @@ public ExportOnlyAEStockingItemList(int slots) {
 
         public void setStockingBusPartMachine(@Nullable MEStockingBusPartMachine stockingBusPartMachine) {
             this.stockingBusPartMachine = stockingBusPartMachine;
-            for (var slot : ((ExportOnlyAEStockingItemSlot[]) inventory)) {
-                slot.setStockingBusPartMachine(stockingBusPartMachine);
+            for (var slot : inventory) {
+                ((ExportOnlyAEStockingItemSlot) (slot)).setStockingBusPartMachine(stockingBusPartMachine);
             }
         }
 

From 3c0b108d56b425c1a8dbd77f076b8a0ae4f786df Mon Sep 17 00:00:00 2001
From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com>
Date: Mon, 13 Jul 2026 20:53:36 -0600
Subject: [PATCH 13/61] Fix cover opening on pipes (#5103)

---
 src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java   | 2 +-
 .../java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java    | 3 +++
 .../gtceu/common/cover/detector/MaintenanceDetectorCover.java  | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
index 58975ba08df..8e00946bc3b 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java
@@ -352,7 +352,7 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
         }
 
         Set types = ToolHelper.getToolTypes(itemStack);
-        if ((!types.isEmpty() && ToolHelper.canUse(itemStack))) {
+        if ((!types.isEmpty() && ToolHelper.canUse(itemStack)) || (types.isEmpty() && player.isShiftKeyDown())) {
             var result = pipeBlockEntity.onToolClick(new ExtendedUseOnContext(player, hand, hit));
             if (result.getSecond() == InteractionResult.CONSUME && player instanceof ServerPlayer serverPlayer) {
                 ToolHelper.playToolSound(result.getFirst(), serverPlayer);
diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java
index 2ab8efef8fb..71ba21453d0 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java
@@ -141,6 +141,9 @@ public boolean canConnectRedstone() {
 
     public final Pair<@Nullable GTToolType, InteractionResult> onToolClick(ExtendedUseOnContext context) {
         var toolType = context.getToolType();
+        if (toolType.isEmpty() && context.getPlayer().isShiftKeyDown()) {
+            return Pair.of(null, onScrewdriverClick(context));
+        }
         if (toolType.contains(GTToolType.SCREWDRIVER)) {
             return Pair.of(GTToolType.SCREWDRIVER, onScrewdriverClick(context));
         } else if (toolType.contains(GTToolType.SOFT_MALLET)) {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
index c10faa71967..4cb5fe1af96 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/MaintenanceDetectorCover.java
@@ -19,7 +19,7 @@ public boolean canAttach() {
             return false;
         }
 
-        return super.canAttach() && coverHolder instanceof MaintenanceHatchPartMachine;
+        return super.canAttach() && coverHolder.getHolder() instanceof MaintenanceHatchPartMachine;
     }
 
     @Override

From a5523d48dd3e3ec519d94897d1262232b155c75c Mon Sep 17 00:00:00 2001
From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com>
Date: Tue, 14 Jul 2026 09:44:37 +0100
Subject: [PATCH 14/61] Misc mui fixes (#5095)

---
 docs/content/Modpacks/Changes/v8.0.0.md       |  3 ++-
 .../feature/multiblock/IDistinctPart.java     |  2 ++
 .../machine/mui/MachineUIPanelBuilder.java    |  3 ++-
 .../electric/BatteryBufferMachine.java        | 23 ++++++++++++++-----
 .../multiblock/part/ItemBusPartMachine.java   |  5 ++++
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/docs/content/Modpacks/Changes/v8.0.0.md b/docs/content/Modpacks/Changes/v8.0.0.md
index c41f965edeb..af2a7b18ccb 100644
--- a/docs/content/Modpacks/Changes/v8.0.0.md
+++ b/docs/content/Modpacks/Changes/v8.0.0.md
@@ -143,4 +143,5 @@ As a recipe-matching optimization, input handlers whose `getTotalContentAmount()
 - Refactored Jade provider code. Use the `MachineInfoProvider` class for jade providers for a specific machine type, and `MachineTraitProvider` for providers for a specific machine trait. 
 - `GTUtil.getMoltenFluid(Material)` has been moved to `Material.getHotFluid()`.
 - `ICopyable::copyConfig`'s `CompoundTag` argument should now be mutated by reference instead of a new one returned (and thus, the return type has been changed to `void`).
-- Tiered Chance Boosting has been formally removed from the API (as it was deprecated in v7.0.) `ChancedInput` and `ChancedOutput` kubeJS calls will throw errors if they still had chance boost values as arguments.
\ No newline at end of file
+- Tiered Chance Boosting has been formally removed from the API (as it was deprecated in v7.0.) `ChancedInput` and `ChancedOutput` kubeJS calls will throw errors if they still had chance boost values as arguments.
+- Any custom `IDistinctPart`'s will have to implement `supportsDistinct` if they don't extend `ItemBusPartMachine`.
\ No newline at end of file
diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IDistinctPart.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IDistinctPart.java
index 3b413343203..1f581f47dd3 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IDistinctPart.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IDistinctPart.java
@@ -5,4 +5,6 @@ public interface IDistinctPart {
     boolean isDistinct();
 
     void setDistinct(boolean isDistinct);
+
+    boolean supportsDistinct();
 }
diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/mui/MachineUIPanelBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/machine/mui/MachineUIPanelBuilder.java
index 2504e35d898..6c09f38dbf0 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/machine/mui/MachineUIPanelBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/machine/mui/MachineUIPanelBuilder.java
@@ -83,7 +83,8 @@ public MachineUIPanel build(PanelSyncManager syncManager, UISettings settings) {
                 attachRight.child(GTMuiWidgets.createVoidingButton(voidable));
             }
             if (machine instanceof IDistinctPart distinctPart) {
-                attachRight.child(GTMuiWidgets.createDistinctnessButton(distinctPart));
+                attachRight.childIf(distinctPart.supportsDistinct(),
+                        () -> GTMuiWidgets.createDistinctnessButton(distinctPart));
             }
         }
 
diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java
index 4456e4bdad2..b1d3989be8f 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java
@@ -19,7 +19,7 @@
 import com.gregtechceu.gtceu.common.mui.GTGuiTextures;
 import com.gregtechceu.gtceu.common.mui.GTMuiMachineUtil;
 import com.gregtechceu.gtceu.config.ConfigHolder;
-import com.gregtechceu.gtceu.utils.GTStringUtils;
+import com.gregtechceu.gtceu.utils.FormattingUtil;
 import com.gregtechceu.gtceu.utils.GTUtil;
 
 import net.minecraft.core.Direction;
@@ -30,9 +30,9 @@
 import net.minecraftforge.energy.IEnergyStorage;
 
 import brachy.modularui.api.drawable.IDrawable;
-import brachy.modularui.api.drawable.Text;
 import brachy.modularui.drawable.progress.ProgressDrawable;
 import brachy.modularui.factory.PosGuiData;
+import brachy.modularui.screen.RichTooltip;
 import brachy.modularui.screen.UISettings;
 import brachy.modularui.value.sync.DoubleSyncValue;
 import brachy.modularui.value.sync.PanelSyncManager;
@@ -152,10 +152,8 @@ public void buildMainUI(ParentWidget mainWidget, PosGuiData guiData, PanelSyn
                 .value(energyPercentage)
                 .marginLeft(5)
                 .size(18, 60)
-                .addTooltipLine(Text.dynamic(() -> Component.literal(
-                        "%s/%s EU".formatted(
-                                GTStringUtils.formatInt(energyContainer.getEnergyStored()),
-                                GTStringUtils.formatInt(energyContainer.getEnergyCapacity()))))))
+                .tooltipDynamic(this::getRichTooltip))
+                .tooltipAutoUpdate(true)
                 .child(GTMuiMachineUtil.createSlotGroupFromInventory(
                         batteryInventory, "batteries",
                         inventorySize, 'B',
@@ -167,6 +165,19 @@ public void buildMainUI(ParentWidget mainWidget, PosGuiData guiData, PanelSyn
         mainWidget.child(flow);
     }
 
+    private void getRichTooltip(RichTooltip r) {
+        if (GTUtil.isShiftDown()) {
+            r.addLine(Component.literal(
+                    "%s/%s EU".formatted(
+                            energyContainer.getEnergyStored(), energyContainer.getEnergyCapacity())));
+        } else {
+            r.addLine(Component.literal(
+                    "%s/%s EU".formatted(
+                            FormattingUtil.formatNumberReadable(energyContainer.getEnergyStored()),
+                            FormattingUtil.formatNumberReadable(energyContainer.getEnergyCapacity()))));
+        }
+    }
+
     private double getEnergyPercentage() {
         return (double) this.energyContainer.getEnergyStored() / this.energyContainer.getEnergyCapacity();
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
index 887c166b923..24791fdb237 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java
@@ -136,6 +136,11 @@ public void setDistinct(boolean distinct) {
         getHandlerList().setDistinctAndNotify(isDistinct);
     }
 
+    @Override
+    public boolean supportsDistinct() {
+        return !io.support(IO.OUT);
+    }
+
     @Override
     public int tintColor(int index) {
         if (index == 9) return getRealColor();

From 9f01c3dc4e6f9c0d8150f903efc5ed3aa829e7d0 Mon Sep 17 00:00:00 2001
From: screret <68943070+screret@users.noreply.github.com>
Date: Tue, 14 Jul 2026 11:47:19 +0300
Subject: [PATCH 15/61] Sussy! (fix the 'sus record' music disc) (#5097)

---
 src/generated/resources/assets/gtceu/lang/en_ud.json         | 2 +-
 src/generated/resources/assets/gtceu/lang/en_us.json         | 2 +-
 .../resources/data/minecraft/tags/items/music_discs.json     | 5 +++++
 src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java | 2 ++
 src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java  | 2 +-
 5 files changed, 10 insertions(+), 3 deletions(-)
 create mode 100644 src/generated/resources/data/minecraft/tags/items/music_discs.json

diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json
index 106d0cb0343..6204955dfb1 100644
--- a/src/generated/resources/assets/gtceu/lang/en_ud.json
+++ b/src/generated/resources/assets/gtceu/lang/en_ud.json
@@ -4838,7 +4838,7 @@
   "item.gtceu.storage_cover": "ɹǝʌoƆ ǝbɐɹoʇS",
   "item.gtceu.sugar_gem": "ǝqnƆ ɹɐbnS",
   "item.gtceu.sus_record": "ɔsıᗡ ɔısnW",
-  "item.gtceu.sus_record.desc": "¡ʎssnsㄥ§",
+  "item.gtceu.sus_record.desc": "¡ʎssns",
   "item.gtceu.sword_extruder_mold.tooltip": "spɹoʍS buıʞɐɯ ɹoɟ ǝdɐɥS ɹǝpnɹʇxƎㄥ§",
   "item.gtceu.tag_filter.tooltip.0": "˙ㄥ§ɹǝʌoƆɟ§ sɐ ㄥ§bɐ⟘ɟ§ ɥʇıʍ O/I ㄥ§ɯǝʇIɟ§ sɹǝʇןıℲㄥ§",
   "item.gtceu.tag_filter.tooltip.1": "˙ǝpɐɹbdn ㄥ§ɯɹⱯ ɔıʇoqoᴚɟ§ puɐ ㄥ§ǝןnpoW ɹoʎǝʌuoƆɟ§ ɐ sɐ pǝsn ǝq uɐƆ",
diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json
index 6df52a555fa..9330a7dc808 100644
--- a/src/generated/resources/assets/gtceu/lang/en_us.json
+++ b/src/generated/resources/assets/gtceu/lang/en_us.json
@@ -4838,7 +4838,7 @@
   "item.gtceu.storage_cover": "Storage Cover",
   "item.gtceu.sugar_gem": "Sugar Cube",
   "item.gtceu.sus_record": "Music Disc",
-  "item.gtceu.sus_record.desc": "§7sussy!",
+  "item.gtceu.sus_record.desc": "sussy!",
   "item.gtceu.sword_extruder_mold.tooltip": "§7Extruder Shape for making Swords",
   "item.gtceu.tag_filter.tooltip.0": "§7Filters §fItem§7 I/O with §fTag§7 as §fCover§7.",
   "item.gtceu.tag_filter.tooltip.1": "Can be used as a §fConveyor Module§7 and §fRobotic Arm§7 upgrade.",
diff --git a/src/generated/resources/data/minecraft/tags/items/music_discs.json b/src/generated/resources/data/minecraft/tags/items/music_discs.json
new file mode 100644
index 00000000000..1ad655bc813
--- /dev/null
+++ b/src/generated/resources/data/minecraft/tags/items/music_discs.json
@@ -0,0 +1,5 @@
+{
+  "values": [
+    "gtceu:sus_record"
+  ]
+}
\ No newline at end of file
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 fafef5889c9..43ef2500e26 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java
@@ -2516,6 +2516,8 @@ public static ItemEntry createFluidCell(Material mat, int capacit
     public static ItemEntry SUS_RECORD = REGISTRATE
             .item("sus_record", p -> new RecordItem(15, GTSoundEntries.SUS_RECORD::getMainEvent, p, 820))
             .lang("Music Disc")
+            .properties(p -> p.stacksTo(1).rarity(Rarity.RARE))
+            .tag(ItemTags.MUSIC_DISCS)
             .register();
     public static ItemEntry NAN_CERTIFICATE = REGISTRATE.item("nan_certificate", Item::new)
             .lang("Certificate of Not Being a Noob Anymore").properties(p -> p.rarity(Rarity.EPIC))
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..3a1969c4ca0 100644
--- a/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java
+++ b/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java
@@ -352,6 +352,6 @@ private static void initItemTooltips(RegistrateLangProvider provider) {
         provider.add("item.gtceu.terminal.tooltip",
                 "Shift + R-Click on a controller to automatically build a multiblock with items from your inventory");
 
-        provider.add("item.gtceu.sus_record.desc", "§7sussy!");
+        provider.add("item.gtceu.sus_record.desc", "sussy!");
     }
 }

From d5db9a64000b1c107a917670055acc3dfd038ec6 Mon Sep 17 00:00:00 2001
From: Jurre Groenendijk 
Date: Tue, 14 Jul 2026 08:57:09 +0000
Subject: [PATCH 16/61] prospector UI fixes (#5099)

---
 .../behavior/ProspectorScannerBehavior.java   |  5 +-
 .../prospector/ProspectorMapHandler.java      | 98 +++++++++++++++----
 2 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
index a9a4d3c9ff3..b9c010a63ed 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ProspectorScannerBehavior.java
@@ -119,7 +119,7 @@ public ModularPanel buildUI(PlayerInventoryGuiData guiData, PanelSyncManag
                 panelSyncManager, guiData.getPlayer());
 
         int mapSize = (this.radius * 2 - 1) * 16 + 1;
-        return ModularPanel.defaultPanel("prospector_scanner", mapSize + 156, mapSize + 24)
+        return ModularPanel.defaultPanel("prospector_scanner", mapSize + 152, 200)
                 .margin(4)
                 .child(new ToggleButton()
                         .size(18)
@@ -127,7 +127,8 @@ public ModularPanel buildUI(PlayerInventoryGuiData guiData, PanelSyncManag
                         .decoration()
                         .stateBackground(GTGuiTextures.PROGRESS_BAR_SOLAR_STEEL)
                         .value(new BoolValue.Dynamic(mapHandler::isDarkMode,
-                                mapHandler::setDarkMode)))
+                                mapHandler::setDarkMode))
+                        .excludeAreaInRecipeViewer())
                 .child(Flow.row()
                         .childPadding(10)
                         .margin(6)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
index 1b41228962d..033606a4b74 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/prospector/ProspectorMapHandler.java
@@ -33,6 +33,7 @@
 import brachy.modularui.widgets.*;
 import brachy.modularui.widgets.layout.Flow;
 import com.google.common.base.Strings;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import lombok.Getter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -65,8 +66,10 @@ public class ProspectorMapHandler extends Widget> imp
     // runtime
     @Getter
     private @Nullable String selected = null;
-    private final Set items = new HashSet<>();
+    // keyed by uniqueId so entries are deduplicated across chunks
+    private final Map items = new Object2ObjectOpenHashMap<>();
     private int chunkIndex = 0;
+    private String lastSearch = "";
 
     public ProspectorMapHandler(ProspectorMode mode, int chunkRadius, int scanInterval,
                                 StringValue searchValue, DynamicSyncedWidget searchListWidget,
@@ -87,6 +90,16 @@ public ProspectorMapHandler(ProspectorMode mode, int chunkRadius, int scanInt
             this.texture = new ProspectorMapTexture<>(this);
             background(this.texture);
             size(this.texture.getImageWidth(), this.texture.getImageHeight());
+
+            tooltipAutoUpdate(true);
+            tooltipDynamic(tooltip -> {
+                tooltip.clearText();
+                List cells = getHoveredChunkCells();
+                if (cells.isEmpty()) return;
+                List lines = new ArrayList<>();
+                this.mode.appendTooltips(cells, lines, null);
+                lines.forEach(tooltip::addLine);
+            });
         } else {
             int diameter = (chunkRadius * 2 - 1) * 16 + 1;
             size(diameter, diameter);
@@ -108,7 +121,14 @@ private DynamicSyncHandler createListSyncHandler() {
                             .collapseDisabledChildren()
                             .expanded()
                             .sizeRel(1f)
-                            .children(this.items, item -> {
+                            .onUpdateListener(list -> {
+                                String current = searchValue.getStringValue();
+                                if (!Objects.equals(current, this.lastSearch)) {
+                                    this.lastSearch = current;
+                                    list.getScrollData().scrollTo(list.getScrollArea(), 0);
+                                }
+                            })
+                            .children(this.items.values(), item -> {
                                 String uniqueId = mode.getUniqueId(item);
                                 Component description = mode.getDescription(item);
 
@@ -126,7 +146,8 @@ private DynamicSyncHandler createListSyncHandler() {
                                             if (Strings.isNullOrEmpty(searched)) {
                                                 return true;
                                             } else {
-                                                return description.getString().toLowerCase().contains(searched);
+                                                return description.getString().toLowerCase()
+                                                        .contains(searched.toLowerCase());
                                             }
                                         })
                                         .child(Flow.row()
@@ -178,7 +199,11 @@ private void scanOres() {
     private void addOresToList(T[][][] data) {
         for (int x = 0; x < mode.cellSize; x++) {
             for (int z = 0; z < mode.cellSize; z++) {
-                Collections.addAll(this.items, data[x][z]);
+                for (T item : data[x][z]) {
+                    if (item != null) {
+                        this.items.putIfAbsent(mode.getUniqueId(item), item);
+                    }
+                }
             }
         }
     }
@@ -219,17 +244,55 @@ public void setDarkMode(boolean darkMode) {
                 Component.translatable("behavior.prospector.added_waypoint",
                         clickedItem.name.copy().withStyle(style -> style.withColor(clickedItem.color))),
                 false);
+        this.getContext().getScreen().getMainPanel().closeIfOpen();
 
         Interactable.playButtonClickSound();
         return Result.SUCCESS;
     }
 
+    /**
+     * @return every non-empty data cell of the chunk currently under the cursor, or an empty list if the
+     *         cursor is off the map.
+     */
+    private List getHoveredChunkCells() {
+        if (this.texture == null) return List.of();
+        int relX = getContext().getMouseX();
+        int relZ = getContext().getMouseY();
+
+        int mapPixels = (this.chunkRadius * 2 - 1) * 16;
+        if (relX < 0 || relZ < 0 || relX >= mapPixels || relZ >= mapPixels) {
+            return List.of();
+        }
+
+        int chunkX = relX / 16;
+        int chunkZ = relZ / 16;
+        int cellSize = this.mode.cellSize;
+        List cells = new ArrayList<>();
+        for (int i = 0; i < cellSize; i++) {
+            for (int j = 0; j < cellSize; j++) {
+                T[] cell = this.texture.data[chunkX * cellSize + i][chunkZ * cellSize + j];
+                if (cell != null && cell.length > 0) {
+                    cells.add(cell);
+                }
+            }
+        }
+        return cells;
+    }
+
     private @Nullable WaypointItem getClickedVein(double mouseX, double mouseY) {
         if (this.texture == null) return null;
-        int chunkX = (int) (mouseX - getArea().x()) / 16;
-        int chunkZ = (int) (mouseY - getArea().y()) / 16;
-        int offsetX = (int) (mouseX - getArea().x()) % 16;
-        int offsetZ = (int) (mouseY - getArea().y()) % 16;
+        int relX = (int) mouseX;
+        int relZ = (int) mouseY;
+
+        int mapPixels = (this.chunkRadius * 2 - 1) * 16;
+        if (relX < 0 || relZ < 0 || relX >= mapPixels || relZ >= mapPixels) {
+            return null;
+        }
+
+        int chunkX = relX / 16;
+        int chunkZ = relZ / 16;
+        int offsetX = relX % 16;
+        int offsetZ = relZ % 16;
         int xDiff = chunkX - (this.chunkRadius - 1);
         int zDiff = chunkZ - (this.chunkRadius - 1);
 
@@ -237,21 +300,14 @@ public void setDarkMode(boolean darkMode) {
         int z = SectionPos.sectionToBlockCoord(player.chunkPosition().z + zDiff) + offsetZ;
         int y = player.level().getHeight(Heightmap.Types.WORLD_SURFACE, x, z);
 
-        if (chunkX < 0 || chunkZ < 0 || chunkX >= this.chunkRadius * 2 - 1 || chunkZ >= this.chunkRadius * 2 - 1) {
-            return null;
-        }
-
         BlockPos pos = new BlockPos(x, y, z);
         // If the ores are filtered use its name
-        if (this.getSelected() != null) {
-            for (T item : this.items) {
-                String uniqueId = mode.getUniqueId(item);
-                if (!this.getSelected().equals(uniqueId)) continue;
-
-                Component name = mode.getDescription(item);
-                int color = mode.getItemColor(item);
-                return new WaypointItem(pos, uniqueId, name, color);
-            }
+        T item = this.items.get(this.getSelected());
+        if (item != null) {
+            Component name = mode.getDescription(item);
+            int color = mode.getItemColor(item);
+            String uniqueId = mode.getUniqueId(item);
+            return new WaypointItem(pos, uniqueId, name, color);
         }
 
         // If the cursor is over an ore use its name

From c00ad844bd803a15963d3b646f245146aa14f8b9 Mon Sep 17 00:00:00 2001
From: Gustavo <77560533+gustovafing@users.noreply.github.com>
Date: Tue, 14 Jul 2026 19:41:28 +1000
Subject: [PATCH 17/61] remove gtregistrate default when creating machines
 (#5107)

---
 .../multiblock/predicates/BasePredicate.java  |   4 +-
 .../api/registry/registrate/GTRegistrate.java |   2 +-
 .../gtceu/common/data/GTMachines.java         | 184 ++++++++++--------
 .../common/data/machines/GCYMMachines.java    |   2 +-
 .../common/data/machines/GTMachineUtils.java  | 169 +---------------
 .../common/data/machines/GTMultiMachines.java |  44 +++--
 .../gtceu/common/registry/GTRegistration.java |   7 +
 .../machine/KJSSteamMachineBuilder.java       |  22 +--
 .../machine/KJSTieredMachineBuilder.java      |   4 +-
 .../machine/KJSTieredMultiblockBuilder.java   |   9 +-
 .../machine/KJSWrappingMultiblockBuilder.java |   8 +-
 11 files changed, 165 insertions(+), 290 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java
index 26c7995acae..a39b9623795 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java
@@ -62,10 +62,10 @@ public BasePredicate() {
      *                       Terminal Auto-Builder},
      *                       {@link PatternPreviewRenderer#draw(PoseStack, MultiBufferSource.BufferSource, Camera, RenderLevelStageEvent.Stage, float)
      *                       In-world Preview} or
-     *                       {@link MultiblockPreviewWidget#MultiblockPreviewWidget(MultiblockMachineDefinition, MultiblockSchemaInfo)
+     *                       {@link MultiblockPreviewWidget#MultiblockPreviewWidget(MultiblockMachineDefinition, MultiblockSchemaInfo, int, int)
      *                       XEI Preview}
      */
-    public BasePredicate(Function errorPredicate,
+    public BasePredicate(Function errorPredicate,
                          @Nullable List candidates) {
         this("Unknown", errorPredicate, candidates);
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java
index cb897b38d2d..1374b066720 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java
@@ -253,7 +253,7 @@ public  GTBlockBuilder block(P parent, String name,
         return this.currentTab;
     }
 
-    public void creativeModeTab(Supplier> currentTab) {
+    public void creativeModeTab(Supplier<@Nullable RegistryEntry> currentTab) {
         this.currentTab = currentTab.get();
     }
 
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java
index 0ab7644be9e..2b79384723a 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java
@@ -66,6 +66,7 @@
 import static com.gregtechceu.gtceu.common.data.models.GTMachineModels.*;
 import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE;
 
+@SuppressWarnings("unused")
 public class GTMachines {
 
     static {
@@ -77,6 +78,7 @@ public class GTMachines {
     // ****** Steam Machine ******//
     //////////////////////////////////////
     public static final Pair STEAM_SOLID_BOILER = registerSteamMachines(
+            REGISTRATE,
             "steam_solid_boiler",
             SteamSolidBoilerMachine::new,
             (pressure, builder) -> builder.rotationState(RotationState.ALL)
@@ -91,6 +93,7 @@ public class GTMachines {
                     .register());
 
     public static final Pair STEAM_LIQUID_BOILER = registerSteamMachines(
+            REGISTRATE,
             "steam_liquid_boiler",
             SteamLiquidBoilerMachine::new,
             (pressure, builder) -> builder.rotationState(RotationState.ALL)
@@ -105,6 +108,7 @@ public class GTMachines {
                     .register());
 
     public static final Pair STEAM_SOLAR_BOILER = registerSteamMachines(
+            REGISTRATE,
             "steam_solar_boiler",
             SteamSolarBoiler::new,
             (pressure, builder) -> builder.rotationState(RotationState.NON_Y_AXIS)
@@ -119,9 +123,10 @@ public class GTMachines {
                     .register());
 
     public static final Pair STEAM_EXTRACTOR = registerSimpleSteamMachines(
+            REGISTRATE,
             "extractor", GTRecipeTypes.EXTRACTOR_RECIPES);
 
-    public static final Pair STEAM_MACERATOR = registerSteamMachines(
+    public static final Pair STEAM_MACERATOR = registerSteamMachines(REGISTRATE,
             "steam_macerator", SimpleSteamMachine::new, (pressure, builder) -> builder
                     .rotationState(RotationState.NON_Y_AXIS)
                     .recipeType(GTRecipeTypes.MACERATOR_RECIPES)
@@ -134,16 +139,21 @@ public class GTMachines {
                     .register());
 
     public static final Pair STEAM_COMPRESSOR = registerSimpleSteamMachines(
+            REGISTRATE,
             "compressor", GTRecipeTypes.COMPRESSOR_RECIPES);
     public static final Pair STEAM_HAMMER = registerSimpleSteamMachines(
+            REGISTRATE,
             "forge_hammer", GTRecipeTypes.FORGE_HAMMER_RECIPES);
     public static final Pair STEAM_FURNACE = registerSimpleSteamMachines(
+            REGISTRATE,
             "furnace", GTRecipeTypes.FURNACE_RECIPES);
     public static final Pair STEAM_ALLOY_SMELTER = registerSimpleSteamMachines(
+            REGISTRATE,
             "alloy_smelter", GTRecipeTypes.ALLOY_SMELTER_RECIPES);
     public static final Pair STEAM_ROCK_CRUSHER = registerSimpleSteamMachines(
+            REGISTRATE,
             "rock_crusher", GTRecipeTypes.ROCK_BREAKER_RECIPES);
-    public static final Pair STEAM_MINER = registerSteamMachines(
+    public static final Pair STEAM_MINER = registerSteamMachines(REGISTRATE,
             "steam_miner",
             (holder, isHP) -> isHP ? new SteamMinerMachine(holder, true, 240, 6, 0, 32) :
                     new SteamMinerMachine(holder, false, 320, 4, 0, 16),
@@ -168,7 +178,7 @@ public class GTMachines {
     //////////////////////////////////////
     // *** SimpleTieredMachine ***//
     //////////////////////////////////////
-    public static final MachineDefinition[] HULL = GTMachineUtils.registerTieredMachines("machine_hull",
+    public static final MachineDefinition[] HULL = GTMachineUtils.registerTieredMachines(REGISTRATE, "machine_hull",
             HullMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.ALL)
@@ -185,7 +195,7 @@ public class GTMachines {
     public static final MachineDefinition[] ALLOY_SMELTER = new SimpleMachineBuilder(REGISTRATE, "alloy_smelter",
             GTRecipeTypes.ALLOY_SMELTER_RECIPES).register();
 
-    public static final MachineDefinition[] ARC_FURNACE = registerTieredMachines("arc_furnace",
+    public static final MachineDefinition[] ARC_FURNACE = registerTieredMachines(REGISTRATE, "arc_furnace",
             SimpleTieredMachine::new, (tier, builder) -> builder
                     .langValue("%s Arc Furnace %s".formatted(VLVH[tier], VLVT[tier]))
                     .rotationState(RotationState.NON_Y_AXIS)
@@ -296,7 +306,7 @@ public class GTMachines {
             .tankScalingFunction(hvCappedTankSizeFunction)
             .hasPollutionDebuff(true)
             .register();
-    public static final MachineDefinition[] MACERATOR = registerTieredMachines("macerator",
+    public static final MachineDefinition[] MACERATOR = registerTieredMachines(REGISTRATE, "macerator",
             SimpleTieredMachine::new, (tier, builder) -> builder
                     .langValue("%s Macerator %s".formatted(VLVH[tier], VLVT[tier]))
                     .rotationState(RotationState.NON_Y_AXIS)
@@ -319,7 +329,7 @@ public class GTMachines {
             .hasPollutionDebuff(true)
             .register();
 
-    public static final MachineDefinition[] ROCK_CRUSHER = registerTieredMachines("rock_crusher",
+    public static final MachineDefinition[] ROCK_CRUSHER = registerTieredMachines(REGISTRATE, "rock_crusher",
             GTMachineInstanceFactories.ROCK_CRUSHER, (tier, builder) -> builder
                     .langValue("%s Rock Crusher %s".formatted(VLVH[tier], VLVT[tier]))
                     .ui(GTSingleblockMachinePanels.GENERAL_MACHINE)
@@ -332,7 +342,7 @@ public class GTMachines {
                     .tooltips(explosion())
                     .register(),
             ELECTRIC_TIERS);
-    public static final MachineDefinition[] AIR_SCRUBBER = registerTieredMachines("air_scrubber",
+    public static final MachineDefinition[] AIR_SCRUBBER = registerTieredMachines(REGISTRATE, "air_scrubber",
             AirScrubberMachine::new, (tier, builder) -> builder
                     .langValue("%s Air Scrubber %s".formatted(VLVH[tier], VLVT[tier]))
                     .ui(GTSingleblockMachinePanels.GENERAL_MACHINE)
@@ -349,28 +359,30 @@ public class GTMachines {
     //////////////////////////////////////
     // **** Simple Generator ****//
     //////////////////////////////////////
-    public static final MachineDefinition[] COMBUSTION = registerSimpleGenerator("combustion",
+    public static final MachineDefinition[] COMBUSTION = registerSimpleGenerator(REGISTRATE, "combustion",
             GTRecipeTypes.COMBUSTION_GENERATOR_FUELS, genericGeneratorTankSizeFunction, 0.1f, GTValues.LV, GTValues.MV,
             GTValues.HV);
-    public static final MachineDefinition[] STEAM_TURBINE = registerSimpleGenerator("steam_turbine",
+    public static final MachineDefinition[] STEAM_TURBINE = registerSimpleGenerator(REGISTRATE, "steam_turbine",
             GTRecipeTypes.STEAM_TURBINE_FUELS, steamGeneratorTankSizeFunction, 0.0f, GTValues.LV, GTValues.MV,
             GTValues.HV);
-    public static final MachineDefinition[] GAS_TURBINE = registerSimpleGenerator("gas_turbine",
+    public static final MachineDefinition[] GAS_TURBINE = registerSimpleGenerator(REGISTRATE, "gas_turbine",
             GTRecipeTypes.GAS_TURBINE_FUELS, genericGeneratorTankSizeFunction, 0.1f, GTValues.LV, GTValues.MV,
             GTValues.HV);
 
     //////////////////////////////////////
     // ******** Electric ********//
     //////////////////////////////////////
-    public static final MachineDefinition[] TRANSFORMER = registerTransformerMachines("", 1);
-    public static final MachineDefinition[] HI_AMP_TRANSFORMER_2A = registerTransformerMachines("Hi-Amp (2x)", 2);
-    public static final MachineDefinition[] HI_AMP_TRANSFORMER_4A = registerTransformerMachines("Hi-Amp (4x)", 4);
-    public static final MachineDefinition[] POWER_TRANSFORMER = registerTransformerMachines("Power", 16);
-
-    public static final MachineDefinition[] ENERGY_CONVERTER_1A = registerConverter(1);
-    public static final MachineDefinition[] ENERGY_CONVERTER_4A = registerConverter(4);
-    public static final MachineDefinition[] ENERGY_CONVERTER_8A = registerConverter(8);
-    public static final MachineDefinition[] ENERGY_CONVERTER_16A = registerConverter(16);
+    public static final MachineDefinition[] TRANSFORMER = registerTransformerMachines(REGISTRATE, "", 1);
+    public static final MachineDefinition[] HI_AMP_TRANSFORMER_2A = registerTransformerMachines(REGISTRATE,
+            "Hi-Amp (2x)", 2);
+    public static final MachineDefinition[] HI_AMP_TRANSFORMER_4A = registerTransformerMachines(REGISTRATE,
+            "Hi-Amp (4x)", 4);
+    public static final MachineDefinition[] POWER_TRANSFORMER = registerTransformerMachines(REGISTRATE, "Power", 16);
+
+    public static final MachineDefinition[] ENERGY_CONVERTER_1A = registerConverter(REGISTRATE, 1);
+    public static final MachineDefinition[] ENERGY_CONVERTER_4A = registerConverter(REGISTRATE, 4);
+    public static final MachineDefinition[] ENERGY_CONVERTER_8A = registerConverter(REGISTRATE, 8);
+    public static final MachineDefinition[] ENERGY_CONVERTER_16A = registerConverter(REGISTRATE, 16);
 
     public static final MachineDefinition LONG_DIST_ITEM_ENDPOINT = REGISTRATE
             .machine("long_distance_item_pipeline_endpoint", LDItemEndpointMachine::new)
@@ -406,15 +418,15 @@ public class GTMachines {
             })
             .register();
 
-    public static final MachineDefinition[] BATTERY_BUFFER_4 = registerBatteryBuffer(4);
+    public static final MachineDefinition[] BATTERY_BUFFER_4 = registerBatteryBuffer(REGISTRATE, 4);
 
-    public static final MachineDefinition[] BATTERY_BUFFER_8 = registerBatteryBuffer(8);
+    public static final MachineDefinition[] BATTERY_BUFFER_8 = registerBatteryBuffer(REGISTRATE, 8);
 
-    public static final MachineDefinition[] BATTERY_BUFFER_16 = registerBatteryBuffer(16);
+    public static final MachineDefinition[] BATTERY_BUFFER_16 = registerBatteryBuffer(REGISTRATE, 16);
 
-    public static final MachineDefinition[] CHARGER_4 = registerCharger(4);
+    public static final MachineDefinition[] CHARGER_4 = registerCharger(REGISTRATE, 4);
 
-    public static final MachineDefinition[] PUMP = registerTieredMachines("pump", PumpMachine::new,
+    public static final MachineDefinition[] PUMP = registerTieredMachines(REGISTRATE, "pump", PumpMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.ALL)
                     .tieredHullModel(GTCEu.id("block/machine/template/pump_machine"))
@@ -433,7 +445,7 @@ public class GTMachines {
                     .register(),
             LV, MV, HV, EV);
 
-    public static final MachineDefinition[] FISHER = registerTieredMachines("fisher", FisherMachine::new,
+    public static final MachineDefinition[] FISHER = registerTieredMachines(REGISTRATE, "fisher", FisherMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.ALL)
                     // .editableUI(FisherMachine.EDITABLE_UI_CREATOR.apply(GTCEu.id("fisher"), (tier + 1) * (tier + 1)))
@@ -451,7 +463,7 @@ public class GTMachines {
                     .register(),
             LV, MV, HV, EV, IV, LuV);
 
-    public static final MachineDefinition[] BLOCK_BREAKER = registerTieredMachines("block_breaker",
+    public static final MachineDefinition[] BLOCK_BREAKER = registerTieredMachines(REGISTRATE, "block_breaker",
             BlockBreakerMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.NON_Y_AXIS)
@@ -468,7 +480,7 @@ public class GTMachines {
                     .register(),
             LV, MV, HV, EV);
 
-    public static final MachineDefinition[] MINER = registerTieredMachines("miner",
+    public static final MachineDefinition[] MINER = registerTieredMachines(REGISTRATE, "miner",
             (holder, tier) -> new MinerMachine(holder, tier, ConfigHolder.INSTANCE.machines.minerSpeed / (tier * 2),
                     tier * 8, tier),
             (tier, builder) -> builder
@@ -496,7 +508,7 @@ public class GTMachines {
                     .register(),
             LV, MV, HV);
 
-    public static final MachineDefinition[] WORLD_ACCELERATOR = registerTieredMachines("world_accelerator",
+    public static final MachineDefinition[] WORLD_ACCELERATOR = registerTieredMachines(REGISTRATE, "world_accelerator",
             WorldAcceleratorMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.NONE)
@@ -525,7 +537,7 @@ public class GTMachines {
                     .register(),
             LV, MV, HV, EV, IV, LuV, ZPM, UV);
 
-    public static final MachineDefinition[] ITEM_COLLECTOR = registerTieredMachines("item_collector",
+    public static final MachineDefinition[] ITEM_COLLECTOR = registerTieredMachines(REGISTRATE, "item_collector",
             ItemCollectorMachine::new,
             (tier, builder) -> builder
                     .rotationState(RotationState.NONE)
@@ -550,7 +562,7 @@ public class GTMachines {
     // ********* Storage *********//
     //////////////////////////////////////
 
-    public static final MachineDefinition[] BUFFER = registerTieredMachines("buffer",
+    public static final MachineDefinition[] BUFFER = registerTieredMachines(REGISTRATE, "buffer",
             BufferMachine::new,
             (tier, builder) -> builder
                     .langValue("%s Buffer %s".formatted(VLVH[tier], VLVT[tier]))
@@ -629,43 +641,51 @@ public class GTMachines {
             .hasBER(true)
             .register();
 
-    public static final MachineDefinition[] SUPER_CHEST = registerQuantumChests("super_chest", LOW_TIERS);
-    public static final MachineDefinition[] QUANTUM_CHEST = registerQuantumChests("quantum_chest", HIGH_TIERS);
+    public static final MachineDefinition[] SUPER_CHEST = registerQuantumChests(REGISTRATE, "super_chest", LOW_TIERS);
+    public static final MachineDefinition[] QUANTUM_CHEST = registerQuantumChests(REGISTRATE, "quantum_chest",
+            HIGH_TIERS);
 
-    public static final MachineDefinition[] SUPER_TANK = registerQuantumTanks("super_tank", LOW_TIERS);
-    public static final MachineDefinition[] QUANTUM_TANK = registerQuantumTanks("quantum_tank", HIGH_TIERS);
+    public static final MachineDefinition[] SUPER_TANK = registerQuantumTanks(REGISTRATE, "super_tank", LOW_TIERS);
+    public static final MachineDefinition[] QUANTUM_TANK = registerQuantumTanks(REGISTRATE, "quantum_tank", HIGH_TIERS);
 
-    public static MachineDefinition WOODEN_CRATE = registerCrate(GTMaterials.Wood, 27, 9, "Wooden Crate");
-    public static MachineDefinition BRONZE_CRATE = registerCrate(GTMaterials.Bronze, 54, 9, "Bronze Crate");
-    public static MachineDefinition STEEL_CRATE = registerCrate(GTMaterials.Steel, 72, 9, "Steel Crate");
-    public static MachineDefinition ALUMINIUM_CRATE = registerCrate(GTMaterials.Aluminium, 90, 10, "Aluminium Crate");
-    public static MachineDefinition STAINLESS_STEEL_CRATE = registerCrate(GTMaterials.StainlessSteel, 108, 12,
+    public static MachineDefinition WOODEN_CRATE = registerCrate(REGISTRATE, GTMaterials.Wood, 27, 9, "Wooden Crate");
+    public static MachineDefinition BRONZE_CRATE = registerCrate(REGISTRATE, GTMaterials.Bronze, 54, 9, "Bronze Crate");
+    public static MachineDefinition STEEL_CRATE = registerCrate(REGISTRATE, GTMaterials.Steel, 72, 9, "Steel Crate");
+    public static MachineDefinition ALUMINIUM_CRATE = registerCrate(REGISTRATE, GTMaterials.Aluminium, 90, 10,
+            "Aluminium Crate");
+    public static MachineDefinition STAINLESS_STEEL_CRATE = registerCrate(REGISTRATE, GTMaterials.StainlessSteel, 108,
+            12,
             "Stainless Steel Crate");
-    public static MachineDefinition TITANIUM_CRATE = registerCrate(GTMaterials.Titanium, 126, 14, "Titanium Crate");
-    public static MachineDefinition TUNGSTENSTEEL_CRATE = registerCrate(GTMaterials.TungstenSteel, 144, 16,
+    public static MachineDefinition TITANIUM_CRATE = registerCrate(REGISTRATE, GTMaterials.Titanium, 126, 14,
+            "Titanium Crate");
+    public static MachineDefinition TUNGSTENSTEEL_CRATE = registerCrate(REGISTRATE, GTMaterials.TungstenSteel, 144, 16,
             "Tungstensteel Crate");
 
-    public static MachineDefinition WOODEN_DRUM = registerDrum(GTMaterials.Wood, (16 * FluidType.BUCKET_VOLUME),
+    public static MachineDefinition WOODEN_DRUM = registerDrum(REGISTRATE, GTMaterials.Wood,
+            (16 * FluidType.BUCKET_VOLUME),
             "Wooden Barrel");
-    public static MachineDefinition BRONZE_DRUM = registerDrum(GTMaterials.Bronze, (32 * FluidType.BUCKET_VOLUME),
+    public static MachineDefinition BRONZE_DRUM = registerDrum(REGISTRATE, GTMaterials.Bronze,
+            (32 * FluidType.BUCKET_VOLUME),
             "Bronze Drum");
-    public static MachineDefinition STEEL_DRUM = registerDrum(GTMaterials.Steel, (64 * FluidType.BUCKET_VOLUME),
+    public static MachineDefinition STEEL_DRUM = registerDrum(REGISTRATE, GTMaterials.Steel,
+            (64 * FluidType.BUCKET_VOLUME),
             "Steel Drum");
-    public static MachineDefinition ALUMINIUM_DRUM = registerDrum(GTMaterials.Aluminium,
+    public static MachineDefinition ALUMINIUM_DRUM = registerDrum(REGISTRATE, GTMaterials.Aluminium,
             (128 * FluidType.BUCKET_VOLUME), "Aluminium Drum");
-    public static MachineDefinition STAINLESS_STEEL_DRUM = registerDrum(GTMaterials.StainlessSteel,
+    public static MachineDefinition STAINLESS_STEEL_DRUM = registerDrum(REGISTRATE, GTMaterials.StainlessSteel,
             (256 * FluidType.BUCKET_VOLUME), "Stainless Steel Drum");
-    public static MachineDefinition GOLD_DRUM = registerDrum(GTMaterials.Gold, (32 * FluidType.BUCKET_VOLUME),
+    public static MachineDefinition GOLD_DRUM = registerDrum(REGISTRATE, GTMaterials.Gold,
+            (32 * FluidType.BUCKET_VOLUME),
             "Gold Drum");
-    public static MachineDefinition TITANIUM_DRUM = registerDrum(GTMaterials.Titanium,
+    public static MachineDefinition TITANIUM_DRUM = registerDrum(REGISTRATE, GTMaterials.Titanium,
             (512 * FluidType.BUCKET_VOLUME), "Titanium Drum");
-    public static MachineDefinition TUNGSTENSTEEL_DRUM = registerDrum(GTMaterials.TungstenSteel,
+    public static MachineDefinition TUNGSTENSTEEL_DRUM = registerDrum(REGISTRATE, GTMaterials.TungstenSteel,
             (1024 * FluidType.BUCKET_VOLUME), "Tungstensteel Drum");
 
     //////////////////////////////////////
     // ********** Part **********//
     //////////////////////////////////////
-    public static final MachineDefinition[] ITEM_IMPORT_BUS = registerTieredMachines("input_bus",
+    public static final MachineDefinition[] ITEM_IMPORT_BUS = registerTieredMachines(REGISTRATE, "input_bus",
             (holder, tier) -> new ItemBusPartMachine(holder, tier, IN),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " Input Bus")
@@ -680,7 +700,7 @@ public class GTMachines {
                     .register(),
             ALL_TIERS);
 
-    public static final MachineDefinition[] ITEM_EXPORT_BUS = registerTieredMachines("output_bus",
+    public static final MachineDefinition[] ITEM_EXPORT_BUS = registerTieredMachines(REGISTRATE, "output_bus",
             (holder, tier) -> new ItemBusPartMachine(holder, tier, OUT),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " Output Bus")
@@ -695,43 +715,44 @@ public class GTMachines {
                     .register(),
             ALL_TIERS);
 
-    public final static MachineDefinition[] FLUID_IMPORT_HATCH = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_IMPORT_HATCH = registerFluidHatches(REGISTRATE,
             "input_hatch", "Input Hatch", "fluid_hatch.import",
             IN, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_1X, 1,
             ALL_TIERS, PartAbility.IMPORT_FLUIDS,
             PartAbility.IMPORT_FLUIDS_1X);
 
-    public final static MachineDefinition[] FLUID_IMPORT_HATCH_4X = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_IMPORT_HATCH_4X = registerFluidHatches(REGISTRATE,
             "input_hatch_4x", "Quadruple Input Hatch", "fluid_hatch.import",
             IN, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_4X, 4,
             MULTI_HATCH_TIERS, PartAbility.IMPORT_FLUIDS,
             PartAbility.IMPORT_FLUIDS_4X);
 
-    public final static MachineDefinition[] FLUID_IMPORT_HATCH_9X = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_IMPORT_HATCH_9X = registerFluidHatches(REGISTRATE,
             "input_hatch_9x", "Nonuple Input Hatch", "fluid_hatch.import",
             IN, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_9X, 9,
             MULTI_HATCH_TIERS, PartAbility.IMPORT_FLUIDS,
             PartAbility.IMPORT_FLUIDS_9X);
 
-    public final static MachineDefinition[] FLUID_EXPORT_HATCH = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_EXPORT_HATCH = registerFluidHatches(REGISTRATE,
             "output_hatch", "Output Hatch", "fluid_hatch.export",
             OUT, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_1X, 1,
             ALL_TIERS, PartAbility.EXPORT_FLUIDS,
             PartAbility.EXPORT_FLUIDS_1X);
 
-    public final static MachineDefinition[] FLUID_EXPORT_HATCH_4X = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_EXPORT_HATCH_4X = registerFluidHatches(REGISTRATE,
             "output_hatch_4x", "Quadruple Output Hatch", "fluid_hatch.export",
             OUT, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_4X, 4,
             MULTI_HATCH_TIERS, PartAbility.EXPORT_FLUIDS,
             PartAbility.EXPORT_FLUIDS_4X);
 
-    public final static MachineDefinition[] FLUID_EXPORT_HATCH_9X = registerFluidHatches(
+    public final static MachineDefinition[] FLUID_EXPORT_HATCH_9X = registerFluidHatches(REGISTRATE,
             "output_hatch_9x", "Nonuple Output Hatch", "fluid_hatch.export",
             OUT, FluidHatchPartMachine.INITIAL_TANK_CAPACITY_9X, 9,
             MULTI_HATCH_TIERS, PartAbility.EXPORT_FLUIDS,
             PartAbility.EXPORT_FLUIDS_9X);
 
-    public static final MachineDefinition[] ENERGY_INPUT_HATCH = registerTieredMachines("energy_input_hatch",
+    public static final MachineDefinition[] ENERGY_INPUT_HATCH = registerTieredMachines(REGISTRATE,
+            "energy_input_hatch",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, IN, 2),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " Energy Hatch")
@@ -749,7 +770,8 @@ public class GTMachines {
                     .register(),
             ALL_TIERS);
 
-    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH = registerTieredMachines("energy_output_hatch",
+    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH = registerTieredMachines(REGISTRATE,
+            "energy_output_hatch",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, OUT, 2),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " Dynamo Hatch")
@@ -767,7 +789,8 @@ public class GTMachines {
                     .register(),
             ALL_TIERS);
 
-    public static final MachineDefinition[] ENERGY_INPUT_HATCH_4A = registerTieredMachines("energy_input_hatch_4a",
+    public static final MachineDefinition[] ENERGY_INPUT_HATCH_4A = registerTieredMachines(REGISTRATE,
+            "energy_input_hatch_4a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, IN, 4),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " 4A Energy Hatch")
@@ -785,7 +808,8 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH_4A = registerTieredMachines("energy_output_hatch_4a",
+    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH_4A = registerTieredMachines(REGISTRATE,
+            "energy_output_hatch_4a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, OUT, 4),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " 4A Dynamo Hatch")
@@ -803,7 +827,8 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] ENERGY_INPUT_HATCH_16A = registerTieredMachines("energy_input_hatch_16a",
+    public static final MachineDefinition[] ENERGY_INPUT_HATCH_16A = registerTieredMachines(REGISTRATE,
+            "energy_input_hatch_16a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, IN, 16),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " 16A Energy Hatch")
@@ -821,7 +846,8 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH_16A = registerTieredMachines("energy_output_hatch_16a",
+    public static final MachineDefinition[] ENERGY_OUTPUT_HATCH_16A = registerTieredMachines(REGISTRATE,
+            "energy_output_hatch_16a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, OUT, 16),
             (tier, builder) -> builder
                     .langValue(VNF[tier] + " 16A Dynamo Hatch")
@@ -839,7 +865,7 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] SUBSTATION_ENERGY_INPUT_HATCH = registerTieredMachines(
+    public static final MachineDefinition[] SUBSTATION_ENERGY_INPUT_HATCH = registerTieredMachines(REGISTRATE,
             "substation_input_hatch_64a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, IN, 64),
             (tier, builder) -> builder
@@ -858,7 +884,7 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] SUBSTATION_ENERGY_OUTPUT_HATCH = registerTieredMachines(
+    public static final MachineDefinition[] SUBSTATION_ENERGY_OUTPUT_HATCH = registerTieredMachines(REGISTRATE,
             "substation_output_hatch_64a",
             (holder, tier) -> new EnergyHatchPartMachine(holder, tier, OUT, 64),
             (tier, builder) -> builder
@@ -877,7 +903,7 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(EV, GTCEuAPI.isHighTier() ? MAX : UHV));
 
-    public static final MachineDefinition[] MUFFLER_HATCH = registerTieredMachines("muffler_hatch",
+    public static final MachineDefinition[] MUFFLER_HATCH = registerTieredMachines(REGISTRATE, "muffler_hatch",
             MufflerPartMachine::new,
             (tier, builder) -> builder
                     .langValue("Muffler Hatch " + VNF[tier])
@@ -1011,7 +1037,8 @@ public class GTMachines {
             .tier(HV)
             .register();
 
-    public static final MachineDefinition[] ITEM_PASSTHROUGH_HATCH = registerTieredMachines("item_passthrough_hatch",
+    public static final MachineDefinition[] ITEM_PASSTHROUGH_HATCH = registerTieredMachines(REGISTRATE,
+            "item_passthrough_hatch",
             (holder, tier) -> new ItemBusPartMachine(holder, tier, IO.BOTH),
             (tier, builder) -> builder
                     .langValue("%s Item Passthrough Hatch".formatted(VNF[tier]))
@@ -1026,7 +1053,8 @@ public class GTMachines {
                     .register(),
             ELECTRIC_TIERS);
 
-    public static final MachineDefinition[] FLUID_PASSTHROUGH_HATCH = registerTieredMachines("fluid_passthrough_hatch",
+    public static final MachineDefinition[] FLUID_PASSTHROUGH_HATCH = registerTieredMachines(REGISTRATE,
+            "fluid_passthrough_hatch",
             (holder, tier) -> new FluidHatchPartMachine(holder, tier, IO.BOTH,
                     FluidHatchPartMachine.INITIAL_TANK_CAPACITY_1X, 1),
             (tier, builder) -> builder
@@ -1056,7 +1084,7 @@ public class GTMachines {
             .overlayTieredHullModel("reservoir_hatch")
             .register();
 
-    public static final MachineDefinition[] DUAL_IMPORT_HATCH = registerTieredMachines(
+    public static final MachineDefinition[] DUAL_IMPORT_HATCH = registerTieredMachines(REGISTRATE,
             "dual_input_hatch",
             (holder, tier) -> new DualHatchPartMachine(holder, tier, IN),
             (tier, builder) -> builder
@@ -1079,7 +1107,7 @@ public class GTMachines {
                     .register(),
             DUAL_HATCH_TIERS);
 
-    public static final MachineDefinition[] DUAL_EXPORT_HATCH = registerTieredMachines(
+    public static final MachineDefinition[] DUAL_EXPORT_HATCH = registerTieredMachines(REGISTRATE,
             "dual_output_hatch",
             (holder, tier) -> new DualHatchPartMachine(holder, tier, OUT),
             (tier, builder) -> builder
@@ -1102,7 +1130,7 @@ public class GTMachines {
                     .register(),
             DUAL_HATCH_TIERS);
 
-    public static final MachineDefinition[] DIODE = registerTieredMachines("diode",
+    public static final MachineDefinition[] DIODE = registerTieredMachines(REGISTRATE, "diode",
             DiodePartMachine::new,
             (tier, builder) -> builder
                     .langValue("%s Diode".formatted(VNF[tier]))
@@ -1121,7 +1149,7 @@ public class GTMachines {
                     .register(),
             ELECTRIC_TIERS);
 
-    public static final MachineDefinition[] ROTOR_HOLDER = registerTieredMachines("rotor_holder",
+    public static final MachineDefinition[] ROTOR_HOLDER = registerTieredMachines(REGISTRATE, "rotor_holder",
             RotorHolderPartMachine::new,
             (tier, builder) -> builder
                     .langValue("%s Rotor Holder".formatted(VNF[tier]))
@@ -1137,17 +1165,17 @@ public class GTMachines {
                     .register(),
             GTValues.tiersBetween(HV, GTCEuAPI.isHighTier() ? OpV : UV));
 
-    public static final MachineDefinition[] LASER_INPUT_HATCH_256 = registerLaserHatch(IN, 256,
+    public static final MachineDefinition[] LASER_INPUT_HATCH_256 = registerLaserHatch(REGISTRATE, IN, 256,
             PartAbility.INPUT_LASER);
-    public static final MachineDefinition[] LASER_OUTPUT_HATCH_256 = registerLaserHatch(OUT, 256,
+    public static final MachineDefinition[] LASER_OUTPUT_HATCH_256 = registerLaserHatch(REGISTRATE, OUT, 256,
             PartAbility.OUTPUT_LASER);
-    public static final MachineDefinition[] LASER_INPUT_HATCH_1024 = registerLaserHatch(IN, 1024,
+    public static final MachineDefinition[] LASER_INPUT_HATCH_1024 = registerLaserHatch(REGISTRATE, IN, 1024,
             PartAbility.INPUT_LASER);
-    public static final MachineDefinition[] LASER_OUTPUT_HATCH_1024 = registerLaserHatch(OUT, 1024,
+    public static final MachineDefinition[] LASER_OUTPUT_HATCH_1024 = registerLaserHatch(REGISTRATE, OUT, 1024,
             PartAbility.OUTPUT_LASER);
-    public static final MachineDefinition[] LASER_INPUT_HATCH_4096 = registerLaserHatch(IN, 4096,
+    public static final MachineDefinition[] LASER_INPUT_HATCH_4096 = registerLaserHatch(REGISTRATE, IN, 4096,
             PartAbility.INPUT_LASER);
-    public static final MachineDefinition[] LASER_OUTPUT_HATCH_4096 = registerLaserHatch(OUT, 4096,
+    public static final MachineDefinition[] LASER_OUTPUT_HATCH_4096 = registerLaserHatch(REGISTRATE, OUT, 4096,
             PartAbility.OUTPUT_LASER);
     public static final MachineDefinition MONITOR = REGISTRATE.machine("monitor", MonitorPartMachine::new)
             .rotationState(RotationState.ALL)
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
index d250a8a3fec..ea864f72201 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java
@@ -49,7 +49,7 @@ public class GCYMMachines {
 
     public static void init() {}
 
-    public static final MachineDefinition[] PARALLEL_HATCH = registerTieredMachines("parallel_hatch",
+    public static final MachineDefinition[] PARALLEL_HATCH = registerTieredMachines(REGISTRATE, "parallel_hatch",
             ParallelHatchPartMachine::new,
             (tier, builder) -> builder
                     .langValue(switch (tier) {
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java
index dc2effb3089..294a8aefa75 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java
@@ -92,7 +92,6 @@
 import static com.gregtechceu.gtceu.common.data.models.GTMachineModels.*;
 import static com.gregtechceu.gtceu.common.machine.electric.BatteryBufferMachine.AMPS_PER_BATTERY_NORMAL;
 import static com.gregtechceu.gtceu.common.machine.storage.QuantumTankMachine.TANK_CAPACITY;
-import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE;
 import static com.gregtechceu.gtceu.utils.FormattingUtil.*;
 
 public class GTMachineUtils {
@@ -126,20 +125,6 @@ public class GTMachineUtils {
             PartAbility.EXPORT_ITEMS, PartAbility.EXPORT_FLUIDS,
     };
 
-    /**
-     * @deprecated Use {@link SimpleMachineBuilder}
-     */
-    @Deprecated(since = "8.0.0")
-    public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType,
-                                                             Int2IntFunction tankScalingFunction,
-                                                             boolean hasPollutionDebuff, PanelFactory panelFactory) {
-        return new SimpleMachineBuilder(REGISTRATE, name, recipeType)
-                .tankScalingFunction(tankScalingFunction)
-                .hasPollutionDebuff(hasPollutionDebuff)
-                .panelFactory(panelFactory)
-                .register();
-    }
-
     /**
      * @deprecated Use {@link SimpleMachineBuilder}
      */
@@ -155,19 +140,6 @@ public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate
                 .register();
     }
 
-    /**
-     * @deprecated Use {@link SimpleMachineBuilder}
-     */
-    @Deprecated(since = "8.0.0")
-    public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType,
-                                                             Int2IntFunction tankScalingFunction,
-                                                             PanelFactory panelFactory) {
-        return new SimpleMachineBuilder(REGISTRATE, name, recipeType)
-                .panelFactory(panelFactory)
-                .tankScalingFunction(tankScalingFunction)
-                .register();
-    }
-
     /**
      * @deprecated Use {@link SimpleMachineBuilder}
      */
@@ -182,17 +154,6 @@ public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate
                 .register();
     }
 
-    /**
-     * @deprecated Use {@link SimpleMachineBuilder}
-     */
-    @Deprecated(since = "8.0.0")
-    public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType,
-                                                             PanelFactory panelFactory) {
-        return new SimpleMachineBuilder(REGISTRATE, name, recipeType)
-                .panelFactory(panelFactory)
-                .register();
-    }
-
     /**
      * @deprecated Use {@link SimpleMachineBuilder}
      */
@@ -219,13 +180,6 @@ public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate
                 .register();
     }
 
-    public static  MachineDefinition[] registerTieredMachines(String name,
-                                                                                           MachineInstanceFactory.Tiered factory,
-                                                                                           BiFunction, MachineDefinition> builder,
-                                                                                           int... tiers) {
-        return registerTieredMachines(REGISTRATE, name, factory, builder, tiers);
-    }
-
     public static  MachineDefinition[] registerTieredMachines(GTRegistrate registrate,
                                                                                            String name,
                                                                                            MachineInstanceFactory.Tiered factory,
@@ -242,13 +196,6 @@ public static  MachineDefinition[] registerTieredMa
         return definitions;
     }
 
-    public static <
-            MACHINE extends MetaMachine> Pair registerSteamMachines(String name,
-                                                                                                          MachineInstanceFactory.Steam factory,
-                                                                                                          BiFunction, MachineDefinition> builder) {
-        return registerSteamMachines(REGISTRATE, name, factory, builder);
-    }
-
     public static <
             MACHINE extends MetaMachine> Pair registerSteamMachines(GTRegistrate registrate,
                                                                                                           String name,
@@ -265,13 +212,6 @@ MACHINE extends MetaMachine> Pair register
         return Pair.of(lowTier, highTier);
     }
 
-    public static MachineDefinition[] registerFluidHatches(String name, String displayName, String tooltip,
-                                                           IO io, int initialCapacity, int slots,
-                                                           int[] tiers, PartAbility... abilities) {
-        return registerFluidHatches(REGISTRATE, name, displayName, tooltip, io, initialCapacity, slots, tiers,
-                abilities);
-    }
-
     public static MachineDefinition[] registerFluidHatches(GTRegistrate registrate, String name, String displayName,
                                                            String tooltip,
                                                            IO io, int initialCapacity, int slots,
@@ -311,10 +251,6 @@ public static MachineDefinition[] registerFluidHatches(GTRegistrate registrate,
                 tiers);
     }
 
-    public static MachineDefinition[] registerTransformerMachines(String langName, int baseAmp) {
-        return registerTransformerMachines(REGISTRATE, langName, baseAmp);
-    }
-
     public static MachineDefinition[] registerTransformerMachines(GTRegistrate registrate, String langName,
                                                                   int baseAmp) {
         return registerTieredMachines(registrate, "transformer_%da".formatted(baseAmp),
@@ -347,15 +283,6 @@ public static MachineDefinition[] registerTransformerMachines(GTRegistrate regis
         // UHV not needed, as a UV transformer transforms up to UHV
     }
 
-    public static MachineDefinition[] registerSimpleGenerator(String name,
-                                                              GTRecipeType recipeType,
-                                                              Int2IntFunction tankScalingFunction,
-                                                              float hazardStrengthPerOperation,
-                                                              int... tiers) {
-        return registerSimpleGenerator(REGISTRATE, name, recipeType, tankScalingFunction, hazardStrengthPerOperation,
-                tiers);
-    }
-
     public static MachineDefinition[] registerSimpleGenerator(GTRegistrate registrate, String name,
                                                               GTRecipeType recipeType,
                                                               Int2IntFunction tankScalingFunction,
@@ -379,11 +306,6 @@ public static MachineDefinition[] registerSimpleGenerator(GTRegistrate registrat
                 tiers);
     }
 
-    public static Pair registerSimpleSteamMachines(String name,
-                                                                                         GTRecipeType recipeType) {
-        return registerSimpleSteamMachines(REGISTRATE, name, recipeType);
-    }
-
     public static Pair registerSimpleSteamMachines(GTRegistrate registrate,
                                                                                          String name,
                                                                                          GTRecipeType recipeType) {
@@ -399,10 +321,6 @@ public static Pair registerSimpleSteamMach
                         .register());
     }
 
-    public static MachineDefinition[] registerBatteryBuffer(int batterySlotSize) {
-        return registerBatteryBuffer(REGISTRATE, batterySlotSize);
-    }
-
     public static MachineDefinition[] registerBatteryBuffer(GTRegistrate registrate, int batterySlotSize) {
         return registerTieredMachines(registrate, "battery_buffer_" + batterySlotSize + "x",
                 (holder, tier) -> new BatteryBufferMachine(holder, tier, batterySlotSize, AMPS_PER_BATTERY_NORMAL,
@@ -426,10 +344,6 @@ public static MachineDefinition[] registerBatteryBuffer(GTRegistrate registrate,
                 ALL_TIERS);
     }
 
-    public static MachineDefinition[] registerCharger(int itemSlotSize) {
-        return registerCharger(REGISTRATE, itemSlotSize);
-    }
-
     public static MachineDefinition[] registerCharger(GTRegistrate registrate, int itemSlotSize) {
         return registerTieredMachines(registrate, "charger_" + itemSlotSize + "x",
                 (holder, tier) -> new BatteryBufferMachine(holder, tier, itemSlotSize,
@@ -451,10 +365,6 @@ public static MachineDefinition[] registerCharger(GTRegistrate registrate, int i
                 ALL_TIERS);
     }
 
-    public static MachineDefinition[] registerConverter(int amperage) {
-        return registerConverter(REGISTRATE, amperage);
-    }
-
     public static MachineDefinition[] registerConverter(GTRegistrate registrate, int amperage) {
         final var tab = registrate.creativeModeTab();
 
@@ -489,10 +399,6 @@ public static MachineDefinition[] registerConverter(GTRegistrate registrate, int
         return converters;
     }
 
-    public static MachineDefinition[] registerLaserHatch(IO io, int amperage, PartAbility ability) {
-        return registerLaserHatch(REGISTRATE, io, amperage, ability);
-    }
-
     public static MachineDefinition[] registerLaserHatch(GTRegistrate registrate, IO io, int amperage,
                                                          PartAbility ability) {
         String name = io == IN ? "target" : "source";
@@ -518,10 +424,6 @@ public static MachineDefinition[] registerLaserHatch(GTRegistrate registrate, IO
                 HIGH_TIERS);
     }
 
-    public static MachineDefinition registerCrate(Material material, int capacity, int rowLength, String lang) {
-        return registerCrate(REGISTRATE, material, capacity, rowLength, lang);
-    }
-
     public static MachineDefinition registerCrate(GTRegistrate registrate, Material material, int capacity,
                                                   int rowLength, String lang) {
         final boolean wooden = material.hasProperty(PropertyKey.WOOD);
@@ -539,10 +441,6 @@ public static MachineDefinition registerCrate(GTRegistrate registrate, Material
                 .register();
     }
 
-    public static MachineDefinition registerDrum(Material material, int capacity, String lang) {
-        return registerDrum(REGISTRATE, material, capacity, lang);
-    }
-
     public static MachineDefinition registerDrum(GTRegistrate registrate, Material material, int capacity,
                                                  String lang) {
         boolean wooden = material.hasProperty(PropertyKey.WOOD);
@@ -571,10 +469,6 @@ public static MachineDefinition registerDrum(GTRegistrate registrate, Material m
         return definition;
     }
 
-    public static MachineDefinition[] registerQuantumTanks(String name, int... tiers) {
-        return registerQuantumTanks(REGISTRATE, name, tiers);
-    }
-
     public static MachineDefinition[] registerQuantumTanks(GTRegistrate registrate, String name, int... tiers) {
         MachineDefinition[] definitions = new MachineDefinition[GTValues.TIER_COUNT];
         for (int tier : tiers) {
@@ -603,10 +497,6 @@ public static MachineDefinition[] registerQuantumTanks(GTRegistrate registrate,
         return definitions;
     }
 
-    public static MachineDefinition[] registerQuantumChests(String name, int... tiers) {
-        return registerQuantumChests(REGISTRATE, name, tiers);
-    }
-
     public static MachineDefinition[] registerQuantumChests(GTRegistrate registrate, String name, int... tiers) {
         return registerTieredMachines(registrate, name,
                 (holder, tier) -> new QuantumChestMachine(holder, tier,
@@ -633,14 +523,6 @@ public static MachineDefinition[] registerQuantumChests(GTRegistrate registrate,
     //////////////////////////////////////
     // multi register helpers
 
-    public static MultiblockMachineDefinition registerMultiblockTank(String name, String displayName, int capacity,
-                                                                     Supplier casing,
-                                                                     Supplier valve,
-                                                                     @Nullable PropertyFluidFilter filter,
-                                                                     BiConsumer, ResourceLocation> rendererSetup) {
-        return registerMultiblockTank(REGISTRATE, name, displayName, capacity, casing, valve, filter, rendererSetup);
-    }
-
     public static MultiblockMachineDefinition registerMultiblockTank(GTRegistrate registrate, String name,
                                                                      String displayName, int capacity,
                                                                      Supplier casing,
@@ -671,11 +553,6 @@ public static MultiblockMachineDefinition registerMultiblockTank(GTRegistrate re
         return builder.register();
     }
 
-    public static MachineDefinition registerTankValve(String name, String displayName, boolean isMetal,
-                                                      BiConsumer, ResourceLocation> rendererSetup) {
-        return registerTankValve(REGISTRATE, name, displayName, isMetal, rendererSetup);
-    }
-
     public static MachineDefinition registerTankValve(GTRegistrate registrate, String name, String displayName,
                                                       boolean isMetal,
                                                       BiConsumer, ResourceLocation> rendererSetup) {
@@ -689,14 +566,6 @@ public static MachineDefinition registerTankValve(GTRegistrate registrate, Strin
         return builder.register();
     }
 
-    public static <
-            MACHINE extends MultiblockControllerMachine> MultiblockMachineDefinition[] registerTieredMultis(String name,
-                                                                                                            MachineInstanceFactory.Tiered factory,
-                                                                                                            BiFunction, MultiblockMachineDefinition> builder,
-                                                                                                            int... tiers) {
-        return registerTieredMultis(REGISTRATE, name, factory, builder, tiers);
-    }
-
     public static <
             MACHINE extends MultiblockControllerMachine> MultiblockMachineDefinition[] registerTieredMultis(GTRegistrate registrate,
                                                                                                             String name,
@@ -714,15 +583,6 @@ MACHINE extends MultiblockControllerMachine> MultiblockMachineDefinition[] regis
         return definitions;
     }
 
-    public static MultiblockMachineDefinition registerLargeBoiler(String name, Supplier casing,
-                                                                  Supplier pipe,
-                                                                  Supplier fireBox,
-                                                                  ResourceLocation texture, BoilerFireboxType firebox,
-                                                                  int maxTemperature, int heatSpeed) {
-        return registerLargeBoiler(REGISTRATE, name, casing, pipe, fireBox, texture, firebox, maxTemperature,
-                heatSpeed);
-    }
-
     public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate registrate, String name,
                                                                   Supplier casing,
                                                                   Supplier pipe,
@@ -768,7 +628,7 @@ public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate regis
                 })
                 .recoveryItems(
                         () -> new ItemLike[] {
-                                GTMaterialItems.MATERIAL_ITEMS.get(TagPrefix.dustTiny, GTMaterials.Ash).get() })
+                                GTMaterialItems.MATERIAL_ITEMS.get(TagPrefix.dustTiny, GTMaterials.Ash).get()})
                 .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE)
                 .model(createWorkableCasingMachineModel(texture,
                         GTCEu.id("block/multiblock/generator/large_%s_boiler".formatted(name)))
@@ -784,15 +644,6 @@ public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate regis
         // spotless:on
     }
 
-    public static MultiblockMachineDefinition registerLargeCombustionEngine(String name, int tier,
-                                                                            Supplier casing,
-                                                                            Supplier gear,
-                                                                            Supplier intake,
-                                                                            ResourceLocation casingTexture,
-                                                                            ResourceLocation overlayModel) {
-        return registerLargeCombustionEngine(REGISTRATE, name, tier, casing, gear, intake, casingTexture, overlayModel);
-    }
-
     public static MultiblockMachineDefinition registerLargeCombustionEngine(GTRegistrate registrate,
                                                                             String name, int tier,
                                                                             Supplier casing,
@@ -844,14 +695,6 @@ public static MultiblockMachineDefinition registerLargeCombustionEngine(GTRegist
                 .register();
     }
 
-    public static MultiblockMachineDefinition registerLargeTurbine(String name, int tier, GTRecipeType recipeType,
-                                                                   Supplier casing,
-                                                                   Supplier gear,
-                                                                   ResourceLocation casingTexture,
-                                                                   ResourceLocation overlayModel) {
-        return registerLargeTurbine(REGISTRATE, name, tier, recipeType, casing, gear, casingTexture, overlayModel);
-    }
-
     public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate registrate,
                                                                    String name, int tier, GTRecipeType recipeType,
                                                                    Supplier casing,
@@ -862,16 +705,6 @@ public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate regi
                 true);
     }
 
-    public static MultiblockMachineDefinition registerLargeTurbine(String name, int tier, GTRecipeType recipeType,
-                                                                   Supplier casing,
-                                                                   Supplier gear,
-                                                                   ResourceLocation casingTexture,
-                                                                   ResourceLocation overlayModel,
-                                                                   boolean needsMuffler) {
-        return registerLargeTurbine(REGISTRATE, name, tier, recipeType, casing, gear, casingTexture, overlayModel,
-                needsMuffler);
-    }
-
     public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate registrate,
                                                                    String name, int tier, GTRecipeType recipeType,
                                                                    Supplier casing,
diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java
index 8e5815b02bc..2ad1331b4a8 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java
@@ -60,27 +60,29 @@
 import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE;
 import static com.gregtechceu.gtceu.utils.FormattingUtil.toRomanNumeral;
 
+@SuppressWarnings("unused")
 public class GTMultiMachines {
 
     //////////////////////////////////////
     // ******* Multiblock *******//
     //////////////////////////////////////
-    public static final MultiblockMachineDefinition LARGE_BOILER_BRONZE = registerLargeBoiler("bronze",
+    public static final MultiblockMachineDefinition LARGE_BOILER_BRONZE = registerLargeBoiler(REGISTRATE, "bronze",
             CASING_BRONZE_BRICKS, CASING_BRONZE_PIPE, FIREBOX_BRONZE,
             GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), BoilerFireboxType.BRONZE_FIREBOX,
             ConfigHolder.INSTANCE.machines.largeBoilers.bronzeBoilerMaxTemperature,
             ConfigHolder.INSTANCE.machines.largeBoilers.bronzeBoilerHeatSpeed);
-    public static final MultiblockMachineDefinition LARGE_BOILER_STEEL = registerLargeBoiler("steel",
+    public static final MultiblockMachineDefinition LARGE_BOILER_STEEL = registerLargeBoiler(REGISTRATE, "steel",
             CASING_STEEL_SOLID, CASING_STEEL_PIPE, FIREBOX_STEEL,
             GTCEu.id("block/casings/solid/machine_casing_solid_steel"), BoilerFireboxType.STEEL_FIREBOX,
             ConfigHolder.INSTANCE.machines.largeBoilers.steelBoilerMaxTemperature,
             ConfigHolder.INSTANCE.machines.largeBoilers.steelBoilerHeatSpeed);
-    public static final MultiblockMachineDefinition LARGE_BOILER_TITANIUM = registerLargeBoiler("titanium",
+    public static final MultiblockMachineDefinition LARGE_BOILER_TITANIUM = registerLargeBoiler(REGISTRATE, "titanium",
             CASING_TITANIUM_STABLE, CASING_TITANIUM_PIPE, FIREBOX_TITANIUM,
             GTCEu.id("block/casings/solid/machine_casing_stable_titanium"), BoilerFireboxType.TITANIUM_FIREBOX,
             ConfigHolder.INSTANCE.machines.largeBoilers.titaniumBoilerMaxTemperature,
             ConfigHolder.INSTANCE.machines.largeBoilers.titaniumBoilerHeatSpeed);
-    public static final MultiblockMachineDefinition LARGE_BOILER_TUNGSTENSTEEL = registerLargeBoiler("tungstensteel",
+    public static final MultiblockMachineDefinition LARGE_BOILER_TUNGSTENSTEEL = registerLargeBoiler(REGISTRATE,
+            "tungstensteel",
             CASING_TUNGSTENSTEEL_ROBUST, CASING_TUNGSTENSTEEL_PIPE, FIREBOX_TUNGSTENSTEEL,
             GTCEu.id("block/casings/solid/machine_casing_robust_tungstensteel"),
             BoilerFireboxType.TUNGSTENSTEEL_FIREBOX,
@@ -492,7 +494,8 @@ public class GTMultiMachines {
                                     BoilerFireboxType.BRONZE_FIREBOX, CASING_BRONZE_BRICKS))))
             .register();
 
-    public static final MultiblockMachineDefinition[] FUSION_REACTOR = registerTieredMultis("fusion_reactor",
+    public static final MultiblockMachineDefinition[] FUSION_REACTOR = registerTieredMultis(REGISTRATE,
+            "fusion_reactor",
             FusionReactorMachine::new, (tier, builder) -> builder
                     .rotationState(RotationState.ALL)
                     .langValue("Fusion Reactor Computer MK %s".formatted(toRomanNumeral(tier - 5)))
@@ -545,7 +548,7 @@ public class GTMultiMachines {
                     .register(),
             LuV, ZPM, UV);
 
-    public static final MultiblockMachineDefinition[] FLUID_DRILLING_RIG = registerTieredMultis(
+    public static final MultiblockMachineDefinition[] FLUID_DRILLING_RIG = registerTieredMultis(REGISTRATE,
             "fluid_drilling_rig", FluidDrillMachine::new, (tier, builder) -> builder
                     .rotationState(RotationState.ALL)
                     .langValue("%s Fluid Drilling Rig %s".formatted(VLVH[tier], VLVT[tier]))
@@ -578,7 +581,7 @@ public class GTMultiMachines {
                     .register(),
             MV, HV, EV);
 
-    public static final MultiblockMachineDefinition[] LARGE_MINER = registerTieredMultis("large_miner",
+    public static final MultiblockMachineDefinition[] LARGE_MINER = registerTieredMultis(REGISTRATE, "large_miner",
             (holder, tier) -> new LargeMinerMachine(holder, tier, 64 / tier, 2 * tier - 5, tier, 8 - (tier - 5)),
             (tier, builder) -> builder
                     .rotationState(RotationState.NON_Y_AXIS)
@@ -672,19 +675,21 @@ public class GTMultiMachines {
                     GTCEu.id("block/multiblock/cleanroom"))
             .register();
 
-    public static final MultiblockMachineDefinition LARGE_COMBUSTION_ENGINE = registerLargeCombustionEngine(
+    public static final MultiblockMachineDefinition LARGE_COMBUSTION_ENGINE = registerLargeCombustionEngine(REGISTRATE,
             "large_combustion_engine", EV,
             CASING_TITANIUM_STABLE, CASING_TITANIUM_GEARBOX, CASING_ENGINE_INTAKE,
             GTCEu.id("block/casings/solid/machine_casing_stable_titanium"),
             GTCEu.id("block/multiblock/generator/large_combustion_engine"));
 
     public static final MultiblockMachineDefinition EXTREME_COMBUSTION_ENGINE = registerLargeCombustionEngine(
+            REGISTRATE,
             "extreme_combustion_engine", IV,
             CASING_TUNGSTENSTEEL_ROBUST, CASING_TUNGSTENSTEEL_GEARBOX, CASING_EXTREME_ENGINE_INTAKE,
             GTCEu.id("block/casings/solid/machine_casing_robust_tungstensteel"),
             GTCEu.id("block/multiblock/generator/extreme_combustion_engine"));
 
-    public static final MultiblockMachineDefinition LARGE_STEAM_TURBINE = registerLargeTurbine("steam_large_turbine",
+    public static final MultiblockMachineDefinition LARGE_STEAM_TURBINE = registerLargeTurbine(REGISTRATE,
+            "steam_large_turbine",
             HV,
             GTRecipeTypes.STEAM_TURBINE_FUELS,
             CASING_STEEL_TURBINE, CASING_STEEL_GEARBOX,
@@ -692,14 +697,17 @@ public class GTMultiMachines {
             GTCEu.id("block/multiblock/generator/large_steam_turbine"),
             false);
 
-    public static final MultiblockMachineDefinition LARGE_GAS_TURBINE = registerLargeTurbine("gas_large_turbine", EV,
+    public static final MultiblockMachineDefinition LARGE_GAS_TURBINE = registerLargeTurbine(REGISTRATE,
+            "gas_large_turbine",
+            EV,
             GTRecipeTypes.GAS_TURBINE_FUELS,
             CASING_STAINLESS_TURBINE, CASING_STAINLESS_STEEL_GEARBOX,
             GTCEu.id("block/casings/mechanic/machine_casing_turbine_stainless_steel"),
             GTCEu.id("block/multiblock/generator/large_gas_turbine"),
             true);
 
-    public static final MultiblockMachineDefinition LARGE_PLASMA_TURBINE = registerLargeTurbine("plasma_large_turbine",
+    public static final MultiblockMachineDefinition LARGE_PLASMA_TURBINE = registerLargeTurbine(REGISTRATE,
+            "plasma_large_turbine",
             IV,
             GTRecipeTypes.PLASMA_GENERATOR_FUELS,
             CASING_TUNGSTENSTEEL_TURBINE, CASING_TUNGSTENSTEEL_GEARBOX,
@@ -788,7 +796,7 @@ public class GTMultiMachines {
                     GTCEu.id("block/multiblock/charcoal_pile_igniter"))
             .register();
 
-    public static MultiblockMachineDefinition[] BEDROCK_ORE_MINER = registerTieredMultis(
+    public static MultiblockMachineDefinition[] BEDROCK_ORE_MINER = registerTieredMultis(REGISTRATE,
             "bedrock_ore_miner", BedrockOreMinerMachine::new, (tier, builder) -> builder
                     .rotationState(RotationState.NON_Y_AXIS)
                     .langValue("%s Bedrock Ore Miner %s".formatted(VLVH[tier], VLVT[tier]))
@@ -825,31 +833,31 @@ public class GTMultiMachines {
             MV, HV, EV);
 
     // Multiblock Tanks
-    public static final MachineDefinition WOODEN_TANK_VALVE = GTMachineUtils.registerTankValve(
+    public static final MachineDefinition WOODEN_TANK_VALVE = GTMachineUtils.registerTankValve(REGISTRATE,
             "wooden_tank_valve", "Wooden Tank Valve", false,
             (builder, overlay) -> builder.sidedWorkableCasingModel(GTCEu.id("block/casings/wood_wall"), overlay));
-    public static final MultiblockMachineDefinition WOODEN_MULTIBLOCK_TANK = registerMultiblockTank(
+    public static final MultiblockMachineDefinition WOODEN_MULTIBLOCK_TANK = registerMultiblockTank(REGISTRATE,
             "wooden_multiblock_tank", "Wooden Multiblock Tank", 250 * 1000,
             CASING_WOOD_WALL, WOODEN_TANK_VALVE::getBlock,
             new PropertyFluidFilter(340, false, false, false, false),
             (builder, overlay) -> builder.sidedWorkableCasingModel(GTCEu.id("block/casings/wood_wall"), overlay));
 
-    public static final MachineDefinition BRONZE_TANK_VALVE = GTMachineUtils.registerTankValve(
+    public static final MachineDefinition BRONZE_TANK_VALVE = GTMachineUtils.registerTankValve(REGISTRATE,
             "bronze_tank_valve", "Bronze Tank Valve", true,
             (builder, overlay) -> builder
                     .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), overlay));
-    public static final MultiblockMachineDefinition BRONZE_MULTIBLOCK_TANK = registerMultiblockTank(
+    public static final MultiblockMachineDefinition BRONZE_MULTIBLOCK_TANK = registerMultiblockTank(REGISTRATE,
             "bronze_multiblock_tank", "Bronze Multiblock Tank", 500 * 1000,
             CASING_BRONZE_BRICKS, BRONZE_TANK_VALVE::getBlock,
             new PropertyFluidFilter(1696, true, false, false, false),
             (builder, overlay) -> builder
                     .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), overlay));
 
-    public static final MachineDefinition STEEL_TANK_VALVE = GTMachineUtils.registerTankValve(
+    public static final MachineDefinition STEEL_TANK_VALVE = GTMachineUtils.registerTankValve(REGISTRATE,
             "steel_tank_valve", "Steel Tank Valve", true,
             (builder, overlay) -> builder.workableCasingModel(
                     GTCEu.id("block/casings/solid/machine_casing_solid_steel"), overlay));
-    public static final MultiblockMachineDefinition STEEL_MULTIBLOCK_TANK = registerMultiblockTank(
+    public static final MultiblockMachineDefinition STEEL_MULTIBLOCK_TANK = registerMultiblockTank(REGISTRATE,
             "steel_multiblock_tank", "Steel Multiblock Tank", 1000 * 1000,
             CASING_STEEL_SOLID, STEEL_TANK_VALVE::getBlock,
             null,
diff --git a/src/main/java/com/gregtechceu/gtceu/common/registry/GTRegistration.java b/src/main/java/com/gregtechceu/gtceu/common/registry/GTRegistration.java
index fc5a4cd7b54..b55eac634a3 100644
--- a/src/main/java/com/gregtechceu/gtceu/common/registry/GTRegistration.java
+++ b/src/main/java/com/gregtechceu/gtceu/common/registry/GTRegistration.java
@@ -6,9 +6,16 @@
 import net.minecraft.resources.ResourceKey;
 import net.minecraft.world.item.CreativeModeTab;
 
+import org.jetbrains.annotations.ApiStatus;
+
 public class GTRegistration {
 
+    /**
+     * Addon devs: You must use your own registrate instance.
+     */
+    @ApiStatus.Internal
     public static final GTRegistrate REGISTRATE = GTRegistrate.create(GTCEu.MOD_ID);
+
     static {
         GTRegistration.REGISTRATE.defaultCreativeTab((ResourceKey) null);
     }
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java
index b16dee0e5df..a147d300272 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java
@@ -8,8 +8,8 @@
 import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine;
 import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection;
 import com.gregtechceu.gtceu.api.registry.registrate.BuilderBase;
+import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate;
 import com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder;
-import com.gregtechceu.gtceu.common.registry.GTRegistration;
 import com.gregtechceu.gtceu.utils.FormattingUtil;
 
 import net.minecraft.resources.ResourceLocation;
@@ -31,7 +31,6 @@ public class KJSSteamMachineBuilder extends BuilderBase {
     public transient SteamDefinitionFunction definition = (isHP, def) -> def.tier(isHP ? 1 : 0);
 
     private transient MachineBuilder lowPressureBuilder = null, highPressureBuilder = null;
-    private transient MachineDefinition hpValue = null;
 
     public KJSSteamMachineBuilder(ResourceLocation id) {
         super(id);
@@ -39,8 +38,10 @@ public KJSSteamMachineBuilder(ResourceLocation id) {
 
     @Override
     public MachineDefinition register() {
+        var registrate = GTRegistrate.createIgnoringListenerErrors(this.id.getNamespace());
+
         if (hasLowPressure) {
-            this.lowPressureBuilder = GTRegistration.REGISTRATE.machine(
+            this.lowPressureBuilder = registrate.machine(
                     String.format("lp_%s", this.id.getPath()),
                     holder -> machine.create(holder, false));
             lowPressureBuilder.langValue("Low Pressure " + FormattingUtil.toEnglishName(this.id.getPath()))
@@ -53,7 +54,7 @@ public MachineDefinition register() {
         }
 
         if (hasHighPressure) {
-            this.highPressureBuilder = GTRegistration.REGISTRATE.machine(
+            this.highPressureBuilder = registrate.machine(
                     String.format("hp_%s", this.id.getPath()),
                     holder -> machine.create(holder, true));
             highPressureBuilder.langValue("High Pressure " + FormattingUtil.toEnglishName(this.id.getPath()))
@@ -62,10 +63,10 @@ public MachineDefinition register() {
                     .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK)
                     .workableSteamHullModel(true, id.withPrefix("block/machines/"));
             definition.apply(true, highPressureBuilder);
-            hpValue = highPressureBuilder.register();
+            value = highPressureBuilder.register();
         }
 
-        return value != null ? value : hpValue;
+        return value;
     }
 
     @Override
@@ -82,17 +83,12 @@ public void generateAssetJsons(@Nullable AssetJsonGenerator generator) {
     @Override
     public void generateLang(LangEventJS lang) {
         super.generateLang(lang);
-        if (value != null) {
-            lang.add(GTCEu.MOD_ID, value.getDescriptionId(), value.getLangValue());
-        }
-        if (hpValue != null) {
-            lang.add(GTCEu.MOD_ID, hpValue.getDescriptionId(), hpValue.getLangValue());
-        }
+        lang.add(GTCEu.MOD_ID, value.getDescriptionId(), value.getLangValue());
     }
 
     @Override
     public MachineDefinition get() {
-        return value != null ? value : hpValue;
+        return value;
     }
 
     @FunctionalInterface
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMachineBuilder.java
index 9c0a5ef5962..2db83acee31 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMachineBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMachineBuilder.java
@@ -6,9 +6,9 @@
 import com.gregtechceu.gtceu.api.machine.MetaMachine;
 import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
 import com.gregtechceu.gtceu.api.registry.registrate.BuilderBase;
+import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate;
 import com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder;
 import com.gregtechceu.gtceu.common.data.machines.GTMachineUtils;
-import com.gregtechceu.gtceu.common.registry.GTRegistration;
 
 import net.minecraft.resources.ResourceLocation;
 
@@ -92,7 +92,7 @@ public void generateLang(LangEventJS lang) {
         MachineDefinition[] definitions = new MachineDefinition[TIER_COUNT];
         for (final int tier : tiers) {
             String tierName = VN[tier].toLowerCase(Locale.ROOT);
-            MachineBuilder builder = GTRegistration.REGISTRATE.machine(
+            MachineBuilder builder = GTRegistrate.createIgnoringListenerErrors(this.id.getNamespace()).machine(
                     String.format("%s_%s", tierName, this.id.getPath()),
                     holder -> machine.create(holder, tier, tankScalingFunction));
 
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMultiblockBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMultiblockBuilder.java
index 30752a84860..618fd802048 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMultiblockBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSTieredMultiblockBuilder.java
@@ -4,10 +4,10 @@
 import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition;
 import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine;
 import com.gregtechceu.gtceu.api.registry.registrate.BuilderBase;
+import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate;
 import com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder;
 import com.gregtechceu.gtceu.api.registry.registrate.MultiblockMachineBuilder;
 import com.gregtechceu.gtceu.common.data.machines.GTMachineUtils;
-import com.gregtechceu.gtceu.common.registry.GTRegistration;
 
 import net.minecraft.resources.ResourceLocation;
 
@@ -77,9 +77,10 @@ public void generateLang(LangEventJS lang) {
         MultiblockMachineDefinition[] definitions = new MultiblockMachineDefinition[TIER_COUNT];
         for (final int tier : tiers) {
             String tierName = VN[tier].toLowerCase(Locale.ROOT);
-            MultiblockMachineBuilder builder = GTRegistration.REGISTRATE.multiblock(
-                    String.format("%s_%s", tierName, this.id.getPath()),
-                    holder -> machine.create(holder, tier));
+            MultiblockMachineBuilder builder = GTRegistrate
+                    .createIgnoringListenerErrors(this.id.getNamespace()).multiblock(
+                            String.format("%s_%s", tierName, this.id.getPath()),
+                            holder -> machine.create(holder, tier));
 
             builder.workableTieredHullModel(id.withPrefix("block/machines/"))
                     .tier(tier);
diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSWrappingMultiblockBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSWrappingMultiblockBuilder.java
index 563b94492e8..bd28c033cb2 100644
--- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSWrappingMultiblockBuilder.java
+++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSWrappingMultiblockBuilder.java
@@ -6,8 +6,8 @@
 import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine;
 import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine;
 import com.gregtechceu.gtceu.api.registry.registrate.BuilderBase;
+import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate;
 import com.gregtechceu.gtceu.api.registry.registrate.MultiblockMachineBuilder;
-import com.gregtechceu.gtceu.common.registry.GTRegistration;
 
 import net.minecraft.resources.ResourceLocation;
 
@@ -75,7 +75,8 @@ public MultiblockMachineDefinition register() {
     }
 
     public static MultiblockMachineBuilder createKJSMulti(ResourceLocation id) {
-        return new MultiblockMachineBuilder<>(GTRegistration.REGISTRATE, id.getPath(),
+        return new MultiblockMachineBuilder<>(GTRegistrate.createIgnoringListenerErrors(id.getNamespace()),
+                id.getPath(),
                 MetaMachineBlock::new,
                 MetaMachineItem::new,
                 WorkableElectricMultiblockMachine::new);
@@ -83,7 +84,8 @@ public MultiblockMachineDefinition register() {
 
     public static MultiblockMachineBuilder createKJSMulti(ResourceLocation id,
                                                                                              KJSTieredMachineBuilder.CreationFunction machine) {
-        return new MultiblockMachineBuilder<>(GTRegistration.REGISTRATE, id.getPath(),
+        return new MultiblockMachineBuilder<>(GTRegistrate.createIgnoringListenerErrors(id.getNamespace()),
+                id.getPath(),
                 MetaMachineBlock::new,
                 MetaMachineItem::new,
                 machine::create);

From bc8735132f016f5c9294b715a2249ff7e6ecd5d1 Mon Sep 17 00:00:00 2001
From: Gustavo <77560533+gustovafing@users.noreply.github.com>
Date: Tue, 14 Jul 2026 22:13:24 +1000
Subject: [PATCH 18/61] Update v8 machine migration docs (#5112)

---
 docs/content/Modpacks/Changes/v8.0.0.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/content/Modpacks/Changes/v8.0.0.md b/docs/content/Modpacks/Changes/v8.0.0.md
index af2a7b18ccb..6d4e394dccd 100644
--- a/docs/content/Modpacks/Changes/v8.0.0.md
+++ b/docs/content/Modpacks/Changes/v8.0.0.md
@@ -15,7 +15,8 @@ Many aspects of the machine classes have been refactored and changed in order to
 
 - The `MetaMachineBlockEntity`(MMBE) class has been removed, and `MetaMachine`(MM) is now a BlockEntity.
 - Most methods and properties of MMBE have been moved onto MM.
-- The `IMachineBlockEntity` interface has been removed. Use `MetaMachineBlock` directly instead.
+- The `IMachineBlock` interface has been removed. Use `MetaMachineBlock` directly instead.
+- The `IMachineBlockEntity` interface has been removed. Use `MetaMachine` directly instead.
 - Many methods common to all block entities have been moved to the `IGregtechBlockEntity` interface.
 - Machine instance creation functions have signature `(BlockEntityCreationInfo) -> MetaMachine` instead of `(IMachineBlockEntity) -> MetaMachine` 
 

From 6dfd8c255b556895454b173bf5e122471c9736fc Mon Sep 17 00:00:00 2001
From: Jambon123 <68718646+Jambon123@users.noreply.github.com>
Date: Wed, 15 Jul 2026 12:15:35 +0100
Subject: [PATCH 19/61]  Wiki information on .handleNonMaterialFluids() in Java
 (#5101)

---
 ...Prefixes-and-the-power-of-.setIgnored().md | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/docs/content/Modpacks/Materials-and-Elements/TagPrefixes-and-the-power-of-.setIgnored().md b/docs/content/Modpacks/Materials-and-Elements/TagPrefixes-and-the-power-of-.setIgnored().md
index 5438349be25..5ab5c122912 100644
--- a/docs/content/Modpacks/Materials-and-Elements/TagPrefixes-and-the-power-of-.setIgnored().md
+++ b/docs/content/Modpacks/Materials-and-Elements/TagPrefixes-and-the-power-of-.setIgnored().md
@@ -76,3 +76,25 @@ GTCEuStartupEvents.materialModification(event => { // (1)
 
 The `Material` for which you are adjusting the TagPrefix must be registered in GTCEu Modern's material registry; if this
 material is custom, this is done using `GTCEuStartupEvents.registry()`, as depicted in these docs.
+
+
+## What about fluids?
+
+Fluids are treated differently to items, their inclusion in a material is a property rather than a TagPrefix or MaterialFlag. 
+This makes replacing the fluid of a material with a fluid that you or another mod have created require a different approach than setIgnored. 
+The way to do this is using `GTFluids.handleNonMaterialFluids()` which can be found in the [``GTFluids`` class](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/common/data/GTFluids.java)
+
+`GTFluids.handleNonMaterialFluids()` takes in a `Material` and a `Fluid` or `Supplier` to replace the liquid of the material with the provided fluid.
+Assure that the material is registered with a liquid before attempting to replace it with your new fluid. An example is below.
+
+!!! note "This may differ!"
+    Depending on the way your fluid is registered you may need to change how you pass the `Fluid` argument, check how it is registered in the mod you are working with.
+
+```java title="ExampleMaterials.java"
+public static void register() {
+    GLUGG_BRINE = new Material.Builder(MyMod.id("glugg_brine"))
+        .liquid(new FluidBuilder()).buildAndRegister();
+
+    GTFluids.handleNonMaterialFluids(GLUGG_BRINE, () -> PVFluidRegistry.BRINE_FLUID_SOURCE.get());
+}
+```

From a5c92916475ec1016206d8bd102ecf2b0517735e Mon Sep 17 00:00:00 2001
From: TarLaboratories <159147059+TarLaboratories@users.noreply.github.com>
Date: Wed, 15 Jul 2026 15:09:34 +0300
Subject: [PATCH 20/61] Fix CM forming after multi refactor (#5091)

---
 .../api/placeholder/MultiLineComponent.java   |   2 +
 .../gtceu/api/placeholder/Placeholder.java    |  11 +-
 .../api/placeholder/PlaceholderHandler.java   |  31 ++--
 .../common/data/machines/GTMultiMachines.java |   6 +-
 .../item/modules/TextModuleBehaviour.java     |   6 +
 .../electric/CentralMonitorMachine.java       | 154 ++++++++++--------
 .../gtceu/common/mui/GTByteBufAdapters.java   |   5 +-
 .../mui/factory/CentralMonitorUIFactory.java  |   7 +-
 8 files changed, 129 insertions(+), 93 deletions(-)

diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
index f25c0c484a6..7dde6d83d6b 100644
--- a/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
+++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java
@@ -142,6 +142,7 @@ public MultiLineComponent withStyle(UnaryOperator