/* * Copyright or © or Copr. Amaury Carrade (2014 - 2016) * * http://amaury.carrade.eu * * This software is governed by the CeCILL-B license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-B * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-B license and that you accept its terms. */ package eu.carrade.amaury.UHCReloaded.spawns; import eu.carrade.amaury.UHCReloaded.UHCReloaded; import eu.carrade.amaury.UHCReloaded.UHConfig; import eu.carrade.amaury.UHCReloaded.spawns.exceptions.CannotGenerateSpawnPointsException; import eu.carrade.amaury.UHCReloaded.spawns.exceptions.UnknownGeneratorException; import eu.carrade.amaury.UHCReloaded.spawns.generators.SpawnPointsGenerator; import eu.carrade.amaury.UHCReloaded.utils.UHUtils; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.World.Environment; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.bukkit.util.Vector; public class SpawnsManager { private final boolean AVOID_WATER; private UHCReloaded p; private LinkedList<Location> spawnPoints = new LinkedList<>(); public SpawnsManager(UHCReloaded plugin) { this.p = plugin; AVOID_WATER = UHConfig.MAP.SPAWN_POINTS.DONT_GENERATE_ABOVE_WATER.get(); } /** * Adds a spawn point at (x;z) in the default world. * * @param vec The vector representing the X and Z coordinates. */ public void addSpawnPoint(final Vector vec) { addSpawnPoint(p.getServer().getWorlds().get(0), vec.getX(), vec.getZ()); } /** * Adds a spawn point at (x;z) in the default world. * * @param x The X coordinate. * @param z The Z coordinate. */ public void addSpawnPoint(final Double x, final Double z) { addSpawnPoint(p.getServer().getWorlds().get(0), x, z); } /** * Adds a spawn point at (x;z) in the given world. * * @param world The world. * @param x The X coordinate. * @param z The Z coordinate. */ public void addSpawnPoint(final World world, final Double x, final Double z) { addSpawnPoint(new Location(world, x, 0, z)); } /** * Adds a spawn point from a location. * * @param location The location. Cloned, so you can use the same location object with * modifications between two calls. * * @throws RuntimeException If the spawn point is in the Nether and no safe spot was * found. * @throws IllegalArgumentException If the spawn point is out of the current border. */ public void addSpawnPoint(final Location location) { Location spawnPoint = location.clone(); // Initial fall, except in the nether. if (!(spawnPoint.getWorld().getEnvironment() == Environment.NETHER)) { spawnPoint.setY(location.getWorld().getHighestBlockYAt(location.getBlockX(), location.getBlockZ()) + 120); } else { Location safeSpot = UHUtils.searchSafeSpot(location); if (safeSpot == null) { throw new RuntimeException("Unable to find a safe spot to set the spawn point " + location.toString()); } spawnPoint.setY(safeSpot.getY()); } if (!p.getBorderManager().isInsideBorder(spawnPoint)) { throw new IllegalArgumentException("The given spawn location is outside the current border"); } spawnPoints.add(spawnPoint); } /** * Returns the registered spawn points. * * @return The spawn points. */ public List<Location> getSpawnPoints() { return spawnPoints; } /** * Removes all spawn points with the same coordinates as the given location object (X, Z, * world). * * @param location The location to be removed. * @param precise If true, only the spawn points at the exact same location will be removed. * Else, the points in the same block. * * @return true if something were removed. */ public boolean removeSpawnPoint(Location location, boolean precise) { List<Location> toRemove = new LinkedList<>(); for (Location spawn : getSpawnPoints()) { if (location.getWorld().equals(spawn.getWorld())) { if (precise && location.getX() == spawn.getX() && location.getZ() == spawn.getZ()) { toRemove.add(spawn); } else if (!precise && location.getBlockX() == spawn.getBlockX() && location.getBlockZ() == spawn.getBlockZ()) { toRemove.add(spawn); } } } for (Location spawnToRemove : toRemove) { // Used to remove all occurrences of the spawn point while (spawnPoints.remove(spawnToRemove)) ; } return toRemove.size() != 0; } /** * Removes all registered spawn points. * * CANNOT BE CANCELLED. */ public void reset() { spawnPoints.clear(); } /** * Imports spawn points from the configuration. * * @return The number of spawn points imported. */ public int importSpawnPointsFromConfig() { int spawnCount = 0; for (Vector position: UHConfig.SPAWN_POINTS) { addSpawnPoint(position); ++spawnCount; } return spawnCount; } /** * Generates spawn points with the given generator. * * @param generatorName The generator to use. * @param world The world where the spawn points will be generated. * @param spawnCount The number of spawn points to generate. * @param regionDiameter The diameter of the region where the spawn points will * be generated.<br> This is limited by the size of the * map. This will be seen as the diameter of a circular * or of a squared map, following the shape of the world * set in the configuration. * @param minimalDistanceBetweenTwoPoints The minimal distance between two points. * @param xCenter The x coordinate of the point in the center of the * region where the points will be generated. * @param zCenter The z coordinate of the point in the center of the * region where the points will be generated. * * @throws CannotGenerateSpawnPointsException In case of fail. * @throws UnknownGeneratorException If no generator was found by the given name. */ public void generateSpawnPoints(String generatorName, World world, int spawnCount, int regionDiameter, int minimalDistanceBetweenTwoPoints, double xCenter, double zCenter) throws CannotGenerateSpawnPointsException, UnknownGeneratorException { Generator generator = Generator.fromString(generatorName); if (generator != null) { generateSpawnPoints(generator, world, spawnCount, regionDiameter, minimalDistanceBetweenTwoPoints, xCenter, zCenter); } else { throw new UnknownGeneratorException("The generator '" + generatorName + "' does not exists."); } } /** * Generates spawn points with the given generator. * * @param generator The generator to use. * @param world The world where the spawn points will be generated. * @param spawnCount The number of spawn points to generate. * @param regionDiameter The diameter of the region where the spawn points will * be generated.<br> This is limited by the size of the * map. This will be seen as the diameter of a circular * or of a squared map, following the shape of the world * set in the configuration. * @param minimalDistanceBetweenTwoPoints The minimal distance between two points. * @param xCenter The x coordinate of the point in the center of the * region where the points will be generated. * @param zCenter The z coordinate of the point in the center of the * region where the points will be generated. * * @throws CannotGenerateSpawnPointsException In case of fail. */ public void generateSpawnPoints(Generator generator, World world, int spawnCount, int regionDiameter, int minimalDistanceBetweenTwoPoints, double xCenter, double zCenter) throws CannotGenerateSpawnPointsException { generateSpawnPoints(generator.getInstance(), world, spawnCount, regionDiameter, minimalDistanceBetweenTwoPoints, xCenter, zCenter); } /** * Generates spawn points with the given generator. * * @param generator The generator to use. * @param world The world where the spawn points will be generated. * @param spawnCount The number of spawn points to generate. * @param regionDiameter The diameter of the region where the spawn points will * be generated.<br> This is limited by the size of the * map. This will be seen as the diameter of a circular * or of a squared map, following the shape of the world * set in the configuration. * @param minimalDistanceBetweenTwoPoints The minimal distance between two points. * @param xCenter The x coordinate of the point in the center of the * region where the points will be generated. * @param zCenter The z coordinate of the point in the center of the * region where the points will be generated. * * @throws CannotGenerateSpawnPointsException In case of fail. */ public void generateSpawnPoints(SpawnPointsGenerator generator, World world, int spawnCount, int regionDiameter, int minimalDistanceBetweenTwoPoints, double xCenter, double zCenter) throws CannotGenerateSpawnPointsException { Set<Location> spawnPoints = generator.generate(world, spawnCount, regionDiameter, minimalDistanceBetweenTwoPoints, xCenter, zCenter, AVOID_WATER); for (Location spawn : spawnPoints) { addSpawnPoint(spawn); } } }