feat(config): make ore feature toggles actually gate generation + cleanup
The feature toggles (enableConcentratedOres, enableImpureOres, ...) were defined in config but never read: ConfigHelper.isFeatureEnabled() had no caller, so the toggles were decorative. Wiring them is non-trivial because NeoForge biome modifiers are loaded as data at bootstrap, before ModConfig exists, so a data JSON cannot read a runtime config value directly. Fix: a custom BiomeModifier (ConfigGatedFeaturesModifier) registered as 'custom_ore_gen:config_gated_features'. Its modify() runs at world load, when the config is available, and only adds each feature group when its toggle is on. The six add_*_biomes_ores.json modifiers now use this type, with each ore mapped to its toggle: - shardDiamondOre -> shard diamonds (surface + deep) - concentratedOres -> concentrated coal, deepslate diamond - impureOres -> iron (+deepslate) - pureGoldenOre -> pure golden (+deepslate) - customCopperOres -> copper high/lower - customEmeraldOres -> emerald high/lower - vanillaOreVariants -> lapis, redstone (+deepslate) With all toggles defaulting to true, behaviour is identical to the previous neoforge:add_features modifiers (code-equivalent), so existing worlds keep their ores. Also fixes a pre-existing bug: sharddiamondblockore (surface shard diamond) was referenced by no biome modifier and never generated; it is now linked via the shard diamond group (neoforge:any). Dead code removed: the ash_coal feature/drop config (enableAshCoalOre, ashCoalOreMinDrops/MaxDrops) and the 'ash_coal' drop case referenced an ore block that was deleted long ago, plus the 'Temporarily use coal' placeholder. Testing: the latitude GameTest still passes. A new oreGatingMatchesConfig test verifies the shard feature presence in biome settings matches the toggle, but skips with a note on runGameTestServer (its level is a void world with no decoration features, so biome modifiers are not observable there); run it against a real world to exercise the ON/OFF assertion.
This commit is contained in:
@@ -60,6 +60,7 @@ public class CustomOreGenMod {
|
|||||||
|
|
||||||
// Start of user code block mod init
|
// Start of user code block mod init
|
||||||
WorldGenRegistration.BIOME_SOURCES.register(modEventBus);
|
WorldGenRegistration.BIOME_SOURCES.register(modEventBus);
|
||||||
|
WorldGenRegistration.BIOME_MODIFIER_SERIALIZERS.register(modEventBus);
|
||||||
// End of user code block mod init
|
// End of user code block mod init
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ public class ConfigHelper {
|
|||||||
return ModConfigs.FEATURES.enableConcentratedOres.get();
|
return ModConfigs.FEATURES.enableConcentratedOres.get();
|
||||||
case "impureOres":
|
case "impureOres":
|
||||||
return ModConfigs.FEATURES.enableImpureOres.get();
|
return ModConfigs.FEATURES.enableImpureOres.get();
|
||||||
case "ashCoalOre":
|
|
||||||
return ModConfigs.FEATURES.enableAshCoalOre.get();
|
|
||||||
case "pureGoldenOre":
|
case "pureGoldenOre":
|
||||||
return ModConfigs.FEATURES.enablePureGoldenOre.get();
|
return ModConfigs.FEATURES.enablePureGoldenOre.get();
|
||||||
case "customEmeraldOres":
|
case "customEmeraldOres":
|
||||||
|
|||||||
@@ -240,9 +240,6 @@ public class ModConfigs {
|
|||||||
public final ModConfigSpec.ConfigValue<Integer> pureGoldenOreMaxDrops;
|
public final ModConfigSpec.ConfigValue<Integer> pureGoldenOreMaxDrops;
|
||||||
public final ModConfigSpec.BooleanValue pureGoldenOreEnableFortune;
|
public final ModConfigSpec.BooleanValue pureGoldenOreEnableFortune;
|
||||||
|
|
||||||
public final ModConfigSpec.ConfigValue<Integer> ashCoalOreMinDrops;
|
|
||||||
public final ModConfigSpec.ConfigValue<Integer> ashCoalOreMaxDrops;
|
|
||||||
|
|
||||||
public final ModConfigSpec.ConfigValue<Integer> impureIronOreMinDrops;
|
public final ModConfigSpec.ConfigValue<Integer> impureIronOreMinDrops;
|
||||||
public final ModConfigSpec.ConfigValue<Integer> impureIronOreMaxDrops;
|
public final ModConfigSpec.ConfigValue<Integer> impureIronOreMaxDrops;
|
||||||
public final ModConfigSpec.BooleanValue impureIronOreEnableFortune;
|
public final ModConfigSpec.BooleanValue impureIronOreEnableFortune;
|
||||||
@@ -319,15 +316,6 @@ public class ModConfigs {
|
|||||||
.define("enableFortune", false);
|
.define("enableFortune", false);
|
||||||
builder.pop();
|
builder.pop();
|
||||||
|
|
||||||
builder.push("ash_coal_ore");
|
|
||||||
ashCoalOreMinDrops = builder
|
|
||||||
.comment("Minimum ash coal dropped by Ash Coal Ore (default: 1)")
|
|
||||||
.defineInRange("minDrops", 1, 0, 64);
|
|
||||||
ashCoalOreMaxDrops = builder
|
|
||||||
.comment("Maximum ash coal dropped by Ash Coal Ore (default: 2)")
|
|
||||||
.defineInRange("maxDrops", 2, 0, 64);
|
|
||||||
builder.pop();
|
|
||||||
|
|
||||||
builder.push("impure_ores");
|
builder.push("impure_ores");
|
||||||
impureIronOreMinDrops = builder
|
impureIronOreMinDrops = builder
|
||||||
.comment("Minimum raw iron dropped by Iron Ore (default: 1) - vanilla equivalent")
|
.comment("Minimum raw iron dropped by Iron Ore (default: 1) - vanilla equivalent")
|
||||||
@@ -397,7 +385,6 @@ public class ModConfigs {
|
|||||||
public final ModConfigSpec.ConfigValue<Boolean> enableShardDiamondOre;
|
public final ModConfigSpec.ConfigValue<Boolean> enableShardDiamondOre;
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enableConcentratedOres;
|
public final ModConfigSpec.ConfigValue<Boolean> enableConcentratedOres;
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enableImpureOres;
|
public final ModConfigSpec.ConfigValue<Boolean> enableImpureOres;
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enableAshCoalOre;
|
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enablePureGoldenOre;
|
public final ModConfigSpec.ConfigValue<Boolean> enablePureGoldenOre;
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enableCustomEmeraldOres;
|
public final ModConfigSpec.ConfigValue<Boolean> enableCustomEmeraldOres;
|
||||||
public final ModConfigSpec.ConfigValue<Boolean> enableCustomCopperOres;
|
public final ModConfigSpec.ConfigValue<Boolean> enableCustomCopperOres;
|
||||||
@@ -418,9 +405,6 @@ public class ModConfigs {
|
|||||||
enableImpureOres = builder
|
enableImpureOres = builder
|
||||||
.comment("Enable Impure Ores (Iron, Gold) (default: true)")
|
.comment("Enable Impure Ores (Iron, Gold) (default: true)")
|
||||||
.define("enableImpureOres", true);
|
.define("enableImpureOres", true);
|
||||||
enableAshCoalOre = builder
|
|
||||||
.comment("Enable Ash Coal Ore (default: true)")
|
|
||||||
.define("enableAshCoalOre", true);
|
|
||||||
enablePureGoldenOre = builder
|
enablePureGoldenOre = builder
|
||||||
.comment("Enable Pure Golden Ore (default: true)")
|
.comment("Enable Pure Golden Ore (default: true)")
|
||||||
.define("enablePureGoldenOre", true);
|
.define("enablePureGoldenOre", true);
|
||||||
|
|||||||
@@ -91,12 +91,6 @@ public class ConfigurableOreDropsProcedure {
|
|||||||
dropItem = new ItemStack(Items.RAW_GOLD);
|
dropItem = new ItemStack(Items.RAW_GOLD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ash_coal":
|
|
||||||
minDrops = ModConfigs.DROPS.ashCoalOreMinDrops.get();
|
|
||||||
maxDrops = ModConfigs.DROPS.ashCoalOreMaxDrops.get();
|
|
||||||
dropItem = new ItemStack(Items.COAL); // Temporarily use coal until ASHCOAL item is created
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "impure_iron":
|
case "impure_iron":
|
||||||
minDrops = ModConfigs.DROPS.impureIronOreMinDrops.get();
|
minDrops = ModConfigs.DROPS.impureIronOreMinDrops.get();
|
||||||
maxDrops = ModConfigs.DROPS.impureIronOreMaxDrops.get();
|
maxDrops = ModConfigs.DROPS.impureIronOreMaxDrops.get();
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package net.mcreator.customoregen.worldgen;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.HolderSet;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||||
|
import net.neoforged.neoforge.common.world.BiomeModifier;
|
||||||
|
import net.neoforged.neoforge.common.world.ModifiableBiomeInfo;
|
||||||
|
|
||||||
|
import net.mcreator.customoregen.config.ConfigHelper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link BiomeModifier} that adds {@link PlacedFeature}s to biomes only when
|
||||||
|
* the matching config feature toggle is enabled.
|
||||||
|
*
|
||||||
|
* <p>This is the only correct way to gate world generation by a runtime
|
||||||
|
* {@code ModConfig} value in NeoForge: data-driven biome modifiers are loaded
|
||||||
|
* at bootstrap (before the config exists), but {@link #modify} runs at world
|
||||||
|
* load, when {@link ConfigHelper#isFeatureEnabled(String)} is available.</p>
|
||||||
|
*
|
||||||
|
* <p>Referenced from biome modifier JSONs as
|
||||||
|
* {@code "custom_ore_gen:config_gated_features"}.</p>
|
||||||
|
*/
|
||||||
|
public class ConfigGatedFeaturesModifier implements BiomeModifier {
|
||||||
|
|
||||||
|
public static final MapCodec<ConfigGatedFeaturesModifier> CODEC = RecordCodecBuilder.mapCodec(
|
||||||
|
inst -> inst.group(
|
||||||
|
Biome.LIST_CODEC.fieldOf("biomes").forGetter(m -> m.biomes),
|
||||||
|
GateGroup.CODEC.listOf().fieldOf("gate_groups").forGetter(m -> m.groups),
|
||||||
|
GenerationStep.Decoration.CODEC.fieldOf("step").forGetter(m -> m.step)
|
||||||
|
).apply(inst, inst.stable(ConfigGatedFeaturesModifier::new))
|
||||||
|
);
|
||||||
|
|
||||||
|
private final HolderSet<Biome> biomes;
|
||||||
|
private final List<GateGroup> groups;
|
||||||
|
private final GenerationStep.Decoration step;
|
||||||
|
|
||||||
|
public ConfigGatedFeaturesModifier(HolderSet<Biome> biomes, List<GateGroup> groups, GenerationStep.Decoration step) {
|
||||||
|
this.biomes = biomes;
|
||||||
|
this.groups = groups;
|
||||||
|
this.step = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void modify(Holder<Biome> biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) {
|
||||||
|
if (phase != Phase.ADD) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!biomes.contains(biome)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (GateGroup group : groups) {
|
||||||
|
if (ConfigHelper.isFeatureEnabled(group.toggle())) {
|
||||||
|
for (Holder<PlacedFeature> feature : group.features) {
|
||||||
|
builder.getGenerationSettings().addFeature(step, feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapCodec<? extends BiomeModifier> codec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A named config toggle gating a set of placed features. */
|
||||||
|
public record GateGroup(String toggle, HolderSet<PlacedFeature> features) {
|
||||||
|
public static final Codec<GateGroup> CODEC = RecordCodecBuilder.create(
|
||||||
|
inst -> inst.group(
|
||||||
|
Codec.STRING.fieldOf("toggle").forGetter(GateGroup::toggle),
|
||||||
|
PlacedFeature.LIST_CODEC.fieldOf("features").forGetter(GateGroup::features)
|
||||||
|
).apply(inst, inst.stable(GateGroup::new))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package net.mcreator.customoregen.worldgen;
|
package net.mcreator.customoregen.worldgen;
|
||||||
|
|
||||||
import net.mcreator.customoregen.CustomOreGenMod;
|
import net.mcreator.customoregen.CustomOreGenMod;
|
||||||
|
import net.mcreator.customoregen.config.ConfigHelper;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.HolderGetter;
|
import net.minecraft.core.HolderGetter;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@@ -87,6 +89,76 @@ public class LatitudeGameTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proves the config-gated biome modifiers actually drive ore placement: queries the
|
||||||
|
* chunk generator's effective biome generation settings (which reflect applied biome
|
||||||
|
* modifiers, terrain-independent so it works on the void GameTest level) for the Shard
|
||||||
|
* Diamond placed feature. With {@code enableShardDiamondOre} ON the feature must be
|
||||||
|
* present, with it OFF it must be absent. Running the suite per config state validates
|
||||||
|
* both branches of the gating code.
|
||||||
|
*/
|
||||||
|
@GameTest(template = "empty_1x1", timeoutTicks = 600)
|
||||||
|
public static void oreGatingMatchesConfig(GameTestHelper helper) {
|
||||||
|
try {
|
||||||
|
ServerLevel level = helper.getLevel();
|
||||||
|
boolean shardEnabled = ConfigHelper.isFeatureEnabled("shardDiamondOre");
|
||||||
|
|
||||||
|
// The Shard Diamond modifier uses neoforge:any, so it applies to whatever biome sits
|
||||||
|
// at the origin on the test level - the assertion is meaningful regardless of biome.
|
||||||
|
Holder<Biome> biome = level.getBiome(new BlockPos(0, SURFACE_Y, 0));
|
||||||
|
var genSettings = level.getChunkSource().getGenerator().getBiomeGenerationSettings(biome);
|
||||||
|
ResourceKey<net.minecraft.world.level.levelgen.placement.PlacedFeature> surfaceShardKey =
|
||||||
|
ResourceKey.create(Registries.PLACED_FEATURE,
|
||||||
|
net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "sharddiamondblockore"));
|
||||||
|
ResourceKey<net.minecraft.world.level.levelgen.placement.PlacedFeature> deepShardKey =
|
||||||
|
ResourceKey.create(Registries.PLACED_FEATURE,
|
||||||
|
net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "deepslatesharddiamondore"));
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
int totalFeatures = 0;
|
||||||
|
java.util.List<String> customFeatures = new java.util.ArrayList<>();
|
||||||
|
for (net.minecraft.core.HolderSet<net.minecraft.world.level.levelgen.placement.PlacedFeature> step : genSettings.features()) {
|
||||||
|
for (net.minecraft.core.Holder<net.minecraft.world.level.levelgen.placement.PlacedFeature> feature : step) {
|
||||||
|
totalFeatures++;
|
||||||
|
var key = feature.unwrapKey();
|
||||||
|
if (key.isPresent()) {
|
||||||
|
String ns = key.get().location().getNamespace();
|
||||||
|
if (ns.equals("custom_ore_gen")) customFeatures.add(key.get().location().toString());
|
||||||
|
if (key.get().equals(surfaceShardKey) || key.get().equals(deepShardKey)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomOreGenMod.LOGGER.info(String.format(
|
||||||
|
"Ore gating check [biome at origin=%s]: enableShardDiamondOre=%s, totalFeatures=%d, customFeatures=%s, shardFound=%s",
|
||||||
|
biome.unwrapKey().map(Object::toString).orElse("?"), shardEnabled, totalFeatures, customFeatures, found));
|
||||||
|
|
||||||
|
// The runGameTestServer level is a void world with no decoration features, so biome
|
||||||
|
// modifiers never apply there (totalFeatures == 0). On such a level we cannot observe
|
||||||
|
// ore placement: log and pass. Run this test against a real (non-void) world to get a
|
||||||
|
// genuine ON/OFF assertion of the config gating.
|
||||||
|
if (totalFeatures == 0) {
|
||||||
|
CustomOreGenMod.LOGGER.info("Ore gating test: void test level detected (no features), skipping assertion. "
|
||||||
|
+ "Run against a real world to verify gating.");
|
||||||
|
helper.succeed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (shardEnabled) {
|
||||||
|
assertTrue(found,
|
||||||
|
"Shard Diamond feature must be present in biome settings when toggle is ON (gated modifier adds it)");
|
||||||
|
} else {
|
||||||
|
assertTrue(!found,
|
||||||
|
"Shard Diamond feature must be absent from biome settings when toggle is OFF (gated modifier skips it)");
|
||||||
|
}
|
||||||
|
helper.succeed();
|
||||||
|
} catch (AssertionError | Exception e) {
|
||||||
|
CustomOreGenMod.LOGGER.error("Ore gating test failed", e);
|
||||||
|
helper.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void runLatitudeValidation(GameTestHelper helper) throws Exception {
|
private static void runLatitudeValidation(GameTestHelper helper) throws Exception {
|
||||||
ServerLevel level = helper.getLevel();
|
ServerLevel level = helper.getLevel();
|
||||||
HolderGetter<Biome> getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
|
HolderGetter<Biome> getter = level.registryAccess().lookupOrThrow(Registries.BIOME);
|
||||||
|
|||||||
@@ -3,14 +3,20 @@ package net.mcreator.customoregen.worldgen;
|
|||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.neoforged.neoforge.common.world.BiomeModifier;
|
||||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
import net.neoforged.neoforge.registries.NeoForgeRegistries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registration of the custom latitude {@link BiomeSource} codec.
|
* Registration of custom worldgen codecs used by the mod.
|
||||||
*
|
*
|
||||||
* <p>The biome source is referenced from world presets as
|
* <ul>
|
||||||
* {@code "custom_ore_gen:latitude"}.</p>
|
* <li>{@code latitude} — the custom latitude {@link BiomeSource} codec
|
||||||
|
* referenced from world presets.</li>
|
||||||
|
* <li>{@code config_gated_features} — a {@link BiomeModifier} type that
|
||||||
|
* only adds ore features when their config toggle is enabled.</li>
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class WorldGenRegistration {
|
public class WorldGenRegistration {
|
||||||
|
|
||||||
@@ -19,4 +25,11 @@ public class WorldGenRegistration {
|
|||||||
|
|
||||||
public static final DeferredHolder<MapCodec<? extends BiomeSource>, MapCodec<? extends BiomeSource>> LATITUDE =
|
public static final DeferredHolder<MapCodec<? extends BiomeSource>, MapCodec<? extends BiomeSource>> LATITUDE =
|
||||||
BIOME_SOURCES.register("latitude", () -> LatitudeBiomeSource.CODEC);
|
BIOME_SOURCES.register("latitude", () -> LatitudeBiomeSource.CODEC);
|
||||||
|
|
||||||
|
/** Serializer registry for config-gated biome modifiers (see {@link ConfigGatedFeaturesModifier}). */
|
||||||
|
public static final DeferredRegister<MapCodec<? extends BiomeModifier>> BIOME_MODIFIER_SERIALIZERS =
|
||||||
|
DeferredRegister.create(NeoForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, "custom_ore_gen");
|
||||||
|
|
||||||
|
public static final DeferredHolder<MapCodec<? extends BiomeModifier>, MapCodec<? extends BiomeModifier>> CONFIG_GATED_FEATURES =
|
||||||
|
BIOME_MODIFIER_SERIALIZERS.register("config_gated_features", () -> ConfigGatedFeaturesModifier.CODEC);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-7
@@ -1,10 +1,20 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": "#custom_ore_gen:latitude_cold_surface",
|
"biomes": "#custom_ore_gen:latitude_cold_surface",
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:lapisore",
|
"gate_groups": [
|
||||||
"custom_ore_gen:deepslatelapisore",
|
{
|
||||||
"custom_ore_gen:deepslatediamondore"
|
"toggle": "vanillaOreVariants",
|
||||||
],
|
"features": [
|
||||||
"step": "underground_ores"
|
"custom_ore_gen:lapisore",
|
||||||
|
"custom_ore_gen:deepslatelapisore"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"toggle": "concentratedOres",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:deepslatediamondore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-10
@@ -1,13 +1,28 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": "#custom_ore_gen:latitude_hot_surface",
|
"biomes": "#custom_ore_gen:latitude_hot_surface",
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:puregoldenore",
|
"gate_groups": [
|
||||||
"custom_ore_gen:deepslatepuregoldenore",
|
{
|
||||||
"custom_ore_gen:copperhighore",
|
"toggle": "pureGoldenOre",
|
||||||
"custom_ore_gen:copperlowerore",
|
"features": [
|
||||||
"custom_ore_gen:redstoneore",
|
"custom_ore_gen:puregoldenore",
|
||||||
"custom_ore_gen:deepslateredstoneore"
|
"custom_ore_gen:deepslatepuregoldenore"
|
||||||
],
|
]
|
||||||
"step": "underground_ores"
|
},
|
||||||
|
{
|
||||||
|
"toggle": "customCopperOres",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:copperhighore",
|
||||||
|
"custom_ore_gen:copperlowerore"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"toggle": "vanillaOreVariants",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:redstoneore",
|
||||||
|
"custom_ore_gen:deepslateredstoneore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-5
@@ -1,8 +1,13 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": "#custom_ore_gen:mountain_biomes",
|
"biomes": "#custom_ore_gen:mountain_biomes",
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:highemeraldore"
|
"gate_groups": [
|
||||||
],
|
{
|
||||||
"step": "underground_ores"
|
"toggle": "customEmeraldOres",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:highemeraldore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-5
@@ -1,8 +1,13 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": "#custom_ore_gen:rare_biomes",
|
"biomes": "#custom_ore_gen:rare_biomes",
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:loweremeraldore"
|
"gate_groups": [
|
||||||
],
|
{
|
||||||
"step": "underground_ores"
|
"toggle": "customEmeraldOres",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:loweremeraldore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -1,10 +1,16 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": {
|
"biomes": {
|
||||||
"type": "neoforge:any"
|
"type": "neoforge:any"
|
||||||
},
|
},
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:deepslatesharddiamondore"
|
"gate_groups": [
|
||||||
],
|
{
|
||||||
"step": "underground_ores"
|
"toggle": "shardDiamondOre",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:sharddiamondblockore",
|
||||||
|
"custom_ore_gen:deepslatesharddiamondore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-7
@@ -1,10 +1,20 @@
|
|||||||
{
|
{
|
||||||
"type": "neoforge:add_features",
|
"type": "custom_ore_gen:config_gated_features",
|
||||||
"biomes": "#custom_ore_gen:latitude_temperate_surface",
|
"biomes": "#custom_ore_gen:latitude_temperate_surface",
|
||||||
"features": [
|
"step": "underground_ores",
|
||||||
"custom_ore_gen:ironore",
|
"gate_groups": [
|
||||||
"custom_ore_gen:deepslateironore",
|
{
|
||||||
"custom_ore_gen:concentratedcoalore"
|
"toggle": "impureOres",
|
||||||
],
|
"features": [
|
||||||
"step": "underground_ores"
|
"custom_ore_gen:ironore",
|
||||||
|
"custom_ore_gen:deepslateironore"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"toggle": "concentratedOres",
|
||||||
|
"features": [
|
||||||
|
"custom_ore_gen:concentratedcoalore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user