Compare commits
2
Commits
neoforge-1.21
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
401674c90b | ||
|
|
ee1b203a7f |
@@ -0,0 +1,9 @@
|
||||
.gradle/
|
||||
build/
|
||||
run/
|
||||
*.iml
|
||||
.idea/
|
||||
*.class
|
||||
*.log
|
||||
*.lock
|
||||
*.bin
|
||||
+1
-1
@@ -3,7 +3,7 @@ plugins {
|
||||
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
|
||||
}
|
||||
|
||||
version = '2.1.12'
|
||||
version = '4.5'
|
||||
group = 'com.aulyrius.custom_ore_gen'
|
||||
archivesBaseName = 'custom_ore_gen'
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import net.minecraftforge.network.NetworkRegistry;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.fml.util.thread.SidedThreadGroups;
|
||||
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.eventbus.api.SubscribeEvent;
|
||||
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.CustomOreGenModItems;
|
||||
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.Function;
|
||||
@@ -41,12 +45,17 @@ public class CustomOreGenMod {
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
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);
|
||||
|
||||
CustomOreGenModItems.REGISTRY.register(bus);
|
||||
|
||||
CustomOreGenModTabs.REGISTRY.register(bus);
|
||||
|
||||
WorldGenRegistration.BIOME_SOURCES.register(bus);
|
||||
|
||||
// Start of user code block mod init
|
||||
// End of user code block mod init
|
||||
}
|
||||
|
||||
@@ -1,35 +1,22 @@
|
||||
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 {
|
||||
// Helper method to safely access config values
|
||||
public static boolean isFeatureEnabled(String featureName) {
|
||||
switch (featureName) {
|
||||
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;
|
||||
}
|
||||
|
||||
private static boolean loaded() {
|
||||
return ModConfigs.SPEC.isLoaded();
|
||||
}
|
||||
|
||||
/** Durabilité de l'outil Shard Diamond concerné (par défaut 200). */
|
||||
public static int getShardDiamondToolDurability(String toolType) {
|
||||
if (!loaded())
|
||||
return 200;
|
||||
switch (toolType) {
|
||||
case "pickaxe":
|
||||
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) {
|
||||
if (!loaded())
|
||||
return defaultSpeed(toolType);
|
||||
switch (toolType) {
|
||||
case "pickaxe":
|
||||
return ModConfigs.TOOL_STATS.shardDiamondPickaxeSpeed.get().floatValue();
|
||||
@@ -55,16 +45,7 @@ public class ConfigHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static int getShardDiamondToolDamage(String toolType) {
|
||||
switch (toolType) {
|
||||
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;
|
||||
}
|
||||
private static float defaultSpeed(String toolType) {
|
||||
return "shovel".equals(toolType) ? 4.0f : 7.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,16 @@ public class ModConfigs {
|
||||
public static final ToolStatsConfig TOOL_STATS;
|
||||
public static final DropsConfig DROPS;
|
||||
public static final FeatureToggleConfig FEATURES;
|
||||
public static final WorldGenConfig WORLD_GEN;
|
||||
|
||||
static {
|
||||
BUILDER.push("Custom Ore Gem Configuration");
|
||||
BUILDER.push("Custom Ore Gen Configuration");
|
||||
|
||||
ORE_GEN = new OreGenConfig(BUILDER);
|
||||
TOOL_STATS = new ToolStatsConfig(BUILDER);
|
||||
DROPS = new DropsConfig(BUILDER);
|
||||
FEATURES = new FeatureToggleConfig(BUILDER);
|
||||
WORLD_GEN = new WorldGenConfig(BUILDER);
|
||||
|
||||
BUILDER.pop();
|
||||
SPEC = BUILDER.build();
|
||||
@@ -128,15 +130,12 @@ public class ModConfigs {
|
||||
public static class ToolStatsConfig {
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondPickaxeDurability;
|
||||
public final ForgeConfigSpec.DoubleValue shardDiamondPickaxeSpeed;
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondPickaxeAttackDamage;
|
||||
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondAxeDurability;
|
||||
public final ForgeConfigSpec.DoubleValue shardDiamondAxeSpeed;
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondAxeAttackDamage;
|
||||
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondShovelDurability;
|
||||
public final ForgeConfigSpec.DoubleValue shardDiamondShovelSpeed;
|
||||
public final ForgeConfigSpec.ConfigValue<Integer> shardDiamondShovelAttackDamage;
|
||||
|
||||
public ToolStatsConfig(ForgeConfigSpec.Builder builder) {
|
||||
builder.push("tool_stats");
|
||||
@@ -148,9 +147,6 @@ public class ModConfigs {
|
||||
shardDiamondPickaxeSpeed = builder
|
||||
.comment("Mining speed of Shard Diamond Pickaxe (default: 7.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
|
||||
.comment("Durability of Shard Diamond Axe (default: 200)")
|
||||
@@ -158,9 +154,6 @@ public class ModConfigs {
|
||||
shardDiamondAxeSpeed = builder
|
||||
.comment("Mining speed of Shard Diamond Axe (default: 7.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
|
||||
.comment("Durability of Shard Diamond Shovel (default: 200)")
|
||||
@@ -168,9 +161,6 @@ public class ModConfigs {
|
||||
shardDiamondShovelSpeed = builder
|
||||
.comment("Mining speed of Shard Diamond Shovel (default: 4.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();
|
||||
@@ -327,4 +317,38 @@ public class ModConfigs {
|
||||
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.mcreator.customoregen.init.CustomOreGenModItems;
|
||||
import net.mcreator.customoregen.config.ConfigHelper;
|
||||
|
||||
public class SharddiamondaxeItem extends AxeItem {
|
||||
public SharddiamondaxeItem() {
|
||||
super(new Tier() {
|
||||
public int getUses() {
|
||||
return 200;
|
||||
return ConfigHelper.getShardDiamondToolDurability("axe");
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return 7f;
|
||||
return ConfigHelper.getShardDiamondToolSpeed("axe");
|
||||
}
|
||||
|
||||
public float getAttackDamageBonus() {
|
||||
|
||||
@@ -8,16 +8,17 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
import net.mcreator.customoregen.init.CustomOreGenModItems;
|
||||
import net.mcreator.customoregen.config.ConfigHelper;
|
||||
|
||||
public class SharddiamondpickaxeItem extends PickaxeItem {
|
||||
public SharddiamondpickaxeItem() {
|
||||
super(new Tier() {
|
||||
public int getUses() {
|
||||
return 200; // Hardcoded - config not loaded yet
|
||||
return ConfigHelper.getShardDiamondToolDurability("pickaxe");
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return 7f;
|
||||
return ConfigHelper.getShardDiamondToolSpeed("pickaxe");
|
||||
}
|
||||
|
||||
public float getAttackDamageBonus() {
|
||||
|
||||
@@ -8,16 +8,17 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
import net.mcreator.customoregen.init.CustomOreGenModItems;
|
||||
import net.mcreator.customoregen.config.ConfigHelper;
|
||||
|
||||
public class SharddiamondshovelItem extends ShovelItem {
|
||||
public SharddiamondshovelItem() {
|
||||
super(new Tier() {
|
||||
public int getUses() {
|
||||
return 200;
|
||||
return ConfigHelper.getShardDiamondToolDurability("shovel");
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return 4f;
|
||||
return ConfigHelper.getShardDiamondToolSpeed("shovel");
|
||||
}
|
||||
|
||||
public float getAttackDamageBonus() {
|
||||
|
||||
-143
@@ -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.Entity;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
import net.mcreator.customoregen.config.ModConfigs;
|
||||
|
||||
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) {
|
||||
// Uniquement côté serveur : l'XP ne doit pas être spawnée côté client.
|
||||
if (world.isClientSide())
|
||||
return;
|
||||
if (entity == null)
|
||||
return;
|
||||
if (!(EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, (entity instanceof LivingEntity _livEnt ? _livEnt.getMainHandItem() : ItemStack.EMPTY)) != 0)) {
|
||||
world.destroyBlock(BlockPos.containing(x, y, z), false);
|
||||
if (world instanceof ServerLevel _level)
|
||||
_level.addFreshEntity(new ExperienceOrb(_level, x, y, z, 2));
|
||||
}
|
||||
|
||||
// Pas d'XP si l'outil est enchanté Silk Touch (comportement vanilla).
|
||||
ItemStack mainHand = (entity instanceof LivingEntity living) ? living.getMainHandItem() : ItemStack.EMPTY;
|
||||
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);
|
||||
}
|
||||
@@ -4,12 +4,12 @@ license="Not specified"
|
||||
|
||||
[[mods]]
|
||||
modId="custom_ore_gen"
|
||||
version="2.1.6-forge"
|
||||
version="4.5-forge"
|
||||
displayName="Custom Ore Gen"
|
||||
displayURL="https://lanro.eu"
|
||||
credits="Created using mod maker MCreator - https://mcreator.net/about"
|
||||
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
|
||||
# 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user