Skip to content

[Suggestion]: changing biome configurations with using biome keys rather than bukkit enum. (example code provided) #1446

@Remodactyl

Description

@Remodactyl

This is a bit of a complex suggestion, and I'm only making it because I've (partially) coded this in myself into the magic plugin for my own purposes, though it's difficult for me to make out exactly what features would all be affected by this and where to make further adjustments.

Essentially, the Magic plugin currently cannot detect custom biomes (such as those added in datapacks), because the Bukkit Biome Enum does not support this, and simply returns "minecraft:custom" or Biome.CUSTOM.
but Minecraft does keep ResourceLocations for all biomes, usually something such as "minecraft:plains" or "datapack:my_custom_biome".
Since most uses of biomes are really just comparison checks, this could be easily done by matching the configured biomes with the returned keys from the biome resource locations.

I've done this by adding a getBlockBiome() method in the CompatibilityLib, and a getBiomeKey, to convert a Biome Enum to a valid minecraft biome key.

getBiomeKey:

@Override
    public String getBiomeKey(String biomeName) {
        String biomeKey;
        Biome bukkitBiome = null;
        try {
            bukkitBiome = Biome.valueOf(biomeName.trim().toUpperCase());
        } catch (Exception ignore) {
        }

        if (bukkitBiome != null) {
            biomeKey = bukkitBiome.getKey().getNamespace() + ":" + bukkitBiome.getKey().getKey();
            return biomeKey;
        }

        Server server = Bukkit.getServer();
        CraftServer craftServer = (CraftServer) server;
        DedicatedServer dedicatedServer = craftServer.getServer();
        MappedRegistry<net.minecraft.world.level.biome.Biome> biomes = (MappedRegistry<net.minecraft.world.level.biome.Biome>) dedicatedServer.registryAccess().registryOrThrow(Registries.BIOME);


        if (!biomeName.contains(":")) {
            biomeName = "minecraft:" + biomeName;
        }

        ResourceLocation biomeResource = ResourceLocation.tryParse(biomeName);
        if (biomes.containsKey(biomeResource)) {
            return biomeName;
        }

        Bukkit.getLogger().info("Failed to parse biome " + biomeName + " fully. Neither datapack, nor bukkit provided meaningful biome definition.");
        return "";
    }

getBlockBiome:


@Override
    public String getBlockBiome(Block block) {

        CraftWorld craftWorld = (CraftWorld) block.getWorld();
        ServerLevel nmsWorld = craftWorld.getHandle();

        Holder<net.minecraft.world.level.biome.Biome> biomeHolder = nmsWorld.getBiome(new BlockPos(block.getX(), block.getY(), block.getZ()));
        ResourceKey<net.minecraft.world.level.biome.Biome> resourceKey = biomeHolder.unwrapKey().get();

        String name = resourceKey.location().getNamespace() + ":" + resourceKey.location().getPath();
        Bukkit.getLogger().info("The retrieved biome key was: " + name);

        return name;
    }

(This was coded for the CompatibilityLib of 1.19.4)

I just coded this as a test, and it is a quick and dirty solution the way I have it set up currently, but it so far appears to be working okay.
If you wanted you could make a proper implementation of this idea.

Do with this as you wish. :)

Image Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions