From b6daa2f21c4233cde8767e05485d40a8f1b3f4cf Mon Sep 17 00:00:00 2001 From: SkyBlase1978 Date: Tue, 28 Jul 2026 16:19:41 +0100 Subject: [PATCH 1/2] fixes issue where mineralogy would cause springs not to spawn --- build.gradle | 14 +++++++++----- gradle.properties | 2 +- .../client/OreSpawnWorldSettingsScreen.java | 14 +++++++++++++- src/main/resources/META-INF/accesstransformer.cfg | 1 + 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 8cd2320..33c3d4b 100644 --- a/build.gradle +++ b/build.gradle @@ -278,11 +278,11 @@ tasks.named('test', Test).configure { useJUnitPlatform() } -// Keep every Eclipse launch input on one physical Gradle cache. Mixing Buildship's -// cache with a command-line cache duplicates named Java modules such as FML and Mixin. +// Keep every Eclipse launch input on Buildship's physical Gradle cache. Command-line +// verification may deliberately use a separate cache, which must not leak into Eclipse. def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') { group = 'IDE' - description = 'Aligns Eclipse project, Buildship, and Forge run classpaths with the active Gradle home.' + description = 'Aligns Eclipse project, Buildship, and Forge run classpaths with Eclipse\'s Gradle home.' doLast { File classpathDir = layout.buildDirectory.dir('classpath').get().asFile @@ -300,14 +300,18 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') { } String configuredGradleHome = buildship.getProperty('connection.gradle.user.home', '').trim() File eclipseProjectClasspath = file('.classpath') - File eclipseGradleHome = gradle.gradleUserHomeDir.canonicalFile + String eclipseGradleHomeOverride = (findProperty('eclipseGradleUserHome') + ?: System.getenv('ECLIPSE_GRADLE_USER_HOME') ?: '').toString().trim() + File eclipseGradleHome = eclipseGradleHomeOverride + ? file(eclipseGradleHomeOverride).canonicalFile + : new File(System.getProperty('user.home'), '.gradle').canonicalFile if (!configuredGradleHome || file(configuredGradleHome).canonicalFile != eclipseGradleHome) { buildship.setProperty('eclipse.preferences.version', '1') buildship.setProperty('connection.gradle.user.home', eclipseGradleHome.absolutePath) buildshipPreferences.parentFile.mkdirs() buildshipPreferences.withOutputStream { buildship.store(it, - 'Generated by syncEclipseRunClasspaths; keep Eclipse and command-line caches aligned.') + 'Generated by syncEclipseRunClasspaths; keep Eclipse launch inputs on the Buildship cache.') } } File eclipseCache = new File(eclipseGradleHome, 'caches').canonicalFile diff --git a/gradle.properties b/gradle.properties index 44fa7df..92c72af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -48,7 +48,7 @@ mod_name=MMD OreSpawn # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=LGPL-2.1 # The mod version. See https://semver.org/ -mod_version=4.0.1 +mod_version=4.0.2 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/zone/moddev/mc/orespawn/client/OreSpawnWorldSettingsScreen.java b/src/main/java/zone/moddev/mc/orespawn/client/OreSpawnWorldSettingsScreen.java index b21f9a9..2e610c0 100644 --- a/src/main/java/zone/moddev/mc/orespawn/client/OreSpawnWorldSettingsScreen.java +++ b/src/main/java/zone/moddev/mc/orespawn/client/OreSpawnWorldSettingsScreen.java @@ -67,6 +67,7 @@ public OreSpawnWorldSettingsScreen(Screen parent, WorldGeologyProfile profile) { @Override protected void init() { + clearWidgetReferences(); OreSpawnScreenLayout.beginHelp(this); int contentWidth = Math.min(390, Math.max(310, this.width - 24)); columnWidth = (contentWidth - 5) / 2; @@ -142,7 +143,7 @@ contentWidth, BUTTON_HEIGHT, new TranslatableComponent("button.orespawn.help"), formationContinuityButton = addPresetButton(left, top + (row * rowIndex), "option.orespawn.formation_continuity", "tooltip.orespawn.formation_continuity", formationContinuity, value -> formationContinuity = value); - if (vanillaOresButton == null) vanillaOresButton = addVanillaOresButton(right, + if (fluids) vanillaOresButton = addVanillaOresButton(right, top + (row * rowIndex), columnWidth); rowIndex++; addRenderableWidget(OreSpawnScreenLayout.explainedButton(this, font, left, top + (row * rowIndex), @@ -169,6 +170,17 @@ contentWidth, BUTTON_HEIGHT, fluidEditorLabel(), button -> openFluidDeposits(), updateFormationControls(); } + private void clearWidgetReferences() { + geologyModeButton = null; + fluidDepositsButton = null; + vanillaOresButton = null; + horizontalSizeButton = null; + verticalThicknessButton = null; + wavinessButton = null; + edgeIrregularityButton = null; + formationContinuityButton = null; + } + private CycleButton addVanillaOresButton(int x, int y, int width) { return addRenderableWidget(CycleButton.onOffBuilder(manageVanillaOres) .withTooltip(value -> tooltip("tooltip.orespawn.manage_vanilla_ores")) diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 8bcc955..1f5bdc2 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -2,3 +2,4 @@ public-f net.minecraft.world.level.chunk.ChunkGenerator f_62137_ # biomeSource public-f net.minecraft.world.level.chunk.ChunkGenerator f_62138_ # runtimeBiomeSource public-f net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_188607_ # globalFluidPicker public-f net.minecraft.world.level.biome.Biome f_47438_ # generationSettings +public-f net.minecraft.world.level.levelgen.feature.configurations.SpringConfiguration f_68128_ # validBlocks From 0ec637757e2ac97070898c5e8bd05ab31bdce112 Mon Sep 17 00:00:00 2001 From: SkyBlase1978 Date: Tue, 28 Jul 2026 16:20:21 +0100 Subject: [PATCH 2/2] vanilla spring fix --- .../orespawn/worldgen/BakedGeomeConfig.java | 6 ++ .../mc/orespawn/worldgen/GeomeConfig.java | 1 + .../worldgen/VanillaSpringCompatibility.java | 56 ++++++++++++++++ .../VanillaSpringCompatibilityTest.java | 66 +++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 src/main/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibility.java create mode 100644 src/test/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibilityTest.java diff --git a/src/main/java/zone/moddev/mc/orespawn/worldgen/BakedGeomeConfig.java b/src/main/java/zone/moddev/mc/orespawn/worldgen/BakedGeomeConfig.java index a1f85a6..e9de578 100644 --- a/src/main/java/zone/moddev/mc/orespawn/worldgen/BakedGeomeConfig.java +++ b/src/main/java/zone/moddev/mc/orespawn/worldgen/BakedGeomeConfig.java @@ -183,6 +183,12 @@ public BlockState[] statesForFamily(RockFamily... families) { return result; } + void addRockBlocks(Set target) { + for (BlockState state : rockStates) { + target.add(state.getBlock()); + } + } + int geomeCount() { return geomes.length; } diff --git a/src/main/java/zone/moddev/mc/orespawn/worldgen/GeomeConfig.java b/src/main/java/zone/moddev/mc/orespawn/worldgen/GeomeConfig.java index ddca149..05fb49d 100644 --- a/src/main/java/zone/moddev/mc/orespawn/worldgen/GeomeConfig.java +++ b/src/main/java/zone/moddev/mc/orespawn/worldgen/GeomeConfig.java @@ -261,6 +261,7 @@ private static void bakeDimensions(JsonObject root) { usableTerrain.put(entry.getKey(), entry.getValue()); } } + VanillaSpringCompatibility.refresh(configs.get(Level.OVERWORLD)); bakedConfigs = Collections.unmodifiableMap(configs); terrainDimensions = Collections.unmodifiableMap(usableTerrain); bakedConfig = configs.get(Level.OVERWORLD); diff --git a/src/main/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibility.java b/src/main/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibility.java new file mode 100644 index 0000000..acec5a0 --- /dev/null +++ b/src/main/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibility.java @@ -0,0 +1,56 @@ +package zone.moddev.mc.orespawn.worldgen; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.data.worldgen.features.MiscOverworldFeatures; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.configurations.SpringConfiguration; + +final class VanillaSpringCompatibility { + private static final Map> ORIGINAL_HOSTS = new IdentityHashMap<>(); + + private VanillaSpringCompatibility() { + throw new IllegalAccessError("Not an instantiable class"); + } + + static synchronized void refresh(BakedGeomeConfig config) { + Set rocks = Collections.newSetFromMap(new IdentityHashMap<>()); + if (config != null) { + config.addRockBlocks(rocks); + } + refreshBlocks(rocks); + } + + static synchronized void refreshBlocks(Iterable rocks) { + update(MiscOverworldFeatures.SPRING_LAVA_OVERWORLD.value().config(), rocks); + update(MiscOverworldFeatures.SPRING_WATER.value().config(), rocks); + } + + private static void update(SpringConfiguration spring, Iterable rocks) { + HolderSet original = ORIGINAL_HOSTS.computeIfAbsent(spring, ignored -> spring.validBlocks); + spring.validBlocks = merge(original, rocks); + } + + static HolderSet merge(HolderSet original, Iterable additionalBlocks) { + List> holders = new ArrayList<>(original.size()); + Set seen = Collections.newSetFromMap(new IdentityHashMap<>()); + for (Holder holder : original) { + if (seen.add(holder.value())) { + holders.add(holder); + } + } + for (Block block : additionalBlocks) { + if (seen.add(block)) { + holders.add(block.builtInRegistryHolder()); + } + } + return HolderSet.direct(holders); + } +} diff --git a/src/test/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibilityTest.java b/src/test/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibilityTest.java new file mode 100644 index 0000000..731f1b5 --- /dev/null +++ b/src/test/java/zone/moddev/mc/orespawn/worldgen/VanillaSpringCompatibilityTest.java @@ -0,0 +1,66 @@ +package zone.moddev.mc.orespawn.worldgen; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import net.minecraft.core.HolderSet; +import net.minecraft.data.worldgen.features.MiscOverworldFeatures; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.feature.configurations.SpringConfiguration; + +class VanillaSpringCompatibilityTest { + @Test + void configuredRocksExtendVanillaSpringHostsWithoutDuplicates() { + HolderSet original = HolderSet.direct( + Blocks.STONE.builtInRegistryHolder(), + Blocks.DIRT.builtInRegistryHolder()); + + HolderSet expanded = VanillaSpringCompatibility.merge(original, + Arrays.asList(Blocks.STONE, Blocks.DIAMOND_BLOCK)); + + assertEquals(3, expanded.size()); + assertTrue(expanded.contains(Blocks.STONE.builtInRegistryHolder())); + assertTrue(expanded.contains(Blocks.DIRT.builtInRegistryHolder())); + assertTrue(expanded.contains(Blocks.DIAMOND_BLOCK.builtInRegistryHolder())); + } + + @Test + void emptyTerrainProfileRestoresVanillaSpringHosts() { + HolderSet original = HolderSet.direct( + Blocks.STONE.builtInRegistryHolder(), + Blocks.DIRT.builtInRegistryHolder()); + + HolderSet restored = VanillaSpringCompatibility.merge(original, Collections.emptyList()); + + assertEquals(2, restored.size()); + assertTrue(restored.contains(Blocks.STONE.builtInRegistryHolder())); + assertTrue(restored.contains(Blocks.DIRT.builtInRegistryHolder())); + } + + @Test + void refreshUpdatesOrdinaryOverworldSpringsAndRestoresThem() { + SpringConfiguration lava = MiscOverworldFeatures.SPRING_LAVA_OVERWORLD.value().config(); + SpringConfiguration water = MiscOverworldFeatures.SPRING_WATER.value().config(); + SpringConfiguration frozen = MiscOverworldFeatures.SPRING_LAVA_FROZEN.value().config(); + HolderSet frozenHosts = frozen.validBlocks; + + try { + VanillaSpringCompatibility.refreshBlocks(Collections.singleton(Blocks.DIAMOND_BLOCK)); + + assertTrue(lava.validBlocks.contains(Blocks.DIAMOND_BLOCK.builtInRegistryHolder())); + assertTrue(water.validBlocks.contains(Blocks.DIAMOND_BLOCK.builtInRegistryHolder())); + assertEquals(frozenHosts, frozen.validBlocks); + } finally { + VanillaSpringCompatibility.refreshBlocks(Collections.emptyList()); + } + + assertTrue(lava.validBlocks.contains(Blocks.STONE.builtInRegistryHolder())); + assertTrue(water.validBlocks.contains(Blocks.STONE.builtInRegistryHolder())); + } +}