Skip to content

Commit

Permalink
Merge pull request #25 from Technici4n/1.17
Browse files Browse the repository at this point in the history
Fix #24: move biome creation after all blocks have been registered
  • Loading branch information
Draylar committed Oct 24, 2021
2 parents 048a526 + b8b0d91 commit 78a509d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 23 deletions.
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);
}
}
}

0 comments on commit 78a509d

Please sign in to comment.