feat(border): add base boundary particles
This commit is contained in:
@@ -97,8 +97,8 @@ final class BaseAdminCommand implements CommandExecutor, TabCompleter {
|
||||
sender.sendMessage(ChatColor.GRAY + "In-base placements=" + player.blocksPlacedInBase()
|
||||
+ " breaks=" + player.blocksBrokenInBase());
|
||||
sender.sendMessage(ChatColor.GRAY + "Toggles: navigation=" + player.navigationEnabled()
|
||||
+ " flight=" + player.flightEnabled() + " bossbar=" + player.bossBarEnabled()
|
||||
+ " visitors=" + player.visitorsEnabled());
|
||||
+ " flight=" + player.flightEnabled() + " border=" + player.borderEnabled()
|
||||
+ " bossbar=" + player.bossBarEnabled() + " visitors=" + player.visitorsEnabled());
|
||||
sender.sendMessage(ChatColor.GRAY + "Base: " + player.base()
|
||||
.map(base -> base.worldName() + " " + base.x() + "," + base.y() + "," + base.z())
|
||||
.orElse("not set"));
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package games.dmg.spigotbase;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class BaseBorderController implements Runnable {
|
||||
private final Server server;
|
||||
private final BaseStateManager stateManager;
|
||||
private final BaseBoundsService boundsService;
|
||||
|
||||
BaseBorderController(
|
||||
Server server,
|
||||
BaseStateManager stateManager,
|
||||
BaseBoundsService boundsService
|
||||
) {
|
||||
this.server = server;
|
||||
this.stateManager = stateManager;
|
||||
this.boundsService = boundsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player player : server.getOnlinePlayers()) {
|
||||
PlayerState state = stateManager.player(player.getUniqueId(), player.getName());
|
||||
if (!state.borderEnabled() || state.base().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
BaseLocation base = state.base().orElseThrow();
|
||||
if (!player.getWorld().getUID().equals(base.worldId())) {
|
||||
continue;
|
||||
}
|
||||
Location playerLocation = player.getLocation();
|
||||
long minimumY = (long) base.y() - boundsService.verticalRange(state);
|
||||
long maximumY = (long) base.y() + boundsService.verticalRange(state);
|
||||
if (playerLocation.getY() < minimumY || playerLocation.getY() > maximumY) {
|
||||
continue;
|
||||
}
|
||||
for (BaseBorderGeometry.Point point : BaseBorderGeometry.visiblePoints(
|
||||
base.x() + 0.5,
|
||||
base.z() + 0.5,
|
||||
boundsService.radius(state),
|
||||
playerLocation.getX(),
|
||||
playerLocation.getZ()
|
||||
)) {
|
||||
Location particle = new Location(
|
||||
player.getWorld(),
|
||||
point.x(),
|
||||
playerLocation.getY() + 0.15,
|
||||
point.z()
|
||||
);
|
||||
player.spawnParticle(
|
||||
Particle.END_ROD,
|
||||
particle,
|
||||
1,
|
||||
0.0, 0.0, 0.0, 0.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package games.dmg.spigotbase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
final class BaseBorderGeometry {
|
||||
static final int MAX_PARTICLES = 64;
|
||||
static final double VISIBILITY_DISTANCE = 32.0;
|
||||
private static final double PARTICLE_SPACING = 1.0;
|
||||
|
||||
private BaseBorderGeometry() {
|
||||
}
|
||||
|
||||
static List<Point> visiblePoints(
|
||||
double centerX,
|
||||
double centerZ,
|
||||
int radius,
|
||||
double playerX,
|
||||
double playerZ
|
||||
) {
|
||||
if (radius <= 0) {
|
||||
throw new IllegalArgumentException("border radius must be positive");
|
||||
}
|
||||
double playerRadius = Math.hypot(playerX - centerX, playerZ - centerZ);
|
||||
if (Math.abs(playerRadius - radius) > VISIBILITY_DISTANCE) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
double circumference = 2.0 * Math.PI * radius;
|
||||
int count = Math.min(MAX_PARTICLES, Math.max(1, (int) Math.ceil(
|
||||
circumference / PARTICLE_SPACING
|
||||
)));
|
||||
double centerAngle = Math.atan2(playerZ - centerZ, playerX - centerX);
|
||||
double angleStep = circumference <= MAX_PARTICLES * PARTICLE_SPACING
|
||||
? 2.0 * Math.PI / count
|
||||
: PARTICLE_SPACING / radius;
|
||||
double startAngle = circumference <= MAX_PARTICLES * PARTICLE_SPACING
|
||||
? 0.0
|
||||
: centerAngle - angleStep * (count - 1) / 2.0;
|
||||
|
||||
List<Point> points = new ArrayList<>(count);
|
||||
double visibilitySquared = VISIBILITY_DISTANCE * VISIBILITY_DISTANCE;
|
||||
for (int index = 0; index < count; index++) {
|
||||
double angle = startAngle + angleStep * index;
|
||||
double x = centerX + radius * Math.cos(angle);
|
||||
double z = centerZ + radius * Math.sin(angle);
|
||||
double deltaX = x - playerX;
|
||||
double deltaZ = z - playerZ;
|
||||
if (deltaX * deltaX + deltaZ * deltaZ <= visibilitySquared) {
|
||||
points.add(new Point(x, z));
|
||||
}
|
||||
}
|
||||
return List.copyOf(points);
|
||||
}
|
||||
|
||||
record Point(double x, double z) {
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
private static final List<String> SETTINGS = List.of(
|
||||
"status", "upgrade", "visitors", "navigation", "flight", "bossbar"
|
||||
"status", "upgrade", "visitors", "navigation", "flight", "border", "bossbar"
|
||||
);
|
||||
private static final List<String> VISITOR_MODES = List.of("allowed", "blocked");
|
||||
private static final List<String> ENABLE_MODES = List.of("enable", "disable");
|
||||
@@ -59,6 +59,9 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
if (arguments.length == 2 && arguments[0].equalsIgnoreCase("flight")) {
|
||||
return updateFlight(player, state, arguments[1]);
|
||||
}
|
||||
if (arguments.length == 2 && arguments[0].equalsIgnoreCase("border")) {
|
||||
return updateBorder(player, state, arguments[1]);
|
||||
}
|
||||
if (arguments.length == 2 && arguments[0].equalsIgnoreCase("bossbar")) {
|
||||
return updateBossBar(player, arguments[1]);
|
||||
}
|
||||
@@ -189,6 +192,29 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateBorder(Player player, PlayerState state, String mode) {
|
||||
if (state.baseLevel() < 1 || state.base().isEmpty()) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "Establish Base I before enabling border visualization.");
|
||||
return true;
|
||||
}
|
||||
Boolean enabled = enabledMode(mode);
|
||||
if (enabled == null) {
|
||||
sendUsage(player);
|
||||
return true;
|
||||
}
|
||||
state = stateManager.update(
|
||||
player.getUniqueId(),
|
||||
player.getName(),
|
||||
current -> current.withBorderEnabled(enabled)
|
||||
);
|
||||
stateManager.saveIfDirty();
|
||||
player.sendMessage(ChatColor.YELLOW + "Base border visualization is now "
|
||||
+ (state.borderEnabled() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled")
|
||||
+ ChatColor.YELLOW + ".");
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateBossBar(Player player, String mode) {
|
||||
Boolean enabled = enabledMode(mode);
|
||||
if (enabled == null) {
|
||||
@@ -218,6 +244,7 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
+ (state.visitorsEnabled() ? "allowed" : "blocked")
|
||||
+ " navigation=" + (state.navigationEnabled() ? "enabled" : "disabled")
|
||||
+ " flight=" + (state.flightEnabled() ? "enabled" : "disabled")
|
||||
+ " border=" + (state.borderEnabled() ? "enabled" : "disabled")
|
||||
+ " bossbar=" + (state.bossBarEnabled() ? "enabled" : "disabled"));
|
||||
state.base().ifPresentOrElse(
|
||||
base -> player.sendMessage(ChatColor.GRAY + "Base: " + base.worldName() + " "
|
||||
@@ -306,7 +333,7 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
List<String> modes = arguments[0].equalsIgnoreCase("visitors")
|
||||
? VISITOR_MODES
|
||||
: switch (arguments[0].toLowerCase(Locale.ROOT)) {
|
||||
case "navigation", "flight", "bossbar" -> ENABLE_MODES;
|
||||
case "navigation", "flight", "border", "bossbar" -> ENABLE_MODES;
|
||||
default -> List.of();
|
||||
};
|
||||
String prefix = arguments[1].toLowerCase(Locale.ROOT);
|
||||
@@ -372,6 +399,6 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
private static void sendUsage(Player player) {
|
||||
player.sendMessage(ChatColor.RED + "Usage: /basesettings "
|
||||
+ "[status|upgrade|visitors <allowed|blocked>|navigation <enable|disable>"
|
||||
+ "|flight <enable|disable>|bossbar <enable|disable>]");
|
||||
+ "|flight <enable|disable>|border <enable|disable>|bossbar <enable|disable>]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ public record PlayerState(
|
||||
boolean visitorsEnabled,
|
||||
Optional<Instant> lastBaseSet,
|
||||
Optional<Instant> lastBaseTeleport,
|
||||
Map<UUID, Instant> visitorCooldownUntil
|
||||
Map<UUID, Instant> visitorCooldownUntil,
|
||||
boolean borderEnabled
|
||||
) {
|
||||
public PlayerState {
|
||||
if (playerId == null) {
|
||||
@@ -69,12 +70,47 @@ public record PlayerState(
|
||||
if (baseLevel < 4 && visitorsEnabled) {
|
||||
throw new IllegalArgumentException("visitor access requires Base IV");
|
||||
}
|
||||
if (borderEnabled && (baseLevel < 1 || base.isEmpty())) {
|
||||
throw new IllegalArgumentException("border visualization requires an established Base I");
|
||||
}
|
||||
if (visitorCooldownUntil.entrySet().stream().anyMatch(entry ->
|
||||
entry.getKey() == null || entry.getValue() == null)) {
|
||||
throw new IllegalArgumentException("visitor cooldowns must be complete");
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerState(
|
||||
UUID playerId,
|
||||
String latestName,
|
||||
Optional<BaseLocation> base,
|
||||
int baseLevel,
|
||||
int sizeLevel,
|
||||
int flightLevel,
|
||||
int warmupLevel,
|
||||
int cooldownLevel,
|
||||
long grassAndDirtBroken,
|
||||
long stoneBroken,
|
||||
long deepslateBroken,
|
||||
long obsidianBroken,
|
||||
long blocksPlacedInBase,
|
||||
long blocksBrokenInBase,
|
||||
boolean navigationEnabled,
|
||||
boolean flightEnabled,
|
||||
boolean bossBarEnabled,
|
||||
boolean visitorsEnabled,
|
||||
Optional<Instant> lastBaseSet,
|
||||
Optional<Instant> lastBaseTeleport,
|
||||
Map<UUID, Instant> visitorCooldownUntil
|
||||
) {
|
||||
this(
|
||||
playerId, latestName, base, baseLevel, sizeLevel, flightLevel,
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, false
|
||||
);
|
||||
}
|
||||
|
||||
public static PlayerState newPlayer(UUID playerId, String latestName) {
|
||||
return new PlayerState(
|
||||
playerId,
|
||||
@@ -93,7 +129,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -103,7 +139,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, count, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,7 +149,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, enabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -123,7 +159,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
enabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -133,7 +169,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stone, deepslate,
|
||||
obsidian, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -143,7 +179,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, enabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -163,7 +199,7 @@ public record PlayerState(
|
||||
newWarmupLevel, newCooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, placements, breaks,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -179,7 +215,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, Optional.of(usedAt), visitorCooldownUntil
|
||||
lastBaseSet, Optional.of(usedAt), visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -189,7 +225,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -206,7 +242,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassDirt, stone, deepslate,
|
||||
obsidian, placements, baseBreaks,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -225,7 +261,8 @@ public record PlayerState(
|
||||
newWarmupLevel, newCooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
newNavigationEnabled, newFlightEnabled, bossBarEnabled, newVisitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil,
|
||||
borderEnabled && newBaseLevel >= 1 && base.isPresent()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -235,7 +272,17 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, enabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
public PlayerState withBorderEnabled(boolean enabled) {
|
||||
return new PlayerState(
|
||||
playerId, latestName, base, baseLevel, sizeLevel, flightLevel,
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, visitorCooldownUntil, enabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +294,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, cooldowns
|
||||
lastBaseSet, lastBaseTeleport, cooldowns, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -257,7 +304,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, Optional.empty(), visitorCooldownUntil
|
||||
lastBaseSet, Optional.empty(), visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -267,7 +314,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
lastBaseSet, lastBaseTeleport, Map.of()
|
||||
lastBaseSet, lastBaseTeleport, Map.of(), borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
@@ -277,7 +324,7 @@ public record PlayerState(
|
||||
warmupLevel, cooldownLevel, grassAndDirtBroken, stoneBroken, deepslateBroken,
|
||||
obsidianBroken, blocksPlacedInBase, blocksBrokenInBase,
|
||||
navigationEnabled, flightEnabled, bossBarEnabled, visitorsEnabled,
|
||||
Optional.of(setAt), lastBaseTeleport, visitorCooldownUntil
|
||||
Optional.of(setAt), lastBaseTeleport, visitorCooldownUntil, borderEnabled
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,12 @@ public final class SpigotBasePlugin extends JavaPlugin {
|
||||
10L,
|
||||
10L
|
||||
);
|
||||
getServer().getScheduler().runTaskTimer(
|
||||
this,
|
||||
new BaseBorderController(getServer(), stateManager, boundsService),
|
||||
10L,
|
||||
10L
|
||||
);
|
||||
getServer().getScheduler().runTaskTimer(this, flightController, 5L, 5L);
|
||||
getServer().getScheduler().runTaskTimer(this, stateManager::saveIfDirty, 600L, 600L);
|
||||
getLogger().info("Spigot Base enabled.");
|
||||
|
||||
@@ -127,7 +127,8 @@ public final class YamlBaseStateRepository {
|
||||
yaml.getBoolean(path + ".visitors-enabled", false),
|
||||
instant(yaml, path + ".last-base-set-epoch-millis"),
|
||||
instant(yaml, path + ".last-base-teleport-epoch-millis"),
|
||||
loadVisitorCooldowns(yaml, path + ".visitor-cooldowns")
|
||||
loadVisitorCooldowns(yaml, path + ".visitor-cooldowns"),
|
||||
yaml.getBoolean(path + ".border-enabled", false)
|
||||
);
|
||||
players.put(playerId, player);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
@@ -222,6 +223,7 @@ public final class YamlBaseStateRepository {
|
||||
yaml.set(path + ".flight-enabled", player.flightEnabled());
|
||||
yaml.set(path + ".boss-bar-enabled", player.bossBarEnabled());
|
||||
yaml.set(path + ".visitors-enabled", player.visitorsEnabled());
|
||||
yaml.set(path + ".border-enabled", player.borderEnabled());
|
||||
yaml.set(
|
||||
path + ".last-base-set-epoch-millis",
|
||||
player.lastBaseSet().map(Instant::toEpochMilli).orElse(null)
|
||||
|
||||
Reference in New Issue
Block a user