mirror of
https://github.com/RonanPlugins/BetterRTP.git
synced 2026-02-16 02:21:06 +00:00
random loc class remapped + Chunk based rtp'ing
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -7,7 +7,7 @@
|
|||||||
<groupId>me.SuperRonanCraft</groupId>
|
<groupId>me.SuperRonanCraft</groupId>
|
||||||
<artifactId>BetterRTP</artifactId>
|
<artifactId>BetterRTP</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>3.6.2</version>
|
<version>4.0.0-DEVBUILD</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ public enum RTPCommandType {
|
|||||||
//SETTINGS(new CmdSettings(), true),
|
//SETTINGS(new CmdSettings(), true),
|
||||||
TEST(new CmdTest(), true),
|
TEST(new CmdTest(), true),
|
||||||
VERSION(new CmdVersion()),
|
VERSION(new CmdVersion()),
|
||||||
WORLD(new CmdWorld());
|
WORLD(new CmdWorld()),
|
||||||
|
DEV(new CmdDeveloper(), true);
|
||||||
|
|
||||||
private final RTPCommand cmd;
|
private final RTPCommand cmd;
|
||||||
private boolean debugOnly = false;
|
private boolean debugOnly = false;
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package me.SuperRonanCraft.BetterRTP.player.commands.types;
|
||||||
|
|
||||||
|
import me.SuperRonanCraft.BetterRTP.player.commands.RTPCommand;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.RandomLocation;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdDeveloper implements RTPCommand {
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "dev";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(CommandSender sendi, String label, String[] args) {
|
||||||
|
RandomLocation.runChunkTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public List<String> tabComplete(CommandSender sendi, String[] args) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean permission(CommandSender sendi) {
|
||||||
|
return sendi.getName().equalsIgnoreCase("SuperRonanCraft") || sendi.getName().equalsIgnoreCase("RonanCrafts");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void usage(CommandSender sendi, String label) {
|
||||||
|
sendi.sendMessage("This is for Developement use only!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package me.SuperRonanCraft.BetterRTP.player.rtp;
|
package me.SuperRonanCraft.BetterRTP.player.rtp;
|
||||||
|
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
||||||
import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_FindLocationEvent;
|
import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_FindLocationEvent;
|
||||||
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueData;
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueData;
|
||||||
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueHandler;
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueHandler;
|
||||||
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WORLD_TYPE;
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.RandomLocation;
|
||||||
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldPlayer;
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldPlayer;
|
||||||
import io.papermc.lib.PaperLib;
|
import org.bukkit.Bukkit;
|
||||||
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
import org.bukkit.Chunk;
|
||||||
import org.apache.commons.lang.UnhandledException;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.*;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public class RTPPlayer {
|
|||||||
if (queueData != null)
|
if (queueData != null)
|
||||||
loc = queueData.getLocation();
|
loc = queueData.getLocation();
|
||||||
else
|
else
|
||||||
loc = WorldPlayer.generateLocation(worldPlayer);
|
loc = RandomLocation.generateLocation(worldPlayer);
|
||||||
}
|
}
|
||||||
attempts++; //Add an attempt
|
attempts++; //Add an attempt
|
||||||
//Load chunk and find out if safe location (asynchronously)
|
//Load chunk and find out if safe location (asynchronously)
|
||||||
@@ -69,6 +69,7 @@ public class RTPPlayer {
|
|||||||
attempt(sendi, loc);
|
attempt(sendi, loc);
|
||||||
});
|
});
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
|
//Legacy non-async support
|
||||||
attempt(sendi, loc);
|
attempt(sendi, loc);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ public class RTPPlayer {
|
|||||||
|
|
||||||
private void attempt(CommandSender sendi, Location loc) {
|
private void attempt(CommandSender sendi, Location loc) {
|
||||||
Location tpLoc;
|
Location tpLoc;
|
||||||
tpLoc = getSafeLocation(worldPlayer.getWorldtype(), worldPlayer.getWorld(), loc, worldPlayer.getMinY(), worldPlayer.getMaxY(), worldPlayer.getBiomes());
|
tpLoc = RandomLocation.getSafeLocation(worldPlayer.getWorldtype(), worldPlayer.getWorld(), loc, worldPlayer.getMinY(), worldPlayer.getMaxY(), worldPlayer.getBiomes());
|
||||||
attemptedLocations.add(loc);
|
attemptedLocations.add(loc);
|
||||||
//Valid location?
|
//Valid location?
|
||||||
if (tpLoc != null && checkDepends(tpLoc)) {
|
if (tpLoc != null && checkDepends(tpLoc)) {
|
||||||
@@ -97,14 +98,6 @@ public class RTPPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Location getSafeLocation(WORLD_TYPE type, World world, Location loc, int minY, int maxY, List<String> biomes) {
|
|
||||||
switch (type) { //Get a Y position and check for bad blocks
|
|
||||||
case NETHER: return getLocAtNether(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes);
|
|
||||||
case NORMAL:
|
|
||||||
default: return getLocAtNormal(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compressed code for MaxAttempts being met
|
// Compressed code for MaxAttempts being met
|
||||||
private void metMax(CommandSender sendi, Player p) {
|
private void metMax(CommandSender sendi, Player p) {
|
||||||
settings.teleport.failedTeleport(p, sendi);
|
settings.teleport.failedTeleport(p, sendi);
|
||||||
@@ -112,67 +105,10 @@ public class RTPPlayer {
|
|||||||
getPl().getpInfo().getRtping().put(p, false);
|
getPl().getpInfo().getRtping().put(p, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Location getLocAtNormal(int x, int z, int minY, int maxY, World world, List<String> biomes) {
|
|
||||||
Block b = world.getHighestBlockAt(x, z);
|
|
||||||
if (b.getType().toString().endsWith("AIR")) //1.15.1 or less
|
|
||||||
b = world.getBlockAt(x, b.getY() - 1, z);
|
|
||||||
else if (!b.getType().isSolid()) { //Water, lava, shrubs...
|
|
||||||
if (!badBlock(b.getType().name(), x, z, world, null)) { //Make sure it's not an invalid block (ex: water, lava...)
|
|
||||||
//int y = world.getHighestBlockYAt(x, z);
|
|
||||||
b = world.getBlockAt(x, b.getY() - 1, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Between max and min y
|
|
||||||
if ( b.getY() >= minY
|
|
||||||
&& b.getY() <= maxY
|
|
||||||
&& !badBlock(b.getType().name(), x, z, world, biomes)) {
|
|
||||||
return new Location(world, x, b.getY() + 1, z);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Location getLocAtNether(int x, int z, int minY, int maxY, World world, List<String> biomes) {
|
|
||||||
//Max and Min Y
|
|
||||||
for (int y = minY + 1; y < maxY/*world.getMaxHeight()*/; y++) {
|
|
||||||
Block block_current = world.getBlockAt(x, y, z);
|
|
||||||
if (block_current.getType().name().endsWith("AIR") || !block_current.getType().isSolid()) {
|
|
||||||
if (!block_current.getType().name().endsWith("AIR") &&
|
|
||||||
!block_current.getType().isSolid()) { //Block is not a solid (ex: lava, water...)
|
|
||||||
String block_in = block_current.getType().name();
|
|
||||||
if (badBlock(block_in, x, z, world, null))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String block = world.getBlockAt(x, y - 1, z).getType().name();
|
|
||||||
if (block.endsWith("AIR")) //Block below is air, skip
|
|
||||||
continue;
|
|
||||||
if (world.getBlockAt(x, y + 1, z).getType().name().endsWith("AIR") //Head space
|
|
||||||
&& !badBlock(block, x, z, world, biomes)) //Valid block
|
|
||||||
return new Location(world, x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean checkDepends(Location loc) {
|
public static boolean checkDepends(Location loc) {
|
||||||
return RTPPluginValidation.checkLocation(loc);
|
return RTPPluginValidation.checkLocation(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad blocks, or bad biome
|
|
||||||
public static boolean badBlock(String block, int x, int z, World world, List<String> biomes) {
|
|
||||||
for (String currentBlock : BetterRTP.getInstance().getRTP().blockList) //Check Block
|
|
||||||
if (currentBlock.toUpperCase().equals(block))
|
|
||||||
return true;
|
|
||||||
//Check Biomes
|
|
||||||
if (biomes == null || biomes.isEmpty())
|
|
||||||
return false;
|
|
||||||
String biomeCurrent = world.getBiome(x, z).name();
|
|
||||||
for (String biome : biomes)
|
|
||||||
if (biomeCurrent.toUpperCase().contains(biome.toUpperCase()))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
//FALSE MEANS NO BAD BLOCKS/BIOME WHERE FOUND!
|
|
||||||
}
|
|
||||||
|
|
||||||
private BetterRTP getPl() {
|
private BetterRTP getPl() {
|
||||||
return BetterRTP.getInstance();
|
return BetterRTP.getInstance();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package me.SuperRonanCraft.BetterRTP.references.database;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.player.playerdata.PlayerData;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueData;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueGenerator;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.RTPWorld;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class DatabaseChunkData extends SQLite {
|
||||||
|
|
||||||
|
public DatabaseChunkData() {
|
||||||
|
super(DATABASE_TYPE.CHUNK_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTables() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
list.add("ChunkData");
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum COLUMNS {
|
||||||
|
ID("id", "integer PRIMARY KEY AUTOINCREMENT"),
|
||||||
|
//Chunk Data
|
||||||
|
WORLD("world", "varchar(32)"),
|
||||||
|
X("x", "long"),
|
||||||
|
Z("z", "long"),
|
||||||
|
BIOME("biome", "string"),
|
||||||
|
MAX_Y("max_y", "integer"),
|
||||||
|
;
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
public final String type;
|
||||||
|
|
||||||
|
COLUMNS(String name, String type) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addChunk(Chunk chunk, int maxy, Biome biome) {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> {
|
||||||
|
String pre = "INSERT OR REPLACE INTO ";
|
||||||
|
String sql = pre + tables.get(0) + " ("
|
||||||
|
+ COLUMNS.WORLD.name + ", "
|
||||||
|
+ COLUMNS.X.name + ", "
|
||||||
|
+ COLUMNS.Z.name + ", "
|
||||||
|
+ COLUMNS.BIOME.name + ", "
|
||||||
|
+ COLUMNS.MAX_Y.name + " "
|
||||||
|
+ ") VALUES(?, ?, ?, ?, ?)";
|
||||||
|
List<Object> params = new ArrayList<Object>() {{
|
||||||
|
add(chunk.getWorld().getName());
|
||||||
|
add(chunk.getX());
|
||||||
|
add(chunk.getZ());
|
||||||
|
add(biome.name());
|
||||||
|
add(maxy);
|
||||||
|
}};
|
||||||
|
sqlUpdate(sql, params);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package me.SuperRonanCraft.BetterRTP.references.database;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.RandomLocation;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
public class DatabaseHandler {
|
public class DatabaseHandler {
|
||||||
@@ -9,12 +10,14 @@ public class DatabaseHandler {
|
|||||||
@Getter private final DatabasePlayers databasePlayers = new DatabasePlayers();
|
@Getter private final DatabasePlayers databasePlayers = new DatabasePlayers();
|
||||||
@Getter private final DatabaseCooldowns databaseCooldowns = new DatabaseCooldowns();
|
@Getter private final DatabaseCooldowns databaseCooldowns = new DatabaseCooldowns();
|
||||||
@Getter private final DatabaseQueue databaseQueue = new DatabaseQueue();
|
@Getter private final DatabaseQueue databaseQueue = new DatabaseQueue();
|
||||||
|
@Getter private final DatabaseChunkData databaseChunks = new DatabaseChunkData();
|
||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> {
|
||||||
databasePlayers.load();
|
databasePlayers.load();
|
||||||
databaseCooldowns.load();
|
databaseCooldowns.load();
|
||||||
databaseQueue.load();
|
databaseQueue.load();
|
||||||
|
databaseChunks.load();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,4 +33,8 @@ public class DatabaseHandler {
|
|||||||
return BetterRTP.getInstance().getDatabaseHandler().getDatabaseQueue();
|
return BetterRTP.getInstance().getDatabaseHandler().getDatabaseQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DatabaseChunkData getChunks() {
|
||||||
|
return BetterRTP.getInstance().getDatabaseHandler().getDatabaseChunks();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package me.SuperRonanCraft.BetterRTP.references.database;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.RandomLocation;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -112,6 +113,7 @@ public abstract class SQLite {
|
|||||||
|
|
||||||
private Enum<?>[] getColumns(DATABASE_TYPE type) {
|
private Enum<?>[] getColumns(DATABASE_TYPE type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case CHUNK_DATA: return DatabaseChunkData.COLUMNS.values();
|
||||||
case PLAYERS: return DatabasePlayers.COLUMNS.values();
|
case PLAYERS: return DatabasePlayers.COLUMNS.values();
|
||||||
case QUEUE: return DatabaseQueue.COLUMNS.values();
|
case QUEUE: return DatabaseQueue.COLUMNS.values();
|
||||||
case COOLDOWN:
|
case COOLDOWN:
|
||||||
@@ -121,6 +123,7 @@ public abstract class SQLite {
|
|||||||
|
|
||||||
private String getColumnName(DATABASE_TYPE type, Enum<?> column) {
|
private String getColumnName(DATABASE_TYPE type, Enum<?> column) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case CHUNK_DATA: return ((DatabaseChunkData.COLUMNS) column).name;
|
||||||
case PLAYERS: return ((DatabasePlayers.COLUMNS) column).name;
|
case PLAYERS: return ((DatabasePlayers.COLUMNS) column).name;
|
||||||
case QUEUE: return ((DatabaseQueue.COLUMNS) column).name;
|
case QUEUE: return ((DatabaseQueue.COLUMNS) column).name;
|
||||||
case COOLDOWN:
|
case COOLDOWN:
|
||||||
@@ -130,6 +133,7 @@ public abstract class SQLite {
|
|||||||
|
|
||||||
private String getColumnType(DATABASE_TYPE type, Enum<?> column) {
|
private String getColumnType(DATABASE_TYPE type, Enum<?> column) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case CHUNK_DATA: return ((DatabaseChunkData.COLUMNS) column).type;
|
||||||
case PLAYERS: return ((DatabasePlayers.COLUMNS) column).type;
|
case PLAYERS: return ((DatabasePlayers.COLUMNS) column).type;
|
||||||
case QUEUE: return ((DatabaseQueue.COLUMNS) column).type;
|
case QUEUE: return ((DatabaseQueue.COLUMNS) column).type;
|
||||||
case COOLDOWN:
|
case COOLDOWN:
|
||||||
@@ -230,5 +234,6 @@ public abstract class SQLite {
|
|||||||
PLAYERS,
|
PLAYERS,
|
||||||
COOLDOWN,
|
COOLDOWN,
|
||||||
QUEUE,
|
QUEUE,
|
||||||
|
CHUNK_DATA,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,13 +149,13 @@ public class QueueGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addQueue(RTPWorld rtpWorld, String id, ReQueueData reQueueData) {
|
private void addQueue(RTPWorld rtpWorld, String id, ReQueueData reQueueData) {
|
||||||
Location loc = WorldPlayer.generateLocation(rtpWorld);
|
Location loc = RandomLocation.generateLocation(rtpWorld);
|
||||||
if (loc != null) {
|
if (loc != null) {
|
||||||
Bukkit.getScheduler().runTask(BetterRTP.getInstance(), () -> {
|
Bukkit.getScheduler().runTask(BetterRTP.getInstance(), () -> {
|
||||||
//BetterRTP.debug("Queued up a new position, attempts " + reQueueData.attempts);
|
//BetterRTP.debug("Queued up a new position, attempts " + reQueueData.attempts);
|
||||||
PaperLib.getChunkAtAsync(loc)
|
PaperLib.getChunkAtAsync(loc)
|
||||||
.thenAccept(v -> {
|
.thenAccept(v -> {
|
||||||
Location safeLoc = RTPPlayer.getSafeLocation(
|
Location safeLoc = RandomLocation.getSafeLocation(
|
||||||
HelperRTP.getWorldType(rtpWorld.getWorld()),
|
HelperRTP.getWorldType(rtpWorld.getWorld()),
|
||||||
loc.getWorld(),
|
loc.getWorld(),
|
||||||
loc,
|
loc,
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package me.SuperRonanCraft.BetterRTP.references.rtpinfo;
|
||||||
|
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.BetterRTP;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.RTPWorld;
|
||||||
|
import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WORLD_TYPE;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class RandomLocation {
|
||||||
|
|
||||||
|
public static Location generateLocation(RTPWorld rtpWorld) {
|
||||||
|
Location loc;
|
||||||
|
switch (rtpWorld.getShape()) {
|
||||||
|
case CIRCLE: loc = generateRound(rtpWorld); break;
|
||||||
|
case SQUARE:
|
||||||
|
default: loc = generateSquare(rtpWorld); break;
|
||||||
|
}
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location generateSquare(RTPWorld rtpWorld) {
|
||||||
|
//Generate a random X and Z based off the quadrant selected
|
||||||
|
int min = rtpWorld.getMinRadius();
|
||||||
|
int max = rtpWorld.getMaxRadius() - min;
|
||||||
|
int x, z;
|
||||||
|
int quadrant = new Random().nextInt(4);
|
||||||
|
try {
|
||||||
|
switch (quadrant) {
|
||||||
|
case 0: // Positive X and Z
|
||||||
|
x = new Random().nextInt(max) + min;
|
||||||
|
z = new Random().nextInt(max) + min;
|
||||||
|
break;
|
||||||
|
case 1: // Negative X and Z
|
||||||
|
x = -new Random().nextInt(max) - min;
|
||||||
|
z = -(new Random().nextInt(max) + min);
|
||||||
|
break;
|
||||||
|
case 2: // Negative X and Positive Z
|
||||||
|
x = -new Random().nextInt(max) - min;
|
||||||
|
z = new Random().nextInt(max) + min;
|
||||||
|
break;
|
||||||
|
default: // Positive X and Negative Z
|
||||||
|
x = new Random().nextInt(max) + min;
|
||||||
|
z = -(new Random().nextInt(max) + min);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
BetterRTP.getInstance().getLogger().warning("A bounding location was negative! Please check your config only has positive x/z for max/min radius!");
|
||||||
|
BetterRTP.getInstance().getLogger().warning("Max: " + rtpWorld.getMaxRadius() + " Min: " + rtpWorld.getMinRadius());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
x += rtpWorld.getCenterX();
|
||||||
|
z += rtpWorld.getCenterZ();
|
||||||
|
//System.out.println(quadrant);
|
||||||
|
return new Location(rtpWorld.getWorld(), x, 69, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location generateRound(RTPWorld rtpWorld) {
|
||||||
|
//Generate a random X and Z based off location on a spiral curve
|
||||||
|
int min = rtpWorld.getMinRadius();
|
||||||
|
int max = rtpWorld.getMaxRadius() - min;
|
||||||
|
int x, z;
|
||||||
|
|
||||||
|
double area = Math.PI * (max - min) * (max + min); //of all the area in this donut
|
||||||
|
double subArea = area * new Random().nextDouble(); //pick a random subset of that area
|
||||||
|
|
||||||
|
double r = Math.sqrt(subArea/Math.PI + min * min); //convert area to radius
|
||||||
|
double theta = (r - (int) r) * 2 * Math.PI; //use the remainder as an angle
|
||||||
|
|
||||||
|
// polar to cartesian
|
||||||
|
x = (int) (r * Math.cos(theta));
|
||||||
|
z = (int) (r * Math.sin(theta));
|
||||||
|
x += rtpWorld.getCenterX();
|
||||||
|
z += rtpWorld.getCenterZ();
|
||||||
|
return new Location(rtpWorld.getWorld(), x, 69, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Location getSafeLocation(WORLD_TYPE type, World world, Location loc, int minY, int maxY, List<String> biomes) {
|
||||||
|
switch (type) { //Get a Y position and check for bad blocks
|
||||||
|
case NETHER: return getLocAtNether(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes);
|
||||||
|
case NORMAL:
|
||||||
|
default: return getLocAtNormal(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Location getLocAtNormal(int x, int z, int minY, int maxY, World world, List<String> biomes) {
|
||||||
|
Block b = getHighestBlock(x, z, world);
|
||||||
|
if (!b.getType().isSolid()) { //Water, lava, shrubs...
|
||||||
|
if (!badBlock(b.getType().name(), x, z, world, null)) { //Make sure it's not an invalid block (ex: water, lava...)
|
||||||
|
//int y = world.getHighestBlockYAt(x, z);
|
||||||
|
b = world.getBlockAt(x, b.getY() - 1, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Between max and min y
|
||||||
|
if ( b.getY() >= minY
|
||||||
|
&& b.getY() <= maxY
|
||||||
|
&& !badBlock(b.getType().name(), x, z, world, biomes)) {
|
||||||
|
return new Location(world, x, b.getY() + 1, z);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Block getHighestBlock(int x, int z, World world) {
|
||||||
|
Block b = world.getHighestBlockAt(x, z);
|
||||||
|
if (b.getType().toString().endsWith("AIR")) //1.15.1 or less
|
||||||
|
b = world.getBlockAt(x, b.getY() - 1, z);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Location getLocAtNether(int x, int z, int minY, int maxY, World world, List<String> biomes) {
|
||||||
|
//Max and Min Y
|
||||||
|
for (int y = minY + 1; y < maxY/*world.getMaxHeight()*/; y++) {
|
||||||
|
Block block_current = world.getBlockAt(x, y, z);
|
||||||
|
if (block_current.getType().name().endsWith("AIR") || !block_current.getType().isSolid()) {
|
||||||
|
if (!block_current.getType().name().endsWith("AIR") &&
|
||||||
|
!block_current.getType().isSolid()) { //Block is not a solid (ex: lava, water...)
|
||||||
|
String block_in = block_current.getType().name();
|
||||||
|
if (badBlock(block_in, x, z, world, null))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String block = world.getBlockAt(x, y - 1, z).getType().name();
|
||||||
|
if (block.endsWith("AIR")) //Block below is air, skip
|
||||||
|
continue;
|
||||||
|
if (world.getBlockAt(x, y + 1, z).getType().name().endsWith("AIR") //Head space
|
||||||
|
&& !badBlock(block, x, z, world, biomes)) //Valid block
|
||||||
|
return new Location(world, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bad blocks, or bad biome
|
||||||
|
public static boolean badBlock(String block, int x, int z, World world, List<String> biomes) {
|
||||||
|
for (String currentBlock : BetterRTP.getInstance().getRTP().getBlockList()) //Check Block
|
||||||
|
if (currentBlock.equalsIgnoreCase(block))
|
||||||
|
return true;
|
||||||
|
//Check Biomes
|
||||||
|
if (biomes == null || biomes.isEmpty())
|
||||||
|
return false;
|
||||||
|
String biomeCurrent = world.getBiome(x, z).name();
|
||||||
|
for (String biome : biomes)
|
||||||
|
if (biomeCurrent.toUpperCase().contains(biome.toUpperCase()))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
//FALSE MEANS NO BAD BLOCKS/BIOME WHERE FOUND!
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runChunkTest() {
|
||||||
|
BetterRTP.getInstance().getLogger().info("---------------- Starting chunk test!");
|
||||||
|
World world = Bukkit.getWorld("world");
|
||||||
|
cacheChunkAt(world, 32, -32, -32, -32);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cacheTask(World world, int goal, int start, int xat, int zat) {
|
||||||
|
zat += 1;
|
||||||
|
if (zat > goal) {
|
||||||
|
zat = start;
|
||||||
|
xat += 1;
|
||||||
|
}
|
||||||
|
if (xat <= goal)
|
||||||
|
cacheChunkAt(world, goal, start, xat, zat);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cacheChunkAt(World world, int goal, int start, int xat, int zat) {
|
||||||
|
CompletableFuture<Chunk> task = PaperLib.getChunkAtAsync(new Location(world, xat * 16, 0, zat * 16));
|
||||||
|
task.thenAccept(chunk -> {
|
||||||
|
try {
|
||||||
|
ChunkSnapshot snapshot = chunk.getChunkSnapshot(true, true, false);
|
||||||
|
int maxy = snapshot.getHighestBlockYAt(8, 8);
|
||||||
|
Biome biome = snapshot.getBiome(8, 8);
|
||||||
|
//BetterRTP.getInstance().getLogger().info("Added " + chunk.getX() + " " + chunk.getZ());
|
||||||
|
BetterRTP.getInstance().getDatabaseHandler().getDatabaseChunks().addChunk(chunk, maxy, biome);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException();
|
||||||
|
//BetterRTP.getInstance().getLogger().info("Tried Adding " + chunk.getX() + " " + chunk.getZ());
|
||||||
|
}
|
||||||
|
}).thenRun(() -> cacheTask(world, goal, start, xat, zat));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -114,73 +114,6 @@ public class WorldPlayer implements RTPWorld, RTPWorld_Defaulted {
|
|||||||
return _zLoc >= _zLMax && (_zLoc <= _zLMin || _zLoc >= _zRMin) && _zLoc <= _zRMax;
|
return _zLoc >= _zLMax && (_zLoc <= _zLMin || _zLoc >= _zRMin) && _zLoc <= _zRMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Location generateLocation(RTPWorld rtpWorld) {
|
|
||||||
Location loc;
|
|
||||||
switch (rtpWorld.getShape()) {
|
|
||||||
case CIRCLE: loc = generateRound(rtpWorld); break;
|
|
||||||
case SQUARE:
|
|
||||||
default: loc = generateSquare(rtpWorld); break;
|
|
||||||
}
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Location generateSquare(RTPWorld rtpWorld) {
|
|
||||||
//Generate a random X and Z based off the quadrant selected
|
|
||||||
int min = rtpWorld.getMinRadius();
|
|
||||||
int max = rtpWorld.getMaxRadius() - min;
|
|
||||||
int x, z;
|
|
||||||
int quadrant = new Random().nextInt(4);
|
|
||||||
try {
|
|
||||||
switch (quadrant) {
|
|
||||||
case 0: // Positive X and Z
|
|
||||||
x = new Random().nextInt(max) + min;
|
|
||||||
z = new Random().nextInt(max) + min;
|
|
||||||
break;
|
|
||||||
case 1: // Negative X and Z
|
|
||||||
x = -new Random().nextInt(max) - min;
|
|
||||||
z = -(new Random().nextInt(max) + min);
|
|
||||||
break;
|
|
||||||
case 2: // Negative X and Positive Z
|
|
||||||
x = -new Random().nextInt(max) - min;
|
|
||||||
z = new Random().nextInt(max) + min;
|
|
||||||
break;
|
|
||||||
default: // Positive X and Negative Z
|
|
||||||
x = new Random().nextInt(max) + min;
|
|
||||||
z = -(new Random().nextInt(max) + min);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
BetterRTP.getInstance().getLogger().warning("A bounding location was negative! Please check your config only has positive x/z for max/min radius!");
|
|
||||||
BetterRTP.getInstance().getLogger().warning("Max: " + rtpWorld.getMaxRadius() + " Min: " + rtpWorld.getMinRadius());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
x += rtpWorld.getCenterX();
|
|
||||||
z += rtpWorld.getCenterZ();
|
|
||||||
//System.out.println(quadrant);
|
|
||||||
return new Location(rtpWorld.getWorld(), x, 69, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Location generateRound(RTPWorld rtpWorld) {
|
|
||||||
//Generate a random X and Z based off location on a spiral curve
|
|
||||||
int min = rtpWorld.getMinRadius();
|
|
||||||
int max = rtpWorld.getMaxRadius() - min;
|
|
||||||
int x, z;
|
|
||||||
|
|
||||||
double area = Math.PI * (max - min) * (max + min); //of all the area in this donut
|
|
||||||
double subArea = area * new Random().nextDouble(); //pick a random subset of that area
|
|
||||||
|
|
||||||
double r = Math.sqrt(subArea/Math.PI + min * min); //convert area to radius
|
|
||||||
double theta = (r - (int) r) * 2 * Math.PI; //use the remainder as an angle
|
|
||||||
|
|
||||||
// polar to cartesian
|
|
||||||
x = (int) (r * Math.cos(theta));
|
|
||||||
z = (int) (r * Math.sin(theta));
|
|
||||||
x += rtpWorld.getCenterX();
|
|
||||||
z += rtpWorld.getCenterZ();
|
|
||||||
return new Location(rtpWorld.getWorld(), x, 69, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
|
|||||||
Reference in New Issue
Block a user