/* * This file is a part of the SteamWar software. * * Copyright (C) 2023 SteamWar.de-Serverteam * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package de.steamwar.towerrun.config; import de.steamwar.sql.SchematicType; import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.winconditions.FirstOutsideWincondition; import de.steamwar.towerrun.winconditions.LastOutsideWincondition; import de.steamwar.towerrun.winconditions.LastRemainingWincondition; import de.steamwar.towerrun.winconditions.WinCondition; import lombok.Getter; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.util.Vector; import java.io.File; import java.util.ArrayList; import java.util.List; @UtilityClass public class WorldConfig { public static final Region[] REGIONS; public static final Location[] DOORS; public static final Location[] KEYS; public static final int LAVA_Y; public static final int LAVE_SPACE; public static final Location SPAWN; public static final int ESCAPE_HEIGHT; public static final Location MIN_TOWER; public static final Location MAX_TOWER; public static final List ACTIVE_WINCONDITIONS; public static final int MAP_MIN_X; public static final int MAP_MIN_Z; public static final int MAP_MAX_X; public static final int MAP_MAX_Z; public static final boolean MELTING; public static final TowerGeneratorConfig TOWER_GENERATOR_CONFIG; public static final List WINCONDITIONS = new ArrayList<>(); static { WINCONDITIONS.add(new LastRemainingWincondition()); WINCONDITIONS.add(new LastOutsideWincondition()); WINCONDITIONS.add(new FirstOutsideWincondition()); } private static Location parseLocation(ConfigurationSection section) { Location loc = new Location( Bukkit.getWorlds().get(0), section.getDouble("x"), section.getDouble("y"), section.getDouble("z") ); if (section.contains("yaw")) { loc.setYaw((float) section.getDouble("yaw")); } if (section.contains("pitch")) { loc.setPitch((float) section.getDouble("pitch")); } return loc; } static { File configFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "config.yml"); if (!configFile.exists()) { TowerRun.getInstance().getLogger().severe("World config not found!"); Bukkit.shutdown(); } ConfigurationSection config = YamlConfiguration.loadConfiguration(configFile); ConfigurationSection tower = config.getConfigurationSection("tower"); List regions = tower.getConfigurationSection("regions").getKeys(false).stream() .map(tower.getConfigurationSection("regions")::getConfigurationSection) .toList(); REGIONS = new Region[regions.size()]; for (int i = 0; i < regions.size(); i++) { REGIONS[i] = new Region(regions.get(i)); } if (REGIONS.length == 1) { MIN_TOWER = REGIONS[0].min; MAX_TOWER = REGIONS[0].max; } else { MIN_TOWER = new Location( Bukkit.getWorlds().get(0), Math.min(REGIONS[0].min.getX(), REGIONS[1].min.getX()), 0, Math.min(REGIONS[0].min.getZ(), REGIONS[1].min.getZ()) ); MAX_TOWER = new Location( Bukkit.getWorlds().get(0), Math.max(REGIONS[0].max.getX(), REGIONS[1].max.getX()), 255, Math.max(REGIONS[0].max.getZ(), REGIONS[1].max.getZ()) ); if (REGIONS.length > 2) { for (int i = 2; i < REGIONS.length; i++) { MIN_TOWER.setX(Math.min(MIN_TOWER.getX(), REGIONS[i].min.getX())); MIN_TOWER.setZ(Math.min(MIN_TOWER.getZ(), REGIONS[i].min.getZ())); MAX_TOWER.setX(Math.max(MAX_TOWER.getX(), REGIONS[i].max.getX())); MAX_TOWER.setZ(Math.max(MAX_TOWER.getZ(), REGIONS[i].max.getZ())); } } } ESCAPE_HEIGHT = tower.getInt("escapeHeight"); SPAWN = parseLocation(tower.getConfigurationSection("spawn")); ConfigurationSection doorSection = tower.getConfigurationSection("doors"); if (doorSection != null) { List doors = doorSection.getKeys(false).stream() .map(tower.getConfigurationSection("doors")::getConfigurationSection) .toList(); DOORS = new Location[doors.size()]; for (int i = 0; i < doors.size(); i++) { DOORS[i] = parseLocation(doors.get(i)); } } else { DOORS = new Location[0]; } ConfigurationSection keysSection = tower.getConfigurationSection("keys"); if (keysSection != null) { List keys = keysSection.getKeys(false).stream() .map(tower.getConfigurationSection("keys")::getConfigurationSection) .toList(); KEYS = new Location[keys.size()]; for (int i = 0; i < keys.size(); i++) { KEYS[i] = parseLocation(keys.get(i)); } } else { KEYS = new Location[0]; } LAVA_Y = tower.getInt("lavaY"); LAVE_SPACE = tower.getInt("laveSpace"); MAP_MIN_X = config.getInt("minX"); MAP_MIN_Z = config.getInt("minZ"); MAP_MAX_X = config.getInt("maxX"); MAP_MAX_Z = config.getInt("maxZ"); MELTING = tower.getBoolean("melting") || tower.contains("meltingBlocks"); // Backwards compatibility with meltingBlocks key! ACTIVE_WINCONDITIONS = config.getStringList("winconditions"); WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(winCondition -> winCondition.setActive(true)); ConfigurationSection towerGeneratorSection = config.getConfigurationSection("towerGenerator"); if (towerGeneratorSection == null) { TOWER_GENERATOR_CONFIG = null; } else { TOWER_GENERATOR_CONFIG = new TowerGeneratorConfig(towerGeneratorSection); } } @Getter public static final class Region { public final Location min; public final Location max; public Region(ConfigurationSection section) { min = new Location( Bukkit.getWorlds().get(0), section.getDouble("minX"), 0, section.getDouble("minZ") ); max = new Location( Bukkit.getWorlds().get(0), section.getDouble("maxX"), 255, section.getDouble("maxZ") ); } public boolean contains(Vector vector) { return vector.getX() >= min.getX() && vector.getX() <= max.getX() && vector.getZ() >= min.getZ() && vector.getZ() <= max.getZ(); } } @Getter public static final class TowerGeneratorConfig { public final int x; public final int y; public final int z; public final int minHeight; public final int maxHeight; public final int minNoBombFloors; public final int maxNoBombFloors; public final double tntChance; public final int minBombs; public final int maxBombs; public final double keyChance; public final int minNoKeyFloors; public final int maxNoKeyFloors; public final SchematicType schematicType; public final TowerGeneratorFillRegion[] fillRegions; public final Region[] tntRegions; public final TowerGeneratorDoorBlock[] doorBlocks; public TowerGeneratorConfig(ConfigurationSection section) { x = section.getInt("x"); y = section.getInt("y"); z = section.getInt("z"); minHeight = section.getInt("minHeight"); maxHeight = section.getInt("maxHeight"); minNoBombFloors = section.getInt("minNoBombFloors"); maxNoBombFloors = section.getInt("maxNoBombFloors"); minBombs = section.getInt("minBombs"); maxBombs = section.getInt("maxBombs"); tntChance = section.getDouble("tntChance"); keyChance = section.getDouble("keyChance"); minNoKeyFloors = section.getInt("minNoKeyFloors"); maxNoKeyFloors = section.getInt("maxNoKeyFloors"); schematicType = SchematicType.fromDB(section.getString("schematicType")); ConfigurationSection fillRegionsSection = section.getConfigurationSection("fillRegions"); if (fillRegionsSection != null) { List fillRegions = fillRegionsSection.getKeys(false).stream() .map(fillRegionsSection::getConfigurationSection) .toList(); this.fillRegions = new TowerGeneratorFillRegion[fillRegions.size()]; for (int i = 0; i < fillRegions.size(); i++) { this.fillRegions[i] = new TowerGeneratorFillRegion(fillRegions.get(i)); } } else { fillRegions = new TowerGeneratorFillRegion[0]; } ConfigurationSection tntRegionsSection = section.getConfigurationSection("tntRegions"); if (tntRegionsSection != null) { List tntRegions = tntRegionsSection.getKeys(false).stream() .map(tntRegionsSection::getConfigurationSection) .toList(); this.tntRegions = new Region[tntRegions.size()]; for (int i = 0; i < tntRegions.size(); i++) { this.tntRegions[i] = new Region(tntRegions.get(i)); } } else { tntRegions = new Region[0]; } ConfigurationSection doorBlocksSection = section.getConfigurationSection("doorBlocks"); if (doorBlocksSection != null) { List doorBlocks = doorBlocksSection.getKeys(false).stream() .map(doorBlocksSection::getConfigurationSection) .toList(); this.doorBlocks = new TowerGeneratorDoorBlock[doorBlocks.size()]; for (int i = 0; i < doorBlocks.size(); i++) { this.doorBlocks[i] = new TowerGeneratorDoorBlock(doorBlocks.get(i)); } } else { doorBlocks = new TowerGeneratorDoorBlock[0]; } } } @Getter public static final class TowerGeneratorFillRegion { private final int minX; private final int minZ; private final int maxX; private final int maxZ; private final double percentage; private final Material material; public TowerGeneratorFillRegion(ConfigurationSection section) { minX = section.getInt("minX"); minZ = section.getInt("minZ"); maxX = section.getInt("maxX"); maxZ = section.getInt("maxZ"); percentage = section.getDouble("percentage"); material = Material.valueOf(section.getString("material")); } } @Getter public static final class TowerGeneratorDoorBlock { private final int x; private final int dy; private final int z; public TowerGeneratorDoorBlock(ConfigurationSection section) { x = section.getInt("x"); dy = section.getInt("dy"); z = section.getInt("z"); } } }