public class RandomSpawnManager {
private static final List<BlockType> unsafeBody = ImmutableList.of(
BlockTypes.AIR,
BlockTypes.CACTUS,
BlockTypes.FIRE,
BlockTypes.LAVA,
BlockTypes.FLOWING_LAVA,
BlockTypes.WATER,
BlockTypes.FLOWING_WATER
);
private final RandomSpawn plugin;
private final Logger logger;
private final Random random;
private final HashMap<String, List<Location<World>>> spawns;
private int maxArea;
RandomSpawnManager(RandomSpawn plugin) {
this.plugin = plugin;
this.logger = plugin.getLogger();
this.random = new Random();
this.spawns = new HashMap<>();
}
void init(ConfigurationLoader<CommentedConfigurationNode> localLoader) {
try {
ConfigurationOptions options = ConfigurationOptions.defaults()
.setShouldCopyDefaults(true);
CommentedConfigurationNode node = localLoader.load(options);
this.maxArea = (int) node.getNode("spawnArea", "maxArea").getValue(2000);
localLoader.save(node);
} catch (IOException e) {
this.logger.warn("Error saving default config!", e);
}
}
public void generationSpawnLocations(Player p) {
List<Location<World>> locs = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Location<World> loc;
do {
loc = getRandomLocation(p.getWorld());
} while (!isValidFloor(loc));
locs.add(loc);
this.logger.info("final loc: " + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ());
}
spawns.put(p.getName(), locs);
this.toSpawn(p, 0);
}
public void toSpawn(Player p, int index) {
Location<World> location = (this.spawns.get(p.getName())).get(index);
p.setLocation(location);
}
private Location<World> getRandomLocation(World world) {
int[] pos = {this.random.nextInt(this.maxArea + 1), this.random.nextInt(this.maxArea + 1)};
for (int i = 0; i < 2; i++) {
if (this.random.nextBoolean()) {
int r = this.random.nextInt(pos.length);
if (this.random.nextBoolean()) {
pos[r] = -pos[r];
} else {
pos[r] = Math.abs(pos[r]);
}
}
}
Location<World> loc = new Location<>(world, pos[0], 70, pos[1]);
world.loadChunk(loc.getPosition().toInt(), true);
Optional<Location<World>> safeLocation = Sponge.getGame().getTeleportHelper().getSafeLocation(loc, 20, 20);
if (safeLocation.isPresent()) {
loc = safeLocation.get();
this.logger.info("safeLocation get!");
}
return loc;
}
private boolean isValidFloor(Location loc) {
return (loc != null) && (!unsafeBody.contains(loc.getBlockType()));
}
public HashMap<String, List<Location<World>>> getSpawns() {
return this.spawns;
}
}