diff --git a/src/main/java/draylar/horizon/MinersHorizon.java b/src/main/java/draylar/horizon/MinersHorizon.java index c5364f9..1086a68 100644 --- a/src/main/java/draylar/horizon/MinersHorizon.java +++ b/src/main/java/draylar/horizon/MinersHorizon.java @@ -1,12 +1,12 @@ package draylar.horizon; import draylar.horizon.config.MinersHorizonConfig; -import draylar.horizon.registry.HorizonBiomes; import draylar.horizon.registry.HorizonBlocks; import draylar.horizon.registry.HorizonWorld; import draylar.horizon.util.HorizonPortalHelper; import draylar.omegaconfig.OmegaConfig; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper; import net.minecraft.item.ItemStack; @@ -31,9 +31,6 @@ public void onInitialize() { // Register ores from config HorizonWorld.registerOreHandlers(); - // Load biomes after ores are loaded - HorizonBiomes.init(); - // The following callback is used for portal activation via any Pickaxe. UseBlockCallback.EVENT.register((player, world, hand, blockHitResult) -> { if(!world.isClient) { @@ -48,6 +45,8 @@ public void onInitialize() { return ActionResult.PASS; }); + + ServerLifecycleEvents.SERVER_STARTING.register(ms -> HorizonWorld.ensureBlocksAreRegistered()); } public static Identifier id(String path) { diff --git a/src/main/java/draylar/horizon/MinersHorizonClient.java b/src/main/java/draylar/horizon/MinersHorizonClient.java index a6af40d..c4af530 100644 --- a/src/main/java/draylar/horizon/MinersHorizonClient.java +++ b/src/main/java/draylar/horizon/MinersHorizonClient.java @@ -4,6 +4,7 @@ import draylar.horizon.registry.HorizonWorld; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; import net.minecraft.block.Block; import net.minecraft.block.Material; @@ -19,6 +20,8 @@ public class MinersHorizonClient implements ClientModInitializer { @Override public void onInitializeClient() { + ClientLifecycleEvents.CLIENT_STARTED.register(mc -> HorizonWorld.ensureBlocksAreRegistered()); + BlockRenderLayerMap.INSTANCE.putBlock(HorizonBlocks.HORIZON_PORTAL, RenderLayer.getTranslucent()); // Register a color provider for stone/ore blocks. diff --git a/src/main/java/draylar/horizon/registry/HorizonBiomes.java b/src/main/java/draylar/horizon/registry/HorizonBiomes.java index 4ea5f4f..7f3cfae 100644 --- a/src/main/java/draylar/horizon/registry/HorizonBiomes.java +++ b/src/main/java/draylar/horizon/registry/HorizonBiomes.java @@ -17,7 +17,6 @@ public class HorizonBiomes { - private static final Biome ROCKY_PLAINS = createRockyPlains(); public static final RegistryKey ROCKY_PLAINS_KEYS = RegistryKey.of(Registry.BIOME_KEY, MinersHorizon.id("rocky_plains")); private HorizonBiomes() { @@ -25,7 +24,7 @@ private HorizonBiomes() { } public static void init() { - Registry.register(BuiltinRegistries.BIOME, ROCKY_PLAINS_KEYS.getValue(), ROCKY_PLAINS); + Registry.register(BuiltinRegistries.BIOME, ROCKY_PLAINS_KEYS.getValue(), createRockyPlains()); } public static Biome createRockyPlains() { diff --git a/src/main/java/draylar/horizon/registry/HorizonWorld.java b/src/main/java/draylar/horizon/registry/HorizonWorld.java index e724bda..c2be7c8 100644 --- a/src/main/java/draylar/horizon/registry/HorizonWorld.java +++ b/src/main/java/draylar/horizon/registry/HorizonWorld.java @@ -26,9 +26,7 @@ import net.minecraft.world.gen.surfacebuilder.SurfaceConfig; import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; public class HorizonWorld { @@ -79,32 +77,41 @@ public static void init() { Registry.register(Registry.CHUNK_GENERATOR, MinersHorizon.id("horizon"), MinersHorizonChunkGenerator.CODEC); } + private static final Map> REMAINING_BLOCKS = new TreeMap<>(); + public static void registerOreHandlers() { List ores = new ArrayList<>(Arrays.asList(MinersHorizon.CONFIG.oreConfigList)); + for (OreConfig ore : ores) { + REMAINING_BLOCKS.computeIfAbsent(ore.block, s -> new ArrayList<>()).add(ore); + } + // Handle ores that have already been registered. Registry.BLOCK.getEntries().forEach(entry -> { - RegistryKey key = entry.getKey(); - String id = key.getValue().toString(); - - // Load every Ore Config with a matching ID. - ores.stream().filter(config -> config.block.equals(id)).forEach(config -> { - ORES.add(load(config, entry.getValue())); - }); + processRegisteredBlock(entry.getKey().getValue().toString(), entry.getValue()); }); - // TODO: there is a chance this slows down game loading. The question is how much? - // 100 entries * 1,000 registry events = 100,000 filter checks. // Register a callback to add in future ores. RegistryEntryAddedCallback.event(Registry.BLOCK).register((rawId, id, object) -> { - - // Load every Ore Config with a matching ID. - ores.stream().filter(config -> config.block.equals(id.toString())).forEach(config -> { - ORES.add(load(config, object)); - }); + processRegisteredBlock(id.toString(), object); }); } + private static void processRegisteredBlock(String id, Block block) { + List configs = REMAINING_BLOCKS.remove(id); + + if (configs != null) { + for (OreConfig config : configs) { + ORES.add(load(config, block)); + } + + if (REMAINING_BLOCKS.size() == 0) { + // Register the biome if all ores have been loaded. + HorizonBiomes.init(); + } + } + } + private static ConfiguredFeature load(OreConfig config, Block block) { return register( String.format("%s_%d_%d_%d", new Identifier(config.block).getPath(), config.size, config.count, config.maxY), @@ -117,4 +124,14 @@ public static void registerOreHandlers() { .spreadHorizontally() .repeat(config.count)); } + + public static void ensureBlocksAreRegistered() { + if (REMAINING_BLOCKS.size() > 0) { + String errorMessage = String.format( + "Miners Horizon: Could not register biome because the following blocks do not exist, yet they were specified in the config:%n%s.", + String.join(", ", REMAINING_BLOCKS.keySet().toArray(String[]::new)) + ); + throw new RuntimeException(errorMessage); + } + } }