Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #24: move biome creation after all blocks have been registered #25

Merged
merged 1 commit into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/main/java/draylar/horizon/MinersHorizon.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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) {
Expand All @@ -48,6 +45,8 @@ public void onInitialize() {

return ActionResult.PASS;
});

ServerLifecycleEvents.SERVER_STARTING.register(ms -> HorizonWorld.ensureBlocksAreRegistered());
}

public static Identifier id(String path) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/draylar/horizon/MinersHorizonClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/draylar/horizon/registry/HorizonBiomes.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@

public class HorizonBiomes {

private static final Biome ROCKY_PLAINS = createRockyPlains();
public static final RegistryKey<Biome> ROCKY_PLAINS_KEYS = RegistryKey.of(Registry.BIOME_KEY, MinersHorizon.id("rocky_plains"));

private HorizonBiomes() {
// NO-OP
}

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() {
Expand Down
51 changes: 34 additions & 17 deletions src/main/java/draylar/horizon/registry/HorizonWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -79,32 +77,41 @@ public static void init() {
Registry.register(Registry.CHUNK_GENERATOR, MinersHorizon.id("horizon"), MinersHorizonChunkGenerator.CODEC);
}

private static final Map<String, List<OreConfig>> REMAINING_BLOCKS = new TreeMap<>();

public static void registerOreHandlers() {
List<OreConfig> 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<Block> 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<OreConfig> 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),
Expand All @@ -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);
}
}
}