Author SHA1 Message Date
Roman 401674c90b fix: corrections complètes + version 4.5
- Enregistre la config Forge (registerConfig) : bug bloquant, la config n'était jamais chargée
- Worldgen latitude: résolution des biomes via le registre du serveur (ServerLifecycleHooks)
  car ForgeRegistries.BIOMES est vide sur les threads de génération (crash IndexOutOfBounds)
- Filets de sécurité anti-crash dans LatitudeBiomeSource (select/fallback), collectPossibleBiomes paresseux
- Câble la config worldgen (temperatureBandWidth, biomeSize, enableBOP/Oceans, spawnSearchRadius, welcome)
- OreexperienceProcedure: supprime la double casse, XP depuis la config
- Handlers spawn/welcome par joueur (suppression des static boolean)
- Outils Shard Diamond câblés sur la config (durabilité/vitesse) via ConfigHelper rendu sûr
- Supprime le code mort (ConfigurableOreDropsProcedure, helpers inutilisés, config non câblable)
- Corrige le nom 'Custom Ore Gem' -> 'Custom Ore Gen'
2026-07-31 20:11:27 +00:00
root ee1b203a7f feat: Add latitude-based world generation with extra-large biomes
- Custom BiomeSource distributes biomes by Z coordinate (north=cold, south=hot)
- Extra-large biomes (~3000 blocks, 8x vanilla)
- Underground biomes follow surface temperature logic
- Always spawn in plains near Z=0
- Welcome message explaining latitude mechanics
- Uses amplified noise settings for higher mountains
- BOP biomes integrated in temperature bands
- Selectable as 'Large Latitude' world type in world creation
- New config section 'world_generation'
- Version bumped to 2.2.0
2026-05-13 10:05:09 +00:00
18 changed files with 615 additions and 208 deletions
+9
View File
@@ -0,0 +1,9 @@
.gradle/
build/
run/
*.iml
.idea/
*.class
*.log
*.lock
*.bin
+1 -1
View File
@@ -3,7 +3,7 @@ plugins {
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
} }
version = '2.1.12' version = '4.5'
group = 'com.aulyrius.custom_ore_gen' group = 'com.aulyrius.custom_ore_gen'
archivesBaseName = 'custom_ore_gen' archivesBaseName = 'custom_ore_gen'
Vendored Regular → Executable
View File
@@ -8,6 +8,8 @@ import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.fml.util.thread.SidedThreadGroups; import net.minecraftforge.fml.util.thread.SidedThreadGroups;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
@@ -20,6 +22,8 @@ import net.minecraft.network.FriendlyByteBuf;
import net.mcreator.customoregen.init.CustomOreGenModTabs; import net.mcreator.customoregen.init.CustomOreGenModTabs;
import net.mcreator.customoregen.init.CustomOreGenModItems; import net.mcreator.customoregen.init.CustomOreGenModItems;
import net.mcreator.customoregen.init.CustomOreGenModBlocks; import net.mcreator.customoregen.init.CustomOreGenModBlocks;
import net.mcreator.customoregen.config.ModConfigs;
import net.mcreator.customoregen.worldgen.WorldGenRegistration;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.function.Function; import java.util.function.Function;
@@ -41,12 +45,17 @@ public class CustomOreGenMod {
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
// Enregistre la configuration COMMON (crée/charge custom_ore_gen.toml)
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModConfigs.SPEC, "custom_ore_gen.toml");
CustomOreGenModBlocks.REGISTRY.register(bus); CustomOreGenModBlocks.REGISTRY.register(bus);
CustomOreGenModItems.REGISTRY.register(bus); CustomOreGenModItems.REGISTRY.register(bus);
CustomOreGenModTabs.REGISTRY.register(bus); CustomOreGenModTabs.REGISTRY.register(bus);
WorldGenRegistration.BIOME_SOURCES.register(bus);
// Start of user code block mod init // Start of user code block mod init
// End of user code block mod init // End of user code block mod init
} }
@@ -1,35 +1,22 @@
package net.mcreator.customoregen.config; package net.mcreator.customoregen.config;
import net.minecraftforge.fml.ModList; /**
* Accès sûr aux valeurs de configuration du mod.
* <p>
* Chaque méthode retourne une valeur par défaut si la configuration n'est pas
* encore chargée (par ex. pendant la construction des objets enregistrés),
* évitant ainsi tout plantage lié à un accès prématuré au {@code ForgeConfigSpec}.
*/
public class ConfigHelper { public class ConfigHelper {
// Helper method to safely access config values
public static boolean isFeatureEnabled(String featureName) { private static boolean loaded() {
switch (featureName) { return ModConfigs.SPEC.isLoaded();
case "shardDiamondTools":
return ModConfigs.FEATURES.enableShardDiamondTools.get();
case "shardDiamondOre":
return ModConfigs.FEATURES.enableShardDiamondOre.get();
case "concentratedOres":
return ModConfigs.FEATURES.enableConcentratedOres.get();
case "impureOres":
return ModConfigs.FEATURES.enableImpureOres.get();
case "ashCoalOre":
return ModConfigs.FEATURES.enableAshCoalOre.get();
case "pureGoldenOre":
return ModConfigs.FEATURES.enablePureGoldenOre.get();
case "customEmeraldOres":
return ModConfigs.FEATURES.enableCustomEmeraldOres.get();
case "customCopperOres":
return ModConfigs.FEATURES.enableCustomCopperOres.get();
case "vanillaOreVariants":
return ModConfigs.FEATURES.enableVanillaOreVariants.get();
default:
return true;
}
} }
/** Durabilité de l'outil Shard Diamond concerné (par défaut 200). */
public static int getShardDiamondToolDurability(String toolType) { public static int getShardDiamondToolDurability(String toolType) {
if (!loaded())
return 200;
switch (toolType) { switch (toolType) {
case "pickaxe": case "pickaxe":
return ModConfigs.TOOL_STATS.shardDiamondPickaxeDurability.get(); return ModConfigs.TOOL_STATS.shardDiamondPickaxeDurability.get();
@@ -42,7 +29,10 @@ public class ConfigHelper {
} }
} }
/** Vitesse de minage de l'outil Shard Diamond concerné. */
public static float getShardDiamondToolSpeed(String toolType) { public static float getShardDiamondToolSpeed(String toolType) {
if (!loaded())
return defaultSpeed(toolType);
switch (toolType) { switch (toolType) {
case "pickaxe": case "pickaxe":
return ModConfigs.TOOL_STATS.shardDiamondPickaxeSpeed.get().floatValue(); return ModConfigs.TOOL_STATS.shardDiamondPickaxeSpeed.get().floatValue();
@@ -55,16 +45,7 @@ public class ConfigHelper {
} }
} }
public static int getShardDiamondToolDamage(String toolType) { private static float defaultSpeed(String toolType) {
switch (toolType) { return "shovel".equals(toolType) ? 4.0f : 7.0f;
case "pickaxe":
return ModConfigs.TOOL_STATS.shardDiamondPickaxeAttackDamage.get();
case "axe":
return ModConfigs.TOOL_STATS.shardDiamondAxeAttackDamage.get();
case "shovel":
return ModConfigs.TOOL_STATS.shardDiamondShovelAttackDamage.get();
default:
return 1;
}
} }
} }
@@ -10,14 +10,16 @@ public class ModConfigs {
public static final ToolStatsConfig TOOL_STATS; public static final ToolStatsConfig TOOL_STATS;
public static final DropsConfig DROPS; public static final DropsConfig DROPS;
public static final FeatureToggleConfig FEATURES; public static final FeatureToggleConfig FEATURES;
public static final WorldGenConfig WORLD_GEN;
static { static {
BUILDER.push("Custom Ore Gem Configuration"); BUILDER.push("Custom Ore Gen Configuration");
ORE_GEN = new OreGenConfig(BUILDER); ORE_GEN = new OreGenConfig(BUILDER);
TOOL_STATS = new ToolStatsConfig(BUILDER); TOOL_STATS = new ToolStatsConfig(BUILDER);
DROPS = new DropsConfig(BUILDER); DROPS = new DropsConfig(BUILDER);
FEATURES = new FeatureToggleConfig(BUILDER); FEATURES = new FeatureToggleConfig(BUILDER);
WORLD_GEN = new WorldGenConfig(BUILDER);
BUILDER.pop(); BUILDER.pop();
SPEC = BUILDER.build(); SPEC = BUILDER.build();
@@ -128,15 +130,12 @@ public class ModConfigs {
public static class ToolStatsConfig { public static class ToolStatsConfig {
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondPickaxeDurability; public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondPickaxeDurability;
public final ForgeConfigSpec.DoubleValue shardDiamondPickaxeSpeed; public final ForgeConfigSpec.DoubleValue shardDiamondPickaxeSpeed;
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondPickaxeAttackDamage;
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondAxeDurability; public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondAxeDurability;
public final ForgeConfigSpec.DoubleValue shardDiamondAxeSpeed; public final ForgeConfigSpec.DoubleValue shardDiamondAxeSpeed;
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondAxeAttackDamage;
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondShovelDurability; public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondShovelDurability;
public final ForgeConfigSpec.DoubleValue shardDiamondShovelSpeed; public final ForgeConfigSpec.DoubleValue shardDiamondShovelSpeed;
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondShovelAttackDamage;
public ToolStatsConfig(ForgeConfigSpec.Builder builder) { public ToolStatsConfig(ForgeConfigSpec.Builder builder) {
builder.push("tool_stats"); builder.push("tool_stats");
@@ -148,9 +147,6 @@ public class ModConfigs {
shardDiamondPickaxeSpeed = builder shardDiamondPickaxeSpeed = builder
.comment("Mining speed of Shard Diamond Pickaxe (default: 7.0)") .comment("Mining speed of Shard Diamond Pickaxe (default: 7.0)")
.defineInRange("pickaxeSpeed", 7.0, 0.1, 20.0); .defineInRange("pickaxeSpeed", 7.0, 0.1, 20.0);
shardDiamondPickaxeAttackDamage = builder
.comment("Attack damage of Shard Diamond Pickaxe (default: 1)")
.defineInRange("pickaxeAttackDamage", 1, 0, 20);
shardDiamondAxeDurability = builder shardDiamondAxeDurability = builder
.comment("Durability of Shard Diamond Axe (default: 200)") .comment("Durability of Shard Diamond Axe (default: 200)")
@@ -158,9 +154,6 @@ public class ModConfigs {
shardDiamondAxeSpeed = builder shardDiamondAxeSpeed = builder
.comment("Mining speed of Shard Diamond Axe (default: 7.0)") .comment("Mining speed of Shard Diamond Axe (default: 7.0)")
.defineInRange("axeSpeed", 7.0, 0.1, 20.0); .defineInRange("axeSpeed", 7.0, 0.1, 20.0);
shardDiamondAxeAttackDamage = builder
.comment("Attack damage of Shard Diamond Axe (default: 6)")
.defineInRange("axeAttackDamage", 6, 0, 20);
shardDiamondShovelDurability = builder shardDiamondShovelDurability = builder
.comment("Durability of Shard Diamond Shovel (default: 200)") .comment("Durability of Shard Diamond Shovel (default: 200)")
@@ -168,9 +161,6 @@ public class ModConfigs {
shardDiamondShovelSpeed = builder shardDiamondShovelSpeed = builder
.comment("Mining speed of Shard Diamond Shovel (default: 4.0)") .comment("Mining speed of Shard Diamond Shovel (default: 4.0)")
.defineInRange("shovelSpeed", 4.0, 0.1, 20.0); .defineInRange("shovelSpeed", 4.0, 0.1, 20.0);
shardDiamondShovelAttackDamage = builder
.comment("Attack damage of Shard Diamond Shovel (default: 2)")
.defineInRange("shovelAttackDamage", 2, 0, 20);
builder.pop(); builder.pop();
builder.pop(); builder.pop();
@@ -327,4 +317,38 @@ public class ModConfigs {
builder.pop(); builder.pop();
} }
} }
public static class WorldGenConfig {
public final ForgeConfigSpec.ConfigValue<Integer> biomeSize;
public final ForgeConfigSpec.ConfigValue<Integer> temperatureBandWidth;
public final ForgeConfigSpec.ConfigValue<Boolean> enableBOPBiomes;
public final ForgeConfigSpec.ConfigValue<Boolean> enableOceans;
public final ForgeConfigSpec.ConfigValue<Boolean> enableWelcomeMessage;
public final ForgeConfigSpec.ConfigValue<Integer> spawnSearchRadius;
public WorldGenConfig(ForgeConfigSpec.Builder builder) {
builder.push("world_generation");
biomeSize = builder
.comment("Individual biome size in blocks (default: 3000)")
.defineInRange("biomeSize", 3000, 500, 20000);
temperatureBandWidth = builder
.comment("Width of each temperature band in blocks (default: 4000)")
.defineInRange("temperatureBandWidth", 4000, 1000, 50000);
enableBOPBiomes = builder
.comment("Include Biomes O' Plenty biomes in temperature bands (default: true)")
.define("enableBOPBiomes", true);
enableOceans = builder
.comment("Generate oceans by latitude band (default: true)")
.define("enableOceans", true);
enableWelcomeMessage = builder
.comment("Show welcome message about latitude mechanics on first join (default: true)")
.define("enableWelcomeMessage", true);
spawnSearchRadius = builder
.comment("Radius to search for plains biome at spawn (default: 100)")
.defineInRange("spawnSearchRadius", 100, 10, 1000);
builder.pop();
}
}
} }
@@ -7,16 +7,17 @@ import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.mcreator.customoregen.init.CustomOreGenModItems; import net.mcreator.customoregen.init.CustomOreGenModItems;
import net.mcreator.customoregen.config.ConfigHelper;
public class SharddiamondaxeItem extends AxeItem { public class SharddiamondaxeItem extends AxeItem {
public SharddiamondaxeItem() { public SharddiamondaxeItem() {
super(new Tier() { super(new Tier() {
public int getUses() { public int getUses() {
return 200; return ConfigHelper.getShardDiamondToolDurability("axe");
} }
public float getSpeed() { public float getSpeed() {
return 7f; return ConfigHelper.getShardDiamondToolSpeed("axe");
} }
public float getAttackDamageBonus() { public float getAttackDamageBonus() {
@@ -8,16 +8,17 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.mcreator.customoregen.init.CustomOreGenModItems; import net.mcreator.customoregen.init.CustomOreGenModItems;
import net.mcreator.customoregen.config.ConfigHelper;
public class SharddiamondpickaxeItem extends PickaxeItem { public class SharddiamondpickaxeItem extends PickaxeItem {
public SharddiamondpickaxeItem() { public SharddiamondpickaxeItem() {
super(new Tier() { super(new Tier() {
public int getUses() { public int getUses() {
return 200; // Hardcoded - config not loaded yet return ConfigHelper.getShardDiamondToolDurability("pickaxe");
} }
public float getSpeed() { public float getSpeed() {
return 7f; return ConfigHelper.getShardDiamondToolSpeed("pickaxe");
} }
public float getAttackDamageBonus() { public float getAttackDamageBonus() {
@@ -8,16 +8,17 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.mcreator.customoregen.init.CustomOreGenModItems; import net.mcreator.customoregen.init.CustomOreGenModItems;
import net.mcreator.customoregen.config.ConfigHelper;
public class SharddiamondshovelItem extends ShovelItem { public class SharddiamondshovelItem extends ShovelItem {
public SharddiamondshovelItem() { public SharddiamondshovelItem() {
super(new Tier() { super(new Tier() {
public int getUses() { public int getUses() {
return 200; return ConfigHelper.getShardDiamondToolDurability("shovel");
} }
public float getSpeed() { public float getSpeed() {
return 4f; return ConfigHelper.getShardDiamondToolSpeed("shovel");
} }
public float getAttackDamageBonus() { public float getAttackDamageBonus() {
@@ -1,143 +0,0 @@
package net.mcreator.customoregen.procedures;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.ExperienceOrb;
import net.mcreator.customoregen.config.ModConfigs;
import net.mcreator.customoregen.init.CustomOreGenModItems;
import java.util.Random;
public class ConfigurableOreDropsProcedure {
public static void execute(LevelAccessor world, double x, double y, double z, Entity entity, String oreType) {
if (world.isClientSide())
return;
Random random = new Random();
int fortuneLevel = 0;
boolean silkTouch = false;
// Get fortune and silk touch from the tool if mining by player
if (entity instanceof Player) {
Player player = (Player) entity;
ItemStack mainHandItem = player.getMainHandItem();
fortuneLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, mainHandItem);
silkTouch = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, mainHandItem) > 0;
}
// If silk touch, drop the block itself and return
if (silkTouch) {
return; // Let vanilla handle silk touch
}
int minDrops = 1;
int maxDrops = 2;
boolean enableFortune = true;
ItemStack dropItem = ItemStack.EMPTY;
// Configure drops based on ore type
switch (oreType) {
case "shard_diamond":
minDrops = ModConfigs.DROPS.shardDiamondOreMinDrops.get();
maxDrops = ModConfigs.DROPS.shardDiamondOreMaxDrops.get();
enableFortune = ModConfigs.DROPS.shardDiamondOreEnableFortune.get();
dropItem = new ItemStack(CustomOreGenModItems.DIAMONDSHARD.get());
break;
case "concentrated_diamond":
minDrops = ModConfigs.DROPS.concentratedDiamondOreMinDrops.get();
maxDrops = ModConfigs.DROPS.concentratedDiamondOreMaxDrops.get();
enableFortune = ModConfigs.DROPS.concentratedDiamondOreEnableFortune.get();
dropItem = new ItemStack(Items.DIAMOND);
break;
case "concentrated_coal":
minDrops = ModConfigs.DROPS.concentratedCoalOreMinDrops.get();
maxDrops = ModConfigs.DROPS.concentratedCoalOreMaxDrops.get();
dropItem = new ItemStack(Items.COAL);
break;
case "pure_golden":
minDrops = ModConfigs.DROPS.pureGoldenOreMinDrops.get();
maxDrops = ModConfigs.DROPS.pureGoldenOreMaxDrops.get();
dropItem = new ItemStack(Items.GOLD_NUGGET);
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":
minDrops = ModConfigs.DROPS.impureIronOreMinDrops.get();
maxDrops = ModConfigs.DROPS.impureIronOreMaxDrops.get();
dropItem = new ItemStack(Items.IRON_NUGGET); // Use iron nugget until IMPUREIRON item is created
break;
case "impure_gold":
minDrops = ModConfigs.DROPS.impureGoldOreMinDrops.get();
maxDrops = ModConfigs.DROPS.impureGoldOreMaxDrops.get();
dropItem = new ItemStack(Items.RAW_GOLD);
break;
default:
return;
}
// Calculate drops
int dropCount = minDrops + random.nextInt(maxDrops - minDrops + 1);
// Apply fortune if enabled
if (enableFortune && fortuneLevel > 0) {
int fortuneBonus = random.nextInt(fortuneLevel + 2) - 1;
if (fortuneBonus < 0)
fortuneBonus = 0;
dropCount += fortuneBonus;
}
// Drop the items
if (!dropItem.isEmpty() && dropCount > 0) {
dropItem.setCount(dropCount);
if (world instanceof ServerLevel) {
ItemEntity itemEntity = new ItemEntity(
(ServerLevel) world,
x + 0.5, y + 0.5, z + 0.5,
dropItem
);
itemEntity.setDefaultPickUpDelay();
((ServerLevel) world).addFreshEntity(itemEntity);
}
}
// Drop experience if configured
int expAmount = ModConfigs.DROPS.oreExperienceDrops.get();
if (expAmount > 0 && entity instanceof Player) {
ExperienceOrb expOrb = new ExperienceOrb(
(ServerLevel) world,
x + 0.5, y + 0.5, z + 0.5,
expAmount
);
((ServerLevel) world).addFreshEntity(expOrb);
}
}
}
@@ -8,16 +8,36 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ExperienceOrb; import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.core.BlockPos;
import net.mcreator.customoregen.config.ModConfigs;
public class OreexperienceProcedure { public class OreexperienceProcedure {
/**
* Ajoute de l'expérience lors de la casse d'un minerai personnalisé.
* <p>
* Ne recasse PAS le bloc : le bloc est déjà détruit par
* {@code onDestroyedByPlayer} (qui appelle {@code super} et génère les
* drops via la loot table). Cette procédure se contente d'ajouter l'orbe
* d'XP, en respectant Silk Touch et la valeur de configuration.
*/
public static void execute(LevelAccessor world, double x, double y, double z, Entity entity) { public static void execute(LevelAccessor world, double x, double y, double z, Entity entity) {
// Uniquement côté serveur : l'XP ne doit pas être spawnée côté client.
if (world.isClientSide())
return;
if (entity == null) if (entity == null)
return; return;
if (!(EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, (entity instanceof LivingEntity _livEnt ? _livEnt.getMainHandItem() : ItemStack.EMPTY)) != 0)) {
world.destroyBlock(BlockPos.containing(x, y, z), false); // Pas d'XP si l'outil est enchanté Silk Touch (comportement vanilla).
if (world instanceof ServerLevel _level) ItemStack mainHand = (entity instanceof LivingEntity living) ? living.getMainHandItem() : ItemStack.EMPTY;
_level.addFreshEntity(new ExperienceOrb(_level, x, y, z, 2)); boolean silkTouch = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, mainHand) > 0;
} if (silkTouch)
return;
int amount = ModConfigs.SPEC.isLoaded() ? ModConfigs.DROPS.oreExperienceDrops.get() : 2;
if (amount <= 0)
return;
if (world instanceof ServerLevel level)
level.addFreshEntity(new ExperienceOrb(level, x + 0.5, y + 0.5, z + 0.5, amount));
} }
} }
@@ -0,0 +1,239 @@
package net.mcreator.customoregen.worldgen;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.server.ServerLifecycleHooks;
import net.mcreator.customoregen.config.ModConfigs;
import java.util.ArrayList;
import java.util.List;
public enum BiomeBand {
FROZEN(-12000),
COLD(-6000),
COOL(-2000),
TEMPERATE(0),
WARM(6000),
HOT(12000),
EXTREME(12000);
public final int bandBoundary;
BiomeBand(int bandBoundary) {
this.bandBoundary = bandBoundary;
}
public static List<Holder<Biome>> oceanFor(double temperature) {
int band = (int) Math.round(temperature);
List<ResourceKey<Biome>> keys = new ArrayList<>();
if (band <= -2) {
keys.add(Biomes.FROZEN_OCEAN);
keys.add(Biomes.DEEP_FROZEN_OCEAN);
} else if (band == -1) {
keys.add(Biomes.COLD_OCEAN);
keys.add(Biomes.DEEP_COLD_OCEAN);
} else if (band == 0) {
keys.add(Biomes.OCEAN);
keys.add(Biomes.DEEP_OCEAN);
keys.add(Biomes.LUKEWARM_OCEAN);
} else if (band == 1) {
keys.add(Biomes.LUKEWARM_OCEAN);
keys.add(Biomes.DEEP_LUKEWARM_OCEAN);
} else {
keys.add(Biomes.WARM_OCEAN);
}
return resolveHolders(keys);
}
public static List<Holder<Biome>> undergroundFor(double temperature) {
int band = (int) Math.round(temperature);
List<ResourceKey<Biome>> keys = new ArrayList<>();
if (band <= -1) {
keys.add(Biomes.DRIPSTONE_CAVES);
} else if (band == 0) {
keys.add(Biomes.LUSH_CAVES);
} else {
keys.add(Biomes.LUSH_CAVES);
keys.add(Biomes.DRIPSTONE_CAVES);
}
return resolveHolders(keys);
}
public List<Holder<Biome>> surface() {
List<ResourceKey<Biome>> keys = new ArrayList<>();
switch (this) {
case FROZEN:
add(keys, Biomes.ICE_SPIKES, Biomes.SNOWY_PLAINS, Biomes.SNOWY_BEACH,
Biomes.FROZEN_RIVER, Biomes.SNOWY_SLOPES, Biomes.DRIPSTONE_CAVES,
Biomes.DEEP_DARK);
addBOP(keys, "auroral_garden", "cold_desert", "tundra", "snowblossom_grove",
"snowy_coniferous_forest", "snowy_fir_clearing", "snowy_maple_woods");
break;
case COLD:
add(keys, Biomes.SNOWY_TAIGA, Biomes.GROVE, Biomes.SNOWY_BEACH,
Biomes.SNOWY_SLOPES, Biomes.OLD_GROWTH_PINE_TAIGA,
Biomes.FROZEN_PEAKS, Biomes.JAGGED_PEAKS, Biomes.ICE_SPIKES);
addBOP(keys, "snowy_coniferous_forest", "snowy_fir_clearing",
"snowy_maple_woods", "snowblossom_grove", "cold_desert", "tundra");
break;
case COOL:
add(keys, Biomes.OLD_GROWTH_PINE_TAIGA, Biomes.OLD_GROWTH_SPRUCE_TAIGA,
Biomes.TAIGA, Biomes.WINDSWEPT_FOREST, Biomes.STONY_SHORE,
Biomes.WINDSWEPT_HILLS, Biomes.STONY_PEAKS,
Biomes.DRIPSTONE_CAVES);
addBOP(keys, "coniferous_forest", "fir_clearing", "dead_forest", "bog",
"muskeg", "old_growth_dead_forest", "highland");
break;
case TEMPERATE:
add(keys, Biomes.PLAINS, Biomes.SUNFLOWER_PLAINS, Biomes.FOREST,
Biomes.BIRCH_FOREST, Biomes.FLOWER_FOREST, Biomes.MEADOW,
Biomes.SWAMP, Biomes.BEACH, Biomes.RIVER, Biomes.CHERRY_GROVE,
Biomes.OLD_GROWTH_BIRCH_FOREST, Biomes.LUSH_CAVES);
addBOP(keys, "grassland", "prairie", "field", "shrubland", "woodland",
"old_growth_woodland", "marsh", "seasonal_forest", "orchard",
"rainbow_hills", "clover_patch", "origin_valley");
break;
case WARM:
add(keys, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.SPARSE_JUNGLE,
Biomes.WINDSWEPT_SAVANNA, Biomes.FOREST, Biomes.STONY_PEAKS,
Biomes.MANGROVE_SWAMP, Biomes.LUSH_CAVES);
addBOP(keys, "dryland", "mediterranean_forest", "prairie", "lavender_field",
"lavender_forest", "orchard", "pasture", "scrubland",
"rocky_shrubland", "floodplain", "rainforest", "rocky_rainforest");
break;
case HOT:
add(keys, Biomes.DESERT, Biomes.JUNGLE, Biomes.BAMBOO_JUNGLE,
Biomes.BADLANDS, Biomes.WOODED_BADLANDS, Biomes.ERODED_BADLANDS,
Biomes.SAVANNA, Biomes.LUSH_CAVES, Biomes.DRIPSTONE_CAVES);
addBOP(keys, "lush_desert", "lush_savanna", "fungal_jungle", "tropics",
"bayou", "volcanic_plains", "wasteland", "outback",
"oasis", "rainforest", "rocky_rainforest", "jade_cliffs");
break;
case EXTREME:
add(keys, Biomes.ERODED_BADLANDS, Biomes.WOODED_BADLANDS,
Biomes.BADLANDS, Biomes.DESERT, Biomes.MANGROVE_SWAMP,
Biomes.WARM_OCEAN);
addBOP(keys, "volcano", "erupting_inferno", "wasteland",
"wasteland_steppe", "dryland", "lush_desert");
break;
}
return resolveHolders(keys);
}
private static void add(List<ResourceKey<Biome>> list, ResourceKey<Biome>... biomes) {
for (ResourceKey<Biome> key : biomes) {
list.add(key);
}
}
private static void addBOP(List<ResourceKey<Biome>> list, String... ids) {
// Respecte le toggle de configuration enableBOPBiomes (true par défaut).
if (!bopEnabled()) return;
for (String id : ids) {
ResourceKey<Biome> key = ResourceKey.create(Registries.BIOME,
new ResourceLocation("biomesoplenty", id));
if (ForgeRegistries.BIOMES.containsKey(key.location())) {
list.add(key);
}
}
}
private static List<Holder<Biome>> resolveHolders(List<ResourceKey<Biome>> keys) {
List<Holder<Biome>> holders = new ArrayList<>();
for (ResourceKey<Biome> key : keys) {
Holder<Biome> holder = resolveOne(key);
if (holder != null)
holders.add(holder);
}
return holders;
}
/**
* Résout un holder de biome de façon robuste :
* 1) registre vanilla {@link BuiltInRegistries} (toujours peuplé pour les
* biomes vanilla, fiable pendant la génération du monde) ;
* 2) registre Forge (biomes ajoutés par d'autres mods, ex. Biomes O' Plenty).
*/
/**
* Résout un holder de biome de façon robuste.
* <p>
* Pendant la génération du monde, {@code ForgeRegistries.BIOMES} peut être
* vide (notamment sur les threads de génération asynchrone). On passe donc
* d'abord par le registre de biomes du serveur — celui-là même qu'utilise la
* worldgen — avant de retomber sur le registre Forge (biomes de mods).
*/
private static Holder<Biome> resolveOne(ResourceKey<Biome> key) {
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
if (server != null) {
Registry<Biome> reg = server.registryAccess().registryOrThrow(Registries.BIOME);
Holder<Biome> holder = reg.getHolder(key).orElse(null);
if (holder != null)
return holder;
}
Holder<Biome> holder = ForgeRegistries.BIOMES.getHolder(key).orElse(null);
if (holder != null)
return holder;
return ForgeRegistries.BIOMES.getHolder(key.location()).orElse(null);
}
/** Holder de secours (plaine), résolu via le registre du serveur. */
private static Holder<Biome> fallbackHolder;
public static Holder<Biome> fallback() {
if (fallbackHolder == null)
fallbackHolder = resolveOne(Biomes.PLAINS);
return fallbackHolder;
}
public static List<Holder<Biome>> allPossible() {
List<Holder<Biome>> all = new ArrayList<>();
for (BiomeBand band : values()) {
all.addAll(band.surface());
}
for (int t = -3; t <= 3; t++) {
all.addAll(oceanFor(t));
all.addAll(undergroundFor(t));
}
return all;
}
public static double getTemperatureAtZ(int blockZ, net.minecraft.world.level.levelgen.synth.ImprovedNoise noise) {
// La largeur de bande est configurable (par défaut 4000 blocs).
double bandWidth = bandWidth();
double raw = blockZ / bandWidth;
double noiseVal = noise.noise(blockZ * (1.32 / bandWidth), 0, 0) * 0.8;
return Math.max(-3.0, Math.min(3.0, raw + noiseVal));
}
public static double getMoistureAtX(int blockX, int blockZ, net.minecraft.world.level.levelgen.synth.ImprovedNoise noise) {
return noise.noise(blockX * 0.00025, blockZ * 0.00015, 0) * 0.5 + 0.5;
}
public static boolean isOceanAt(int blockX, int blockZ, double temperature, net.minecraft.world.level.levelgen.synth.ImprovedNoise oceanNoise) {
double oceanChance = oceanNoise.noise(blockX * 0.0001, blockZ * 0.0001, 0) * 0.5 + 0.5;
double bandFactor = Math.abs(temperature) / 3.0;
return oceanChance < 0.15 + bandFactor * 0.15;
}
public static BiomeBand fromTemperature(double temperature) {
int idx = (int) Math.round(temperature) + 3;
idx = Math.max(0, Math.min(values().length - 1, idx));
return values()[idx];
}
// --- Accès sûrs à la configuration (valeurs par défaut si non chargée) ---
private static int bandWidth() {
return ModConfigs.SPEC.isLoaded() ? ModConfigs.WORLD_GEN.temperatureBandWidth.get() : 4000;
}
private static boolean bopEnabled() {
return !ModConfigs.SPEC.isLoaded() || ModConfigs.WORLD_GEN.enableBOPBiomes.get();
}
}
@@ -0,0 +1,113 @@
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.util.RandomSource;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.levelgen.synth.ImprovedNoise;
import net.mcreator.customoregen.config.ModConfigs;
import java.util.List;
import java.util.stream.Stream;
public class LatitudeBiomeSource extends BiomeSource {
public static final MapCodec<LatitudeBiomeSource> MAP_CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(
Codec.LONG.fieldOf("seed").forGetter(src -> src.seed)
).apply(instance, LatitudeBiomeSource::new)
);
public static final Codec<LatitudeBiomeSource> CODEC = MAP_CODEC.codec();
private final long seed;
private final ImprovedNoise temperatureNoise;
private final ImprovedNoise moistureNoise;
private final ImprovedNoise oceanNoise;
private final ImprovedNoise biomeSelectorNoise;
public LatitudeBiomeSource(long seed) {
this.seed = seed;
RandomSource rng = RandomSource.create(seed);
this.temperatureNoise = new ImprovedNoise(rng);
this.moistureNoise = new ImprovedNoise(rng);
this.oceanNoise = new ImprovedNoise(rng);
this.biomeSelectorNoise = new ImprovedNoise(rng);
}
@Override
protected Codec<? extends BiomeSource> codec() {
return CODEC;
}
@Override
protected Stream<Holder<Biome>> collectPossibleBiomes() {
// Résolution paresseuse : le registre du serveur n'est pas forcément
// disponible au moment de la construction du BiomeSource.
return BiomeBand.allPossible().stream();
}
@Override
public Holder<Biome> getNoiseBiome(int quartX, int quartY, int quartZ, Climate.Sampler sampler) {
int blockX = quartX * 4;
int blockZ = quartZ * 4;
int blockY = quartY * 4;
double temperature = BiomeBand.getTemperatureAtZ(blockZ, temperatureNoise);
double moisture = BiomeBand.getMoistureAtX(blockX, blockZ, moistureNoise);
if (oceansEnabled() && BiomeBand.isOceanAt(blockX, blockZ, temperature, oceanNoise)) {
List<Holder<Biome>> oceans = BiomeBand.oceanFor(temperature);
double pick = biomeSelectorNoise.noise(blockX * 0.005, blockZ * 0.005, 1000);
int idx = (int) ((pick * 0.5 + 0.5) * oceans.size());
return select(oceans, idx);
}
if (blockY < 0) {
List<Holder<Biome>> underground = BiomeBand.undergroundFor(temperature);
double pick = biomeSelectorNoise.noise(blockX * 0.01, blockZ * 0.01, 2000);
int idx = (int) ((pick * 0.5 + 0.5) * underground.size());
return select(underground, idx);
}
BiomeBand band = BiomeBand.fromTemperature(temperature);
List<Holder<Biome>> biomes = band.surface();
if (biomes.isEmpty()) {
biomes = BiomeBand.TEMPERATE.surface();
}
double selectorScale = 2.4 / biomeSize();
double pick = biomeSelectorNoise.noise(blockX * selectorScale, blockZ * selectorScale, 3000);
double adjusted = pick * 0.5 + moisture * 0.3;
int idx = (int) ((adjusted * 0.5 + 0.5) * biomes.size());
return select(biomes, idx);
}
/**
* Sélectionne un biome dans la liste à l'indice donné, sans jamais lever
* d'exception : si la liste est vide (résolution de holders échouée),
* retourne un biome de secours garanti.
*/
private Holder<Biome> select(List<Holder<Biome>> list, int idx) {
if (list.isEmpty()) {
Holder<Biome> fb = BiomeBand.fallback();
if (fb != null)
return fb;
}
int clamped = Math.max(0, Math.min(list.size() - 1, idx));
return list.get(clamped);
}
// --- Accès sûrs à la configuration (valeurs par défaut si non chargée) ---
private static boolean oceansEnabled() {
return !ModConfigs.SPEC.isLoaded() || ModConfigs.WORLD_GEN.enableOceans.get();
}
private static int biomeSize() {
return ModConfigs.SPEC.isLoaded() ? ModConfigs.WORLD_GEN.biomeSize.get() : 3000;
}
}
@@ -0,0 +1,55 @@
package net.mcreator.customoregen.worldgen;
import net.mcreator.customoregen.CustomOreGenMod;
import net.mcreator.customoregen.config.ModConfigs;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraft.world.entity.player.Player;
@Mod.EventBusSubscriber(modid = CustomOreGenMod.MODID)
public class PlainsSpawnHandler {
@SubscribeEvent
public static void onPlayerJoin(EntityJoinLevelEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
if (!(event.getLevel() instanceof ServerLevel level)) return;
if (!level.dimensionType().natural()) return;
// Garde naturel : si le spawn a déjà été déplacé (non nul), on ne fait plus rien.
// Évite le booléen statique global qui ne se déclenchait qu'une fois par serveur.
if (level.getSharedSpawnPos().getX() != 0 || level.getSharedSpawnPos().getZ() != 0) return;
BlockPos spawn = findPlainsSpawn(level);
level.setDefaultSpawnPos(spawn, 0.0f);
CustomOreGenMod.LOGGER.info("Custom Ore Gen: Spawn set to plains at {}", spawn);
}
private static BlockPos findPlainsSpawn(ServerLevel level) {
int radius = ModConfigs.SPEC.isLoaded() ? ModConfigs.WORLD_GEN.spawnSearchRadius.get() : 100;
BlockPos bestPos = new BlockPos(0, 64, 0);
double bestDistance = Double.MAX_VALUE;
for (int x = -radius; x <= radius; x += 4) {
for (int z = -radius; z <= radius; z += 4) {
BlockPos pos = new BlockPos(x, 0, z);
var biome = level.getBiome(pos);
if (biome.is(Biomes.PLAINS) || biome.is(Biomes.SUNFLOWER_PLAINS)) {
double dist = Math.sqrt(x * x + z * z);
if (dist < bestDistance) {
bestDistance = dist;
int y = level.getHeight(Heightmap.Types.WORLD_SURFACE, x, z);
bestPos = new BlockPos(x, y, z);
}
}
}
}
return bestPos;
}
}
@@ -0,0 +1,45 @@
package net.mcreator.customoregen.worldgen;
import net.mcreator.customoregen.CustomOreGenMod;
import net.mcreator.customoregen.config.ModConfigs;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = CustomOreGenMod.MODID)
public class WelcomeMessageHandler {
private static final String WELCOMED_KEY = "custom_ore_gen_welcomed";
@SubscribeEvent
public static void onPlayerJoin(EntityJoinLevelEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
if (!(event.getLevel() instanceof ServerLevel level)) return;
// Message configurable et envoyé UNE fois par joueur (persisté dans ses données).
if (ModConfigs.SPEC.isLoaded() && !ModConfigs.WORLD_GEN.enableWelcomeMessage.get()) return;
if (player.getPersistentData().getBoolean(WELCOMED_KEY)) return;
ChunkGenerator generator = level.getChunkSource().getGenerator();
if (!(generator.getBiomeSource() instanceof LatitudeBiomeSource)) return;
player.getPersistentData().putBoolean(WELCOMED_KEY, true);
player.sendSystemMessage(Component.literal(""));
player.sendSystemMessage(Component.literal("\u00A76\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
player.sendSystemMessage(Component.literal("\u00A7e Custom Ore Gen \u00BB Mode Latitude"));
player.sendSystemMessage(Component.literal("\u00A76\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
player.sendSystemMessage(Component.literal("\u00A77 Le monde suit une logique de latitude !"));
player.sendSystemMessage(Component.literal("\u00A7b Nord (Z \u2192 -) \u00A73\u2192 Landes enneig\u00E9es & ta\u00EFgas"));
player.sendSystemMessage(Component.literal("\u00A7a Centre \u00A72\u2192 Plaines, for\u00EAts temp\u00E9r\u00E9es \u00A78[SPAWN]"));
player.sendSystemMessage(Component.literal("\u00A7c Sud (Z \u2192 +) \u00A76\u2192 D\u00E9serts, jungles & savanes"));
player.sendSystemMessage(Component.literal("\u00A77 Les grottes suivent la m\u00EAme logique."));
player.sendSystemMessage(Component.literal("\u00A7e Astuce : F3 pour voir vos coordonn\u00E9es Z"));
player.sendSystemMessage(Component.literal("\u00A76\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
}
}
@@ -0,0 +1,16 @@
package net.mcreator.customoregen.worldgen;
import net.mcreator.customoregen.CustomOreGenMod;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import com.mojang.serialization.Codec;
public class WorldGenRegistration {
public static final DeferredRegister<Codec<? extends BiomeSource>> BIOME_SOURCES =
DeferredRegister.create(Registries.BIOME_SOURCE, CustomOreGenMod.MODID);
public static final RegistryObject<Codec<? extends BiomeSource>> LATITUDE =
BIOME_SOURCES.register("latitude", () -> LatitudeBiomeSource.CODEC);
}
+2 -2
View File
@@ -4,12 +4,12 @@ license="Not specified"
[[mods]] [[mods]]
modId="custom_ore_gen" modId="custom_ore_gen"
version="2.1.6-forge" version="4.5-forge"
displayName="Custom Ore Gen" displayName="Custom Ore Gen"
displayURL="https://lanro.eu" displayURL="https://lanro.eu"
credits="Created using mod maker MCreator - https://mcreator.net/about" credits="Created using mod maker MCreator - https://mcreator.net/about"
authors="Aulyrius cr\u00E9e via MCreator" authors="Aulyrius cr\u00E9e via MCreator"
description="Changement de la distribution des ressources sur Minecraft, ne pas utilis\u00E9 seul sans KubeJS" description="Changement de la distribution des ressources. Monde latitude extra-large avec biomes r\u00E9partis par Z (nord=froid, sud=chaud), montagnes amplifi\u00E9es, grottes suivent la surface. Ne pas utiliser seul sans KubeJS."
# Start of user code block mod configuration # Start of user code block mod configuration
# End of user code block mod configuration # End of user code block mod configuration
@@ -0,0 +1,36 @@
{
"dimensions": {
"minecraft:overworld": {
"type": "minecraft:overworld",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "custom_ore_gen:latitude",
"seed": 0
},
"settings": "minecraft:amplified"
}
},
"minecraft:the_nether": {
"type": "minecraft:the_nether",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:nether"
},
"settings": "minecraft:nether"
}
},
"minecraft:the_end": {
"type": "minecraft:the_end",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:the_end"
},
"settings": "minecraft:end"
}
}
}
}