Untitled

 avatar
unknown
plain_text
9 months ago
9.1 kB
10
Indexable
package dev.nighter.teaWorldBiome.world;

import dev.nighter.teaWorldBiome.TeaWorldBiome;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo;
import org.jspecify.annotations.NullMarked;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@NullMarked
public class WorldManager {
    private final TeaWorldBiome plugin;
    private final Map<String, String> worldBiomeMap = new ConcurrentHashMap<>();
    private final Set<String> availableBiomes;

    public WorldManager(TeaWorldBiome plugin) {
        this.plugin = plugin;
        this.availableBiomes = initializeAvailableBiomes();
    }

    public World createSingleBiomeWorld(String worldName, String biomeName) {
        if (!isValidBiome(biomeName)) {
            throw new IllegalArgumentException("Invalid biome: " + biomeName);
        }

        if (worldExists(worldName)) {
            throw new IllegalStateException("World already exists: " + worldName);
        }

        // Store the biome mapping for this world
        worldBiomeMap.put(worldName, biomeName.toUpperCase());

        try {
            // Create the world with custom biome provider and chunk generator
            WorldCreator creator = new WorldCreator(worldName);
            creator.type(WorldType.LARGE_BIOMES);

            creator.generateStructures(false);
            creator.biomeProvider(new SingleBiomeProvider(worldName, biomeName));
            creator.generator(new FlatTerrainGenerator()); // Custom generator without caves/water

            World world = creator.createWorld();

            if (world != null) {
                configureWorldForPvP(world);
            }

            assert world != null;
            return world;
        } catch (Exception e) {
            // Remove from map if creation failed
            worldBiomeMap.remove(worldName);
            plugin.getLogger().severe("Failed to create world " + worldName + ": " + e.getMessage());
            throw e;
        }
    }

    private void configureWorldForPvP(World world) {
        // Set world properties for PvP
        world.setSpawnFlags(false, false); // No monsters, no animals
        world.setAutoSave(true);
        world.setKeepSpawnInMemory(false);
        world.setDifficulty(Difficulty.HARD);
        world.setTime(6000); // Set to noon
        world.setGameRuleValue("doDaylightCycle", "true"); // Disable day/night cycle
        world.setGameRuleValue("doWeatherCycle", "true"); // Disable weather
        world.setGameRuleValue("doMobSpawning", "false"); // Disable mob spawning
        world.setGameRuleValue("announceAdvancements", "false"); // Disable advancement announcements
        world.setGameRuleValue("showDeathMessages", "true"); // Disable death messages for cleaner PvP
        world.setStorm(false); // Disable storms
        world.setThundering(false); // Disable thunder
    }

    public boolean worldExists(String worldName) {
        return Bukkit.getWorld(worldName) != null;
    }

    public boolean isValidBiome(String biomeName) {
        return availableBiomes.contains(biomeName.toUpperCase());
    }

    public Set<String> getAvailableBiomeNames() {
        return new HashSet<>(availableBiomes);
    }

    public String getWorldBiome(String worldName) {
        return worldBiomeMap.get(worldName);
    }

    public void removeWorldTracking(String worldName) {
        worldBiomeMap.remove(worldName);
    }

    public World getWorld(String worldName) {
        return Objects.requireNonNull(Bukkit.getWorld(worldName));
    }

    public boolean deleteWorld(String worldName) {
        World world = getWorld(worldName);

        // Unload the world first
        Bukkit.unloadWorld(world, false);

        // Remove the world from tracking
        removeWorldTracking(worldName);

        // Delete the world directory
        return Bukkit.getWorldContainer().delete();
    }

    private Set<String> initializeAvailableBiomes() {
        Set<String> biomes = new HashSet<>();

        for (org.bukkit.block.Biome biome : Registry.BIOME) {
            biomes.add(biome.getKey().getKey().toUpperCase());
        }

        return biomes;
    }

    public static class FlatTerrainGenerator extends ChunkGenerator {

        @Override
        public void generateNoise(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) {
            // Generate solid base terrain without caves
            for (int x = 0; x < 16; x++) {
                for (int z = 0; z < 16; z++) {

                    // Stone layers (no caves) - only underground
                    for (int y = 1; y < 60; y++) {
                        chunkData.setBlock(x, y, z, Material.STONE);
                    }

                    // Deepslate layers (no caves) - below stone
                    for (int y = -60; y < 1; y++) {
                        chunkData.setBlock(x, y, z, Material.DEEPSLATE);
                    }
                }
            }
        }

        @Override
        public void generateSurface(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) {
            // Let vanilla handle surface generation first
            super.generateSurface(worldInfo, random, chunkX, chunkZ, chunkData);

            // Then remove all water blocks at surface level and above
            removeWaterFromSurface(chunkData);
        }

        private void removeWaterFromSurface(ChunkData chunkData) {
            for (int x = 0; x < 16; x++) {
                for (int z = 0; z < 16; z++) {
                    // Check from 50 up to 100 blocks high
                    for (int y = 50; y < 100; y++) {
                        Material currentBlock = chunkData.getType(x, y, z);

                        // Remove water and replace with air
                        if (currentBlock == Material.WATER) {
                            chunkData.setBlock(x, y, z, Material.AIR);
                        }
                        // Also remove kelp, seagrass, and other water plants
                        else if (isWaterPlant(currentBlock)) {
                            chunkData.setBlock(x, y, z, Material.AIR);
                        }
                    }
                }
            }
        }

        private boolean isWaterPlant(Material material) {
            return material == Material.KELP ||
                    material == Material.KELP_PLANT ||
                    material == Material.SEAGRASS ||
                    material == Material.TALL_SEAGRASS ||
                    material == Material.SEA_PICKLE;
        }

        @Override
        public boolean shouldGenerateNoise() {
            return true;
        }

        @Override
        public boolean shouldGenerateSurface() {
            return true; // Changed to true to allow vanilla surface generation
        }

        @Override
        public boolean shouldGenerateBedrock() {
            return true;
        }

        @Override
        public boolean shouldGenerateCaves() {
            return false;
        }

        @Override
        public boolean shouldGenerateDecorations() {
            return true;
        }

        @Override
        public boolean shouldGenerateMobs() {
            return false;
        }

        @Override
        public boolean shouldGenerateStructures() {
            return false;
        }
    }

    public class SingleBiomeProvider extends BiomeProvider {
        private final String worldName;
        private final String biomeName;
        private final org.bukkit.block.Biome biome;

        public SingleBiomeProvider(String worldName, String biomeName) {
            this.worldName = worldName;
            this.biomeName = biomeName.toUpperCase();

            NamespacedKey biomeKey = NamespacedKey.minecraft(this.biomeName.toLowerCase());
            this.biome = Registry.BIOME.get(biomeKey);

            if (this.biome == null) {
                throw new IllegalArgumentException("Invalid biome: " + biomeName);
            }
        }

        @Override
        public org.bukkit.block.Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
            if (worldInfo.getName().equals(this.worldName)) {
                return this.biome;
            }

            return Registry.BIOME.get(NamespacedKey.minecraft("plains"));
        }

        @Override
        public List<org.bukkit.block.Biome> getBiomes(WorldInfo worldInfo) {
            if (worldInfo.getName().equals(this.worldName)) {
                return Collections.singletonList(this.biome);
            }

            List<org.bukkit.block.Biome> allBiomes = new ArrayList<>();
            Registry.BIOME.iterator().forEachRemaining(allBiomes::add);
            return allBiomes;
        }
    }
}
Editor is loading...
Leave a Comment