diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 793fac00a..af17e27d6 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -86,13 +86,13 @@ object Versions { } object Allay { - const val api = "0.12.0" + const val api = "0.13.0" const val gson = "2.13.2" - const val mappings = "8002ed6" - const val mappingsGenerator = "fd83f41" + const val mappings = "15398c1" + const val mappingsGenerator = "8fa6058" - const val mcmeta = "b758592" + const val mcmeta = "e85a17c" } object Minestom { diff --git a/platforms/allay/README.md b/platforms/allay/README.md index 90392d1a8..31d437325 100644 --- a/platforms/allay/README.md +++ b/platforms/allay/README.md @@ -2,8 +2,8 @@ ## Resource files -Current mapping version: je 1.21.7 to be 1.21.93 +Current mapping version: je 1.21.9 to be 1.21.111 - `mapping/biomes.json` and `mapping/items.json` are obtained from [GeyserMC/mappings](https://github.com/GeyserMC/mappings). -- `mapping/blocks.json` is obtained from [GeyserMC/mappings-generator](https://github.com/GeyserMC/mappings-generator) (path: `https://github.com/GeyserMC/mappings-generator/blob/master/new_generator_blocks.json`). +- `mapping/blocks.json` is obtained from [GeyserMC/mappings-generator](https://github.com/GeyserMC/mappings-generator) (path: `https://github.com/GeyserMC/mappings-generator/blob/master/generator_blocks.json`). - `je_blocks.json` is obtained from [misode/mcmeta](https://github.com/misode/mcmeta) (path: `https://github.com/misode/mcmeta/blob/-summary/blocks/data.json`). diff --git a/platforms/allay/build.gradle.kts b/platforms/allay/build.gradle.kts index be9399a84..7fa3c9b8e 100644 --- a/platforms/allay/build.gradle.kts +++ b/platforms/allay/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { geyserMappings("GeyserMC.mappings", "items", Versions.Allay.mappings, ext = "json") geyserMappings("GeyserMC.mappings", "biomes", Versions.Allay.mappings, ext = "json") - geyserMappings("GeyserMC.mappings-generator", "new_generator_blocks", Versions.Allay.mappingsGenerator, ext = "json") + geyserMappings("GeyserMC.mappings-generator", "generator_blocks", Versions.Allay.mappingsGenerator, ext = "json") mcmeta("misode.mcmeta", "blocks/data", Versions.Allay.mcmeta, ext = "json") } @@ -38,7 +38,7 @@ tasks.processResources { into("mapping") // rather jank, but whatever - rename("(?:new_generator_)?([^-]+)-(.*)\\.json", "$1.json") + rename("(?:generator_)?([^-]+)-(.*)\\.json", "$1.json") } from(mcmeta) { rename("data-(.*)\\.json", "je_blocks.json") diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/AllayPlatform.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/AllayPlatform.java index cd8353efc..f9cb5831f 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/AllayPlatform.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/AllayPlatform.java @@ -45,7 +45,7 @@ public boolean reload() { getConfigRegistry().get(wrapper.getConfigPack().getRegistryKey()).ifPresent(pack -> { wrapper.setConfigPack(pack); var dimension = wrapper.getAllayWorldGenerator().getDimension(); - TerraAllayPlugin.INSTANCE.getPluginLogger().info( + TerraAllayPlugin.instance.getPluginLogger().info( "Replaced pack in chunk generator for world {}", dimension.getWorld().getWorldData().getDisplayName() + ":" + dimension.getDimensionInfo().dimensionId() ); @@ -72,7 +72,7 @@ public boolean reload() { @Override public @NotNull File getDataFolder() { - return TerraAllayPlugin.INSTANCE.getPluginContainer().dataFolder().toFile(); + return TerraAllayPlugin.instance.getPluginContainer().dataFolder().toFile(); } @Override diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/JeBlockState.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/JeBlockState.java index 89495bb03..58c8f97b9 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/JeBlockState.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/JeBlockState.java @@ -10,12 +10,25 @@ * @author daoge_cmd */ public class JeBlockState { + protected final String identifier; protected final TreeMap properties; + protected int hash = Integer.MAX_VALUE; private JeBlockState(String data) { - String[] strings = data.replace("[", ",").replace("]", ",").replace(" ", "").split(","); + // TODO: support block state with nbt (identifier[properties]{nbt}), for now we just ignore it + int braceIndex = data.indexOf('{'); + if (braceIndex != -1) { + data = data.substring(0, braceIndex); + } + + String[] strings = data + .replace("[", ",") + .replace("]", ",") + .replace(" ", "") + .split(","); + this.identifier = strings[0]; this.properties = new TreeMap<>(); if(strings.length > 1) { diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/Mapping.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/Mapping.java index cfd142356..39c455ec7 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/Mapping.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/Mapping.java @@ -13,6 +13,7 @@ import org.allaymc.api.block.type.BlockTypes; import org.allaymc.api.item.type.ItemType; import org.allaymc.api.item.type.ItemTypeGetter; +import org.allaymc.api.world.data.DimensionInfo; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -57,7 +58,7 @@ public static JeBlockState blockStateBeToJe(BlockState beBlockState) { public static BlockState blockStateJeToBe(JeBlockState jeBlockState) { BlockState result = JE_BLOCK_STATE_HASH_TO_BE.get(jeBlockState.getHash()); if(result == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().warn("Failed to find be block state for {}", jeBlockState); + TerraAllayPlugin.instance.getPluginLogger().warn("Failed to find be block state for {}", jeBlockState); return BE_AIR_STATE; } return result; @@ -81,10 +82,19 @@ public static int biomeIdJeToBe(String jeBiomeId) { return JE_BIOME_ID_TO_BE.get(jeBiomeId); } + public static String dimensionIdBeToJe(String beDimensionId) { + return switch (beDimensionId) { + case "overworld" -> "minecraft:overworld"; + case "nether" -> "minecraft:the_nether"; + case "the_end" -> "minecraft:the_end"; + default -> beDimensionId; + }; + } + public static Map getJeBlockDefaultProperties(String jeBlockIdentifier) { var defaultProperties = JE_BLOCK_DEFAULT_PROPERTIES.get(jeBlockIdentifier); if(defaultProperties == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().warn("Failed to find default properties for {}", jeBlockIdentifier); + TerraAllayPlugin.instance.getPluginLogger().warn("Failed to find default properties for {}", jeBlockIdentifier); return Map.of(); } @@ -98,7 +108,7 @@ private static void error() { private static boolean initBiomeMapping() { try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/biomes.json")) { if(stream == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("biomes mapping not found"); + TerraAllayPlugin.instance.getPluginLogger().error("biomes mapping not found"); return false; } @@ -106,7 +116,7 @@ private static boolean initBiomeMapping() { }); mappings.forEach((javaId, mapping) -> JE_BIOME_ID_TO_BE.put(javaId, mapping.bedrockId())); } catch(IOException e) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load biomes mapping", e); + TerraAllayPlugin.instance.getPluginLogger().error("Failed to load biomes mapping", e); return false; } return true; @@ -115,7 +125,7 @@ private static boolean initBiomeMapping() { private static boolean initItemMapping() { try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/items.json")) { if(stream == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("items mapping not found"); + TerraAllayPlugin.instance.getPluginLogger().error("items mapping not found"); return false; } @@ -129,7 +139,7 @@ private static boolean initItemMapping() { JE_ITEM_ID_TO_BE.put(javaId, itemType); }); } catch(IOException e) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load items mapping", e); + TerraAllayPlugin.instance.getPluginLogger().error("Failed to load items mapping", e); return false; } return true; @@ -138,7 +148,7 @@ private static boolean initItemMapping() { private static boolean initBlockStateMapping() { try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/blocks.json")) { if(stream == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("blocks mapping not found"); + TerraAllayPlugin.instance.getPluginLogger().error("blocks mapping not found"); return false; } @@ -152,7 +162,7 @@ private static boolean initBlockStateMapping() { JE_BLOCK_STATE_HASH_TO_BE.put(jeState.getHash(), beState); }); } catch(IOException e) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load blocks mapping", e); + TerraAllayPlugin.instance.getPluginLogger().error("Failed to load blocks mapping", e); return false; } return true; @@ -162,7 +172,7 @@ private static boolean initBlockStateMapping() { private static boolean initJeBlockDefaultProperties() { try(InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("je_blocks.json")) { if(stream == null) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("je_block_default_states.json not found"); + TerraAllayPlugin.instance.getPluginLogger().error("je_block_default_states.json not found"); return false; } diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/TerraAllayPlugin.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/TerraAllayPlugin.java index d2e5a16a6..76b47601b 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/TerraAllayPlugin.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/TerraAllayPlugin.java @@ -15,38 +15,38 @@ */ public class TerraAllayPlugin extends Plugin { - public static TerraAllayPlugin INSTANCE; - public static AllayPlatform PLATFORM; + public static TerraAllayPlugin instance; + public static AllayPlatform platform; { - INSTANCE = this; + TerraAllayPlugin.instance = this; } @Override public void onLoad() { - pluginLogger.info("Starting Terra..."); + this.pluginLogger.info("Starting Terra..."); - pluginLogger.info("Loading mapping..."); + this.pluginLogger.info("Loading mapping..."); Mapping.init(); - pluginLogger.info("Initializing allay platform..."); - PLATFORM = new AllayPlatform(); - PLATFORM.getEventManager().callEvent(new PlatformInitializationEvent()); + this.pluginLogger.info("Initializing allay platform..."); + TerraAllayPlugin.platform = new AllayPlatform(); + TerraAllayPlugin.platform.getEventManager().callEvent(new PlatformInitializationEvent()); // TODO: adapt command manager - pluginLogger.info("Registering generator..."); + this.pluginLogger.info("Registering generator..."); Registries.WORLD_GENERATOR_FACTORIES.register("TERRA", preset -> { try { AllayGeneratorWrapper wrapper = new AllayGeneratorWrapper(preset); AllayPlatform.GENERATOR_WRAPPERS.add(wrapper); return wrapper.getAllayWorldGenerator(); } catch(IllegalArgumentException e) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("Fail to create world generator with preset: {}", preset, e); + TerraAllayPlugin.instance.getPluginLogger().error("Fail to create world generator with preset: {}", preset, e); return Registries.WORLD_GENERATOR_FACTORIES.get("FLAT").apply(""); } }); - pluginLogger.info("Terra started"); + this.pluginLogger.info("Terra started"); } @Override @@ -61,10 +61,10 @@ public boolean isReloadable() { @Override public void reload() { - if(PLATFORM.reload()) { - pluginLogger.info("Terra reloaded successfully."); + if(TerraAllayPlugin.platform.reload()) { + this.pluginLogger.info("Terra reloaded successfully."); } else { - pluginLogger.error("Terra failed to reload."); + this.pluginLogger.error("Terra failed to reload."); } } diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayBlockEntity.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayBlockEntity.java new file mode 100644 index 000000000..e6c0229f8 --- /dev/null +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayBlockEntity.java @@ -0,0 +1,52 @@ +package com.dfsek.terra.allay.delegate; + +import com.dfsek.seismic.type.vector.Vector3; + +import com.dfsek.terra.allay.Mapping; +import com.dfsek.terra.api.block.state.BlockState; + +import org.allaymc.api.blockentity.BlockEntity; + + +/** + * @author daoge_cmd + */ +public record AllayBlockEntity(BlockEntity allayBlockEntity) implements com.dfsek.terra.api.block.entity.BlockEntity { + + @Override + public boolean update(boolean applyPhysics) { + return false; + } + + @Override + public Vector3 getPosition() { + var pos = this.allayBlockEntity.getPosition(); + return Vector3.of(pos.x(), pos.y(), pos.z()); + } + + @Override + public int getX() { + return this.allayBlockEntity.getPosition().x(); + } + + @Override + public int getY() { + return this.allayBlockEntity.getPosition().y(); + } + + @Override + public int getZ() { + return this.allayBlockEntity.getPosition().z(); + } + + @Override + public BlockState getBlockState() { + var allayBlockState = this.allayBlockEntity.getBlockState(); + return new AllayBlockState(allayBlockState, Mapping.blockStateBeToJe(this.allayBlockEntity.getBlockState())); + } + + @Override + public Object getHandle() { + return this.allayBlockEntity; + } +} diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayChunk.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayChunk.java index 0ffc1766b..b206af951 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayChunk.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayChunk.java @@ -21,6 +21,13 @@ public record AllayChunk(ServerWorld world, Chunk allayChunk) implements com.dfs @Override public void setBlock(int x, int y, int z, BlockState data, boolean physics) { + var dimensionInfo = allayChunk.getDimensionInfo(); + if (x < 0 || x > 15 || + z < 0 || z > 15 || + y < dimensionInfo.minHeight() || y > dimensionInfo.maxHeight()) { + return; + } + AllayBlockState allayBlockState = (AllayBlockState) data; allayChunk.setBlockState(x, y, z, allayBlockState.allayBlockState()); if(allayBlockState.containsWater() || allayChunk.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER)) { diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayFakeEntity.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayFakeEntity.java index 7ac5cc113..cf228e5f4 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayFakeEntity.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayFakeEntity.java @@ -7,7 +7,7 @@ /** - * NOTICE: Entity is not supported currently, and this is a fake implementation. + * TODO: Entity is not supported currently, and this is a fake implementation. * * @author daoge_cmd */ diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoChunk.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoChunk.java index 517957678..9bee9b223 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoChunk.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoChunk.java @@ -26,6 +26,13 @@ public int getMaxHeight() { @Override public void setBlock(int x, int y, int z, @NotNull BlockState blockState) { + var dimensionInfo = allayChunk.getDimensionInfo(); + if (x < 0 || x > 15 || + z < 0 || z > 15 || + y < dimensionInfo.minHeight() || y > dimensionInfo.maxHeight()) { + return; + } + AllayBlockState allayBlockState = (AllayBlockState) blockState; allayChunk.setBlockState(x, y, z, allayBlockState.allayBlockState()); if(allayBlockState.containsWater() || allayChunk.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER)) { diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoWorld.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoWorld.java index de50c171e..ea9907254 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoWorld.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayProtoWorld.java @@ -43,6 +43,11 @@ public ServerWorld getWorld() { @Override public void setBlockState(int x, int y, int z, BlockState data, boolean physics) { + var dimensionInfo = allayServerWorld.allayDimension().getDimensionInfo(); + if (y < dimensionInfo.minHeight() || y > dimensionInfo.maxHeight()) { + return; + } + AllayBlockState allayBlockState = (AllayBlockState) data; context.setBlockState(x, y, z, allayBlockState.allayBlockState()); if(allayBlockState.containsWater() || context.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER)) { @@ -63,7 +68,24 @@ public Entity spawnEntity(double x, double y, double z, EntityType entityType) { @Override public BlockEntity getBlockEntity(int x, int y, int z) { - return null; + return new AllayBlockEntity(getBlockEntity(context, x, y, z)); + } + + // TODO: use method in OtherChunkAccessibleContext directly after bumped allay-api version to 0.14.0 + private static org.allaymc.api.blockentity.BlockEntity getBlockEntity(OtherChunkAccessibleContext context, int x, int y, int z) { + var currentChunk = context.getCurrentChunk(); + var currentChunkX = currentChunk.getX(); + var currentChunkZ = currentChunk.getZ(); + var dimInfo = currentChunk.getDimensionInfo(); + + if (x >= currentChunkX * 16 && x < currentChunkX * 16 + 16 && + z >= currentChunkZ * 16 && z < currentChunkZ * 16 + 16 && + y >= dimInfo.minHeight() && y <= dimInfo.maxHeight()) { + return currentChunk.getBlockEntity(x & 15, y, z & 15); + } else { + var chunk = context.getChunkSource().getChunk(x >> 4, z >> 4); + return chunk == null ? null : chunk.getBlockEntity(x & 15, y, z & 15); + } } @Override diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayServerWorld.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayServerWorld.java index 70404a59f..fd493b328 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayServerWorld.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayServerWorld.java @@ -27,6 +27,11 @@ public Chunk getChunkAt(int x, int z) { @Override public void setBlockState(int x, int y, int z, BlockState data, boolean physics) { + var dimensionInfo = allayDimension.getDimensionInfo(); + if (y < dimensionInfo.minHeight() || y > dimensionInfo.maxHeight()) { + return; + } + // In dimension#setBlockState() method, Water will be moved to layer 1 if it is placed at layer 0 allayDimension.setBlockState(x, y, z, ((AllayBlockState) data).allayBlockState()); } @@ -44,7 +49,7 @@ public BlockState getBlockState(int x, int y, int z) { @Override public BlockEntity getBlockEntity(int x, int y, int z) { - return null; + return new AllayBlockEntity(allayDimension.getBlockEntity(x, y, z)); } @Override diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayWorldProperties.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayWorldProperties.java new file mode 100644 index 000000000..f28b5c250 --- /dev/null +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/delegate/AllayWorldProperties.java @@ -0,0 +1,42 @@ +package com.dfsek.terra.allay.delegate; + +import com.dfsek.terra.api.world.info.WorldProperties; + +import org.allaymc.api.world.data.DimensionInfo; + + +/** + * @author daoge_cmd + */ +public class AllayWorldProperties implements WorldProperties { + + private final Object fakeHandle; + private final long seed; + private final DimensionInfo dimensionInfo; + + public AllayWorldProperties(long seed, DimensionInfo dimensionInfo) { + this.fakeHandle = new Object(); + this.seed = seed; + this.dimensionInfo = dimensionInfo; + } + + @Override + public long getSeed() { + return this.seed; + } + + @Override + public int getMaxHeight() { + return dimensionInfo.maxHeight(); + } + + @Override + public int getMinHeight() { + return dimensionInfo.minHeight(); + } + + @Override + public Object getHandle() { + return fakeHandle; + } +} diff --git a/platforms/allay/src/main/java/com/dfsek/terra/allay/generator/AllayGeneratorWrapper.java b/platforms/allay/src/main/java/com/dfsek/terra/allay/generator/AllayGeneratorWrapper.java index af27fee32..81baf6e1b 100644 --- a/platforms/allay/src/main/java/com/dfsek/terra/allay/generator/AllayGeneratorWrapper.java +++ b/platforms/allay/src/main/java/com/dfsek/terra/allay/generator/AllayGeneratorWrapper.java @@ -1,18 +1,19 @@ package com.dfsek.terra.allay.generator; +import com.dfsek.terra.allay.Mapping; +import com.dfsek.terra.allay.delegate.AllayWorldProperties; + +import com.google.common.base.Preconditions; import org.allaymc.api.utils.AllayStringUtils; import org.allaymc.api.world.biome.BiomeType; import org.allaymc.api.world.chunk.UnsafeChunk; +import org.allaymc.api.world.data.DimensionInfo; import org.allaymc.api.world.generator.WorldGenerator; import org.allaymc.api.world.generator.context.NoiseContext; import org.allaymc.api.world.generator.context.PopulateContext; import org.allaymc.api.world.generator.function.Noiser; import org.allaymc.api.world.generator.function.Populator; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; - import com.dfsek.terra.allay.TerraAllayPlugin; import com.dfsek.terra.allay.delegate.AllayProtoChunk; import com.dfsek.terra.allay.delegate.AllayProtoWorld; @@ -30,27 +31,23 @@ */ public class AllayGeneratorWrapper implements GeneratorWrapper { + protected static final String OPTION_META_PACK_NAME = "meta-pack"; protected static final String OPTION_PACK_NAME = "pack"; protected static final String OPTION_SEED = "seed"; - protected final BiomeProvider biomeProvider; protected final long seed; protected final WorldGenerator allayWorldGenerator; - protected ChunkGenerator chunkGenerator; + protected ConfigPack configPack; + protected ChunkGenerator chunkGenerator; + protected BiomeProvider biomeProvider; + protected WorldProperties worldProperties; protected AllayServerWorld allayServerWorld; public AllayGeneratorWrapper(String preset) { - Map options = AllayStringUtils.parseOptions(preset); - String packName = options.get(OPTION_PACK_NAME); - if(packName == null) { - throw new IllegalArgumentException("Missing config pack name"); - } - this.seed = Long.parseLong(options.getOrDefault(OPTION_SEED, "0")); - this.configPack = getConfigPack(packName); - this.chunkGenerator = createGenerator(this.configPack); - this.biomeProvider = this.configPack.getBiomeProvider(); + var options = AllayStringUtils.parseOptions(preset); + this.seed = parseSeed(options.get(OPTION_SEED)); this.allayWorldGenerator = WorldGenerator .builder() .name("TERRA") @@ -59,40 +56,52 @@ public AllayGeneratorWrapper(String preset) { .populators(new AllayPopulator()) .onDimensionSet(dimension -> { this.allayServerWorld = new AllayServerWorld(this, dimension); - this.worldProperties = new WorldProperties() { - - private final Object fakeHandle = new Object(); + this.worldProperties = new AllayWorldProperties(this.seed, dimension.getDimensionInfo()); - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return dimension.getDimensionInfo().maxHeight(); - } + var metaPackName = options.get(OPTION_META_PACK_NAME); + if (metaPackName != null) { + setConfigPack(getConfigPackByMeta(metaPackName, dimension.getDimensionInfo())); + return; + } - @Override - public int getMinHeight() { - return dimension.getDimensionInfo().minHeight(); - } + var packName = options.get(OPTION_PACK_NAME); + if(packName != null) { + setConfigPack(getConfigPackById(packName)); + return; + } - @Override - public Object getHandle() { - return fakeHandle; - } - }; + throw new IllegalArgumentException("Either 'pack' or 'meta-pack' option should be specified in the generator preset!"); }) .build(); } - protected static ConfigPack getConfigPack(String packName) { - Optional byId = TerraAllayPlugin.PLATFORM.getConfigRegistry().getByID(packName); - return byId.orElseGet( - () -> TerraAllayPlugin.PLATFORM.getConfigRegistry().getByID(packName.toUpperCase(Locale.ENGLISH)) - .orElseThrow(() -> new IllegalArgumentException("Cant find terra config pack named " + packName)) - ); + protected static long parseSeed(String str) { + if(str == null) { + return 0; + } + + try { + return Long.parseLong(str); + } catch(NumberFormatException e) { + // Return the hashcode of the string if it cannot be parsed to a long value directly + return str.hashCode(); + } + } + + protected static ConfigPack getConfigPackById(String packId) { + return TerraAllayPlugin.platform + .getConfigRegistry() + .getByID(packId) + .orElseThrow(() -> new IllegalArgumentException("Cant find terra config pack named " + packId)); + } + + protected static ConfigPack getConfigPackByMeta(String metaPackId, DimensionInfo dimensionInfo) { + return TerraAllayPlugin.platform + .getMetaConfigRegistry() + .getByID(metaPackId) + .orElseThrow(() -> new IllegalArgumentException("Cant find terra meta pack named " + metaPackId)) + .packs() + .get(Mapping.dimensionIdBeToJe(dimensionInfo.toString())); } protected static ChunkGenerator createGenerator(ConfigPack configPack) { @@ -101,7 +110,7 @@ protected static ChunkGenerator createGenerator(ConfigPack configPack) { @Override public ChunkGenerator getHandle() { - return chunkGenerator; + return this.chunkGenerator; } public BiomeProvider getBiomeProvider() { @@ -113,8 +122,10 @@ public ConfigPack getConfigPack() { } public void setConfigPack(ConfigPack configPack) { + Preconditions.checkNotNull(configPack, "Config pack cannot be null!"); this.configPack = configPack; this.chunkGenerator = createGenerator(this.configPack); + this.biomeProvider = this.configPack.getBiomeProvider(); } public long getSeed() { @@ -165,7 +176,7 @@ public boolean apply(PopulateContext context) { generationStage.populate(tmp); } } catch(Exception e) { - TerraAllayPlugin.INSTANCE.getPluginLogger().error("Error while populating chunk", e); + TerraAllayPlugin.instance.getPluginLogger().error("Error while populating chunk", e); } return true; }