feat(pocket-base): add mob spawning toggle
This commit is contained in:
@@ -66,6 +66,10 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
&& arguments[1].equalsIgnoreCase("upgrade")) {
|
||||
return purchasePocketUpgrade(player, state);
|
||||
}
|
||||
if (arguments.length == 3 && arguments[0].equalsIgnoreCase("pocket")
|
||||
&& arguments[1].equalsIgnoreCase("mobs")) {
|
||||
return updatePocketMobSpawning(player, arguments[2]);
|
||||
}
|
||||
if (arguments.length == 2 && arguments[0].equalsIgnoreCase("visitors")) {
|
||||
return updateVisitors(player, state, arguments[1]);
|
||||
}
|
||||
@@ -176,6 +180,37 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updatePocketMobSpawning(Player player, String mode) {
|
||||
if (pocketBases == null) {
|
||||
player.sendMessage(ChatColor.RED + "Pocket Bases are currently unavailable.");
|
||||
return true;
|
||||
}
|
||||
PocketBaseState current = pocketBases.state(player.getUniqueId());
|
||||
if (current.level() < 1) {
|
||||
player.sendMessage(ChatColor.RED + "Pocket Base I is still locked.");
|
||||
return true;
|
||||
}
|
||||
Boolean enabled = enabledMode(mode);
|
||||
if (enabled == null) {
|
||||
sendUsage(player);
|
||||
return true;
|
||||
}
|
||||
final PocketBaseState updated;
|
||||
try {
|
||||
updated = pocketBases.setMobSpawning(player.getUniqueId(), enabled);
|
||||
} catch (IOException | RuntimeException exception) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The Pocket Base mob-spawning setting could not be changed.");
|
||||
return true;
|
||||
}
|
||||
player.sendMessage(ChatColor.YELLOW + "Pocket Base mob spawning is now "
|
||||
+ (updated.mobSpawningEnabled()
|
||||
? ChatColor.GREEN + "enabled"
|
||||
: ChatColor.RED + "disabled")
|
||||
+ ChatColor.YELLOW + ".");
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateVisitors(Player player, PlayerState state, String mode) {
|
||||
if (state.baseLevel() < 4) {
|
||||
player.sendMessage(ChatColor.RED + "Base IV visitor access is still locked.");
|
||||
@@ -408,14 +443,17 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
|
||||
private void showPocketPath(Player player, PlayerState owner) {
|
||||
int level = pocketBases == null ? 0 : pocketBases.state(owner.playerId()).level();
|
||||
int price = level == 0
|
||||
PocketBaseState pocket = pocketBases == null
|
||||
? PocketBaseState.locked(owner.playerId())
|
||||
: pocketBases.state(owner.playerId());
|
||||
int price = pocket.level() == 0
|
||||
? settings.current().pocketBaseUnlockCost()
|
||||
: settings.current().pocketBaseUpgradeCost();
|
||||
player.sendMessage(colorForPrerequisite(owner.baseLevel() >= 4 && owner.base().isPresent())
|
||||
+ "Pocket Base " + level + ": " + ChatColor.GRAY + price + " "
|
||||
+ "Pocket Base " + pocket.level() + ": " + ChatColor.GRAY + price + " "
|
||||
+ settings.current().pocketBaseCurrencyMaterial().toLowerCase(Locale.ROOT)
|
||||
+ " → /basesettings pocket upgrade");
|
||||
+ " → /basesettings pocket upgrade; mob spawning="
|
||||
+ (pocket.mobSpawningEnabled() ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
private void showCooldownPath(Player player, PlayerState state) {
|
||||
@@ -447,13 +485,18 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
List<String> modes = arguments[0].equalsIgnoreCase("visitors")
|
||||
? VISITOR_MODES
|
||||
: switch (arguments[0].toLowerCase(Locale.ROOT)) {
|
||||
case "pocket" -> List.of("upgrade");
|
||||
case "pocket" -> List.of("upgrade", "mobs");
|
||||
case "navigation", "flight", "border", "spawnable", "bossbar" -> ENABLE_MODES;
|
||||
default -> List.of();
|
||||
};
|
||||
String prefix = arguments[1].toLowerCase(Locale.ROOT);
|
||||
return modes.stream().filter(mode -> mode.startsWith(prefix)).toList();
|
||||
}
|
||||
if (arguments.length == 3 && arguments[0].equalsIgnoreCase("pocket")
|
||||
&& arguments[1].equalsIgnoreCase("mobs")) {
|
||||
String prefix = arguments[2].toLowerCase(Locale.ROOT);
|
||||
return ENABLE_MODES.stream().filter(mode -> mode.startsWith(prefix)).toList();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@@ -513,8 +556,8 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private static void sendUsage(Player player) {
|
||||
player.sendMessage(ChatColor.RED + "Usage: /basesettings "
|
||||
+ "[status|upgrade|pocket upgrade|visitors <allowed|blocked>"
|
||||
+ "|navigation <enable|disable>"
|
||||
+ "[status|upgrade|pocket upgrade|pocket mobs <enable|disable>"
|
||||
+ "|visitors <allowed|blocked>|navigation <enable|disable>"
|
||||
+ "|flight <enable|disable>|border <enable|disable>"
|
||||
+ "|spawnable <enable|disable>|bossbar <enable|disable>]");
|
||||
}
|
||||
|
||||
@@ -60,6 +60,27 @@ final class PocketBaseManager {
|
||||
}
|
||||
}
|
||||
|
||||
PocketBaseState setMobSpawning(UUID ownerId, boolean enabled) throws IOException {
|
||||
PocketBaseState current = states.state(ownerId);
|
||||
if (current.level() < 1) {
|
||||
throw new IllegalStateException("Pocket Base I is still locked");
|
||||
}
|
||||
worlds.setMobSpawning(ownerId, enabled);
|
||||
try {
|
||||
return states.updateAndSave(
|
||||
ownerId,
|
||||
state -> state.withMobSpawningEnabled(enabled)
|
||||
);
|
||||
} catch (IOException | RuntimeException exception) {
|
||||
try {
|
||||
worlds.setMobSpawning(ownerId, current.mobSpawningEnabled());
|
||||
} catch (RuntimeException rollbackFailure) {
|
||||
exception.addSuppressed(rollbackFailure);
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
Optional<UUID> ownerForPocketWorld(UUID worldId) {
|
||||
return worlds.ownerForWorld(worldId);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import java.util.UUID;
|
||||
public record PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance
|
||||
Optional<PocketPortalLocation> entrance,
|
||||
boolean mobSpawningEnabled
|
||||
) {
|
||||
public PocketBaseState {
|
||||
if (ownerId == null) {
|
||||
@@ -21,19 +22,31 @@ public record PocketBaseState(
|
||||
}
|
||||
}
|
||||
|
||||
public PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance
|
||||
) {
|
||||
this(ownerId, level, entrance, false);
|
||||
}
|
||||
|
||||
public static PocketBaseState locked(UUID ownerId) {
|
||||
return new PocketBaseState(ownerId, 0, Optional.empty());
|
||||
return new PocketBaseState(ownerId, 0, Optional.empty(), false);
|
||||
}
|
||||
|
||||
public PocketBaseState withLevel(int newLevel) {
|
||||
return new PocketBaseState(ownerId, newLevel, entrance);
|
||||
return new PocketBaseState(ownerId, newLevel, entrance, mobSpawningEnabled);
|
||||
}
|
||||
|
||||
public PocketBaseState withEntrance(PocketPortalLocation portal) {
|
||||
return new PocketBaseState(ownerId, level, Optional.of(portal));
|
||||
return new PocketBaseState(ownerId, level, Optional.of(portal), mobSpawningEnabled);
|
||||
}
|
||||
|
||||
public PocketBaseState withoutEntrance() {
|
||||
return new PocketBaseState(ownerId, level, Optional.empty());
|
||||
return new PocketBaseState(ownerId, level, Optional.empty(), mobSpawningEnabled);
|
||||
}
|
||||
|
||||
public PocketBaseState withMobSpawningEnabled(boolean enabled) {
|
||||
return new PocketBaseState(ownerId, level, entrance, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ final class PocketBaseWorldService {
|
||||
void loadExisting(Map<UUID, PocketBaseState> states) {
|
||||
for (PocketBaseState state : states.values()) {
|
||||
if (state.level() > 0) {
|
||||
ensureWorld(state.ownerId());
|
||||
setMobSpawning(state.ownerId(), state.mobSpawningEnabled());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,10 @@ final class PocketBaseWorldService {
|
||||
return ensureWorld(ownerId);
|
||||
}
|
||||
|
||||
void setMobSpawning(UUID ownerId, boolean enabled) {
|
||||
ensureWorld(ownerId).setSpawnFlags(enabled, enabled);
|
||||
}
|
||||
|
||||
Location arrival(UUID ownerId) {
|
||||
return new Location(ensureWorld(ownerId), 0.5, PLATFORM_Y + 1, 5.5, 180.0f, 0.0f);
|
||||
}
|
||||
@@ -90,7 +94,8 @@ final class PocketBaseWorldService {
|
||||
private World ensureWorld(UUID ownerId) {
|
||||
String name = worldName(ownerId);
|
||||
World world = server.getWorld(name);
|
||||
if (world == null) {
|
||||
boolean created = world == null;
|
||||
if (created) {
|
||||
WorldCreator creator = new WorldCreator(name)
|
||||
.environment(World.Environment.NORMAL)
|
||||
.generator(new VoidPocketChunkGenerator())
|
||||
@@ -100,6 +105,9 @@ final class PocketBaseWorldService {
|
||||
if (world == null) {
|
||||
throw new IllegalStateException("Could not create Pocket Base world " + name);
|
||||
}
|
||||
if (created) {
|
||||
world.setSpawnFlags(false, false);
|
||||
}
|
||||
ownersByWorld.put(world.getUID(), ownerId);
|
||||
return world;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ public final class YamlPocketBaseRepository {
|
||||
PocketBaseState state = new PocketBaseState(
|
||||
ownerId,
|
||||
level,
|
||||
loadPortal(yaml, path + ".entrance")
|
||||
loadPortal(yaml, path + ".entrance"),
|
||||
yaml.getBoolean(path + ".mob-spawning-enabled", false)
|
||||
);
|
||||
states.put(ownerId, state);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
@@ -61,6 +62,7 @@ public final class YamlPocketBaseRepository {
|
||||
for (PocketBaseState state : states.values()) {
|
||||
String path = "owners." + state.ownerId();
|
||||
yaml.set(path + ".level", state.level());
|
||||
yaml.set(path + ".mob-spawning-enabled", state.mobSpawningEnabled());
|
||||
state.entrance().ifPresent(portal -> savePortal(yaml, path + ".entrance", portal));
|
||||
}
|
||||
Path temporary = Files.createTempFile(parent, "spigot-base-pocket-", ".yml");
|
||||
|
||||
Reference in New Issue
Block a user