feat(pocket-base): split hostile and passive mob spawning
This commit is contained in:
@@ -29,7 +29,7 @@ The plugin JAR is written to `build/libs/`.
|
|||||||
/basesettings status
|
/basesettings status
|
||||||
/basesettings upgrade
|
/basesettings upgrade
|
||||||
/basesettings pocket upgrade
|
/basesettings pocket upgrade
|
||||||
/basesettings pocket mobs <enable|disable>
|
/basesettings pocket mobs <hostile|passive> <enable|disable>
|
||||||
/basesettings pocket type <void|nether|overworld> <subtype>
|
/basesettings pocket type <void|nether|overworld> <subtype>
|
||||||
/basesettings visitors <allowed|blocked>
|
/basesettings visitors <allowed|blocked>
|
||||||
/basesettings navigation <enable|disable>
|
/basesettings navigation <enable|disable>
|
||||||
@@ -45,7 +45,7 @@ After 250 Survival-mode block placements anywhere by default, the spawnable over
|
|||||||
|
|
||||||
`/base` has a stationary warm-up. Looking around is allowed, while movement between blocks, damage, teleportation, world changes, death, logout, and conflicting teleport commands cancel it without consuming the cooldown.
|
`/base` has a stationary warm-up. Looking around is allowed, while movement between blocks, damage, teleportation, world changes, death, logout, and conflicting teleport commands cancel it without consuming the cooldown.
|
||||||
|
|
||||||
Base IV owners can purchase and expand a persistent Pocket Base with `/basesettings pocket upgrade`. Activating a complete diamond-block portal frame inside the normal base with flint and steel opens one public entrance to the owner's grass platform in a private void world. The owner can move the return portal by building and igniting another complete frame inside the unlocked Pocket Base boundary; only the newly activated return portal remains functional. Natural hostile and passive mob spawning is disabled by default and can be controlled by the owner with `/basesettings pocket mobs <enable|disable>`.
|
Base IV owners can purchase and expand a persistent Pocket Base with `/basesettings pocket upgrade`. Activating a complete diamond-block portal frame inside the normal base with flint and steel opens one public entrance to the owner's grass platform in a private void world. The owner can move the return portal by building and igniting another complete frame inside the unlocked Pocket Base boundary; only the newly activated return portal remains functional. Natural hostile and passive mob spawning is disabled by default. Owners can control each category independently with `/basesettings pocket mobs <hostile|passive> <enable|disable>`.
|
||||||
|
|
||||||
Owners can change biome metadata without altering Pocket Base blocks, entities, inventories, or portals by using `/basesettings pocket type <void|nether|overworld> <subtype>`. Void uses `the_void`; Nether and Overworld accept their compatible vanilla biome names, such as `crimson_forest` or `plains`. Each change defaults to 16 netherite blocks, is configurable, and affects applicable natural mob selection when spawning is enabled. The Pocket Base remains a void-generated normal-environment world; dimension-specific mechanics do not change.
|
Owners can change biome metadata without altering Pocket Base blocks, entities, inventories, or portals by using `/basesettings pocket type <void|nether|overworld> <subtype>`. Void uses `the_void`; Nether and Overworld accept their compatible vanilla biome names, such as `crimson_forest` or `plains`. Each change defaults to 16 netherite blocks, is configurable, and affects applicable natural mob selection when spawning is enabled. The Pocket Base remains a void-generated normal-environment world; dimension-specific mechanics do not change.
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -95,8 +95,9 @@ description: Chronological record of material decisions affecting the Spigot Bas
|
|||||||
## 2026-08-24 — Pocket Base mob-spawning control
|
## 2026-08-24 — Pocket Base mob-spawning control
|
||||||
|
|
||||||
- Disabled natural hostile and passive mob spawning by default in new and existing Pocket Bases without a saved preference.
|
- Disabled natural hostile and passive mob spawning by default in new and existing Pocket Bases without a saved preference.
|
||||||
- Added the persisted owner setting `/basesettings pocket mobs enable|disable`, contextual autocomplete, and status reporting.
|
- Added independent persisted owner settings through `/basesettings pocket mobs <hostile|passive> <enable|disable>`, contextual autocomplete, and status reporting.
|
||||||
- Reapplied saved spawn flags when Pocket Base worlds load and restored the prior world setting when persistence fails.
|
- Migrated each legacy combined mob-spawning preference to both categories to preserve existing behavior.
|
||||||
|
- Reapplied both saved spawn flags when Pocket Base worlds load and restored both prior world settings when persistence fails.
|
||||||
- Verified the feature with `./gradlew clean check jar`.
|
- Verified the feature with `./gradlew clean check jar`.
|
||||||
|
|
||||||
## 2026-08-24 — Relocatable Pocket Base return portals
|
## 2026-08-24 — Relocatable Pocket Base return portals
|
||||||
|
|||||||
@@ -1,25 +1,27 @@
|
|||||||
---
|
---
|
||||||
type: User Story
|
type: User Story
|
||||||
title: "US-018: Control Pocket Base mob spawning"
|
title: "US-018: Control Pocket Base mob spawning"
|
||||||
description: Let Pocket Base owners control natural mob spawning in their private world, with spawning disabled by default.
|
description: Let Pocket Base owners control hostile and passive natural mob spawning independently in their private world, with both disabled by default.
|
||||||
status: done
|
status: done
|
||||||
---
|
---
|
||||||
|
|
||||||
# US-018: Control Pocket Base mob spawning
|
# US-018: Control Pocket Base mob spawning
|
||||||
|
|
||||||
As a **Pocket Base owner**, I want to enable or disable natural mob spawning in my Pocket Base so that I can choose whether the private world supports normal mob activity.
|
As a **Pocket Base owner**, I want to enable or disable hostile and passive natural mob spawning independently in my Pocket Base so that I can choose which kinds of normal mob activity its private world supports.
|
||||||
|
|
||||||
## Acceptance criteria
|
## Acceptance criteria
|
||||||
|
|
||||||
- [x] Natural mob spawning is disabled by default in every new Pocket Base and in existing Pocket Bases that have no saved preference.
|
- [x] Hostile and passive natural mob spawning are both disabled by default in every new Pocket Base and in existing Pocket Bases that have no saved preference.
|
||||||
- [x] A Pocket Base owner can use `/basesettings pocket mobs enable|disable` to control natural mob spawning in their own Pocket Base.
|
- [x] A Pocket Base owner can use `/basesettings pocket mobs hostile enable|disable` to control hostile natural mob spawning in their own Pocket Base.
|
||||||
- [x] The setting controls both hostile and passive natural spawning only in the owner's Pocket Base.
|
- [x] A Pocket Base owner can use `/basesettings pocket mobs passive enable|disable` to control passive natural mob spawning in their own Pocket Base.
|
||||||
- [x] The command is unavailable until Pocket Base I is unlocked.
|
- [x] Changing one mob category does not change the other category.
|
||||||
- [x] The command and its modes are offered through contextual autocomplete.
|
- [x] The commands are unavailable until Pocket Base I is unlocked.
|
||||||
- [x] `/basesettings status` displays the current Pocket Base mob-spawning setting.
|
- [x] The commands, categories, and modes are offered through contextual autocomplete.
|
||||||
- [x] The preference persists across restarts and is reapplied when the Pocket Base world loads.
|
- [x] `/basesettings status` displays the current hostile and passive Pocket Base mob-spawning settings.
|
||||||
- [x] Disabling natural spawning does not remove existing mobs or prevent explicitly spawned or summoned mobs.
|
- [x] Both preferences persist across restarts and are reapplied when the Pocket Base world loads.
|
||||||
- [x] Persistence or world-application failures produce a clear failure message without reporting a successful change.
|
- [x] Existing saved `mob-spawning-enabled` values migrate to both category preferences, preserving prior behavior.
|
||||||
|
- [x] Disabling either natural-spawning category does not remove existing mobs or prevent explicitly spawned or summoned mobs.
|
||||||
|
- [x] Persistence or world-application failures produce a clear failure message, restore both prior world flags, and do not report a successful change.
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
|
|||||||
@@ -69,9 +69,9 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
&& arguments[1].equalsIgnoreCase("upgrade")) {
|
&& arguments[1].equalsIgnoreCase("upgrade")) {
|
||||||
return purchasePocketUpgrade(player, state);
|
return purchasePocketUpgrade(player, state);
|
||||||
}
|
}
|
||||||
if (arguments.length == 3 && arguments[0].equalsIgnoreCase("pocket")
|
if (arguments.length == 4 && arguments[0].equalsIgnoreCase("pocket")
|
||||||
&& arguments[1].equalsIgnoreCase("mobs")) {
|
&& arguments[1].equalsIgnoreCase("mobs")) {
|
||||||
return updatePocketMobSpawning(player, arguments[2]);
|
return updatePocketMobSpawning(player, arguments[2], arguments[3]);
|
||||||
}
|
}
|
||||||
if (arguments.length == 4 && arguments[0].equalsIgnoreCase("pocket")
|
if (arguments.length == 4 && arguments[0].equalsIgnoreCase("pocket")
|
||||||
&& arguments[1].equalsIgnoreCase("type")) {
|
&& arguments[1].equalsIgnoreCase("type")) {
|
||||||
@@ -240,7 +240,11 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updatePocketMobSpawning(Player player, String mode) {
|
private boolean updatePocketMobSpawning(
|
||||||
|
Player player,
|
||||||
|
String category,
|
||||||
|
String mode
|
||||||
|
) {
|
||||||
if (pocketBases == null) {
|
if (pocketBases == null) {
|
||||||
player.sendMessage(ChatColor.RED + "Pocket Bases are currently unavailable.");
|
player.sendMessage(ChatColor.RED + "Pocket Bases are currently unavailable.");
|
||||||
return true;
|
return true;
|
||||||
@@ -256,17 +260,30 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final PocketBaseState updated;
|
final PocketBaseState updated;
|
||||||
|
final boolean settingEnabled;
|
||||||
try {
|
try {
|
||||||
updated = pocketBases.setMobSpawning(player.getUniqueId(), enabled);
|
if (category.equalsIgnoreCase("hostile")) {
|
||||||
|
updated = pocketBases.setHostileMobSpawning(
|
||||||
|
player.getUniqueId(), enabled
|
||||||
|
);
|
||||||
|
settingEnabled = updated.hostileMobSpawningEnabled();
|
||||||
|
} else if (category.equalsIgnoreCase("passive")) {
|
||||||
|
updated = pocketBases.setPassiveMobSpawning(
|
||||||
|
player.getUniqueId(), enabled
|
||||||
|
);
|
||||||
|
settingEnabled = updated.passiveMobSpawningEnabled();
|
||||||
|
} else {
|
||||||
|
sendUsage(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} catch (IOException | RuntimeException exception) {
|
} catch (IOException | RuntimeException exception) {
|
||||||
player.sendMessage(ChatColor.RED
|
player.sendMessage(ChatColor.RED
|
||||||
+ "The Pocket Base mob-spawning setting could not be changed.");
|
+ "The Pocket Base mob-spawning setting could not be changed.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
player.sendMessage(ChatColor.YELLOW + "Pocket Base mob spawning is now "
|
player.sendMessage(ChatColor.YELLOW + "Pocket Base "
|
||||||
+ (updated.mobSpawningEnabled()
|
+ category.toLowerCase(Locale.ROOT) + " mob spawning is now "
|
||||||
? ChatColor.GREEN + "enabled"
|
+ (settingEnabled ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled")
|
||||||
: ChatColor.RED + "disabled")
|
|
||||||
+ ChatColor.YELLOW + ".");
|
+ ChatColor.YELLOW + ".");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -514,8 +531,10 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
+ settings.current().pocketBaseCurrencyMaterial().toLowerCase(Locale.ROOT)
|
+ settings.current().pocketBaseCurrencyMaterial().toLowerCase(Locale.ROOT)
|
||||||
+ " → /basesettings pocket upgrade; type="
|
+ " → /basesettings pocket upgrade; type="
|
||||||
+ pocket.biome().worldType().commandName() + "/" + pocket.biome().commandName()
|
+ pocket.biome().worldType().commandName() + "/" + pocket.biome().commandName()
|
||||||
+ "; mob spawning="
|
+ "; hostile spawning="
|
||||||
+ (pocket.mobSpawningEnabled() ? "enabled" : "disabled"));
|
+ (pocket.hostileMobSpawningEnabled() ? "enabled" : "disabled")
|
||||||
|
+ "; passive spawning="
|
||||||
|
+ (pocket.passiveMobSpawningEnabled() ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showCooldownPath(Player player, PlayerState state) {
|
private void showCooldownPath(Player player, PlayerState state) {
|
||||||
@@ -557,7 +576,9 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
if (arguments.length == 3 && arguments[0].equalsIgnoreCase("pocket")) {
|
if (arguments.length == 3 && arguments[0].equalsIgnoreCase("pocket")) {
|
||||||
String prefix = arguments[2].toLowerCase(Locale.ROOT);
|
String prefix = arguments[2].toLowerCase(Locale.ROOT);
|
||||||
if (arguments[1].equalsIgnoreCase("mobs")) {
|
if (arguments[1].equalsIgnoreCase("mobs")) {
|
||||||
return ENABLE_MODES.stream().filter(mode -> mode.startsWith(prefix)).toList();
|
return List.of("hostile", "passive").stream()
|
||||||
|
.filter(category -> category.startsWith(prefix))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (arguments[1].equalsIgnoreCase("type")) {
|
if (arguments[1].equalsIgnoreCase("type")) {
|
||||||
return POCKET_WORLD_TYPES.stream()
|
return POCKET_WORLD_TYPES.stream()
|
||||||
@@ -565,9 +586,16 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (arguments.length == 4 && arguments[0].equalsIgnoreCase("pocket")
|
if (arguments.length == 4 && arguments[0].equalsIgnoreCase("pocket")) {
|
||||||
&& arguments[1].equalsIgnoreCase("type")) {
|
|
||||||
String prefix = arguments[3].toLowerCase(Locale.ROOT);
|
String prefix = arguments[3].toLowerCase(Locale.ROOT);
|
||||||
|
if (arguments[1].equalsIgnoreCase("mobs")
|
||||||
|
&& (arguments[2].equalsIgnoreCase("hostile")
|
||||||
|
|| arguments[2].equalsIgnoreCase("passive"))) {
|
||||||
|
return ENABLE_MODES.stream()
|
||||||
|
.filter(mode -> mode.startsWith(prefix))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
if (arguments[1].equalsIgnoreCase("type")) {
|
||||||
return PocketBaseWorldType.fromCommand(arguments[2])
|
return PocketBaseWorldType.fromCommand(arguments[2])
|
||||||
.map(PocketBaseBiome::commandNames)
|
.map(PocketBaseBiome::commandNames)
|
||||||
.orElse(List.of())
|
.orElse(List.of())
|
||||||
@@ -575,6 +603,7 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
.filter(biome -> biome.startsWith(prefix))
|
.filter(biome -> biome.startsWith(prefix))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,7 +663,8 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
|||||||
|
|
||||||
private static void sendUsage(Player player) {
|
private static void sendUsage(Player player) {
|
||||||
player.sendMessage(ChatColor.RED + "Usage: /basesettings "
|
player.sendMessage(ChatColor.RED + "Usage: /basesettings "
|
||||||
+ "[status|upgrade|pocket upgrade|pocket mobs <enable|disable>"
|
+ "[status|upgrade|pocket upgrade|pocket mobs "
|
||||||
|
+ "<hostile|passive> <enable|disable>"
|
||||||
+ "|pocket type <void|nether|overworld> <subtype>"
|
+ "|pocket type <void|nether|overworld> <subtype>"
|
||||||
+ "|visitors <allowed|blocked>|navigation <enable|disable>"
|
+ "|visitors <allowed|blocked>|navigation <enable|disable>"
|
||||||
+ "|flight <enable|disable>|border <enable|disable>"
|
+ "|flight <enable|disable>|border <enable|disable>"
|
||||||
|
|||||||
@@ -92,20 +92,48 @@ final class PocketBaseManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PocketBaseState setMobSpawning(UUID ownerId, boolean enabled) throws IOException {
|
PocketBaseState setHostileMobSpawning(UUID ownerId, boolean enabled)
|
||||||
|
throws IOException {
|
||||||
PocketBaseState current = states.state(ownerId);
|
PocketBaseState current = states.state(ownerId);
|
||||||
|
return setMobSpawning(
|
||||||
|
current,
|
||||||
|
enabled,
|
||||||
|
current.passiveMobSpawningEnabled(),
|
||||||
|
state -> state.withHostileMobSpawningEnabled(enabled)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PocketBaseState setPassiveMobSpawning(UUID ownerId, boolean enabled)
|
||||||
|
throws IOException {
|
||||||
|
PocketBaseState current = states.state(ownerId);
|
||||||
|
return setMobSpawning(
|
||||||
|
current,
|
||||||
|
current.hostileMobSpawningEnabled(),
|
||||||
|
enabled,
|
||||||
|
state -> state.withPassiveMobSpawningEnabled(enabled)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PocketBaseState setMobSpawning(
|
||||||
|
PocketBaseState current,
|
||||||
|
boolean hostileEnabled,
|
||||||
|
boolean passiveEnabled,
|
||||||
|
java.util.function.UnaryOperator<PocketBaseState> update
|
||||||
|
) throws IOException {
|
||||||
if (current.level() < 1) {
|
if (current.level() < 1) {
|
||||||
throw new IllegalStateException("Pocket Base I is still locked");
|
throw new IllegalStateException("Pocket Base I is still locked");
|
||||||
}
|
}
|
||||||
worlds.setMobSpawning(ownerId, enabled);
|
UUID ownerId = current.ownerId();
|
||||||
|
worlds.setMobSpawning(ownerId, hostileEnabled, passiveEnabled);
|
||||||
try {
|
try {
|
||||||
return states.updateAndSave(
|
return states.updateAndSave(ownerId, update);
|
||||||
ownerId,
|
|
||||||
state -> state.withMobSpawningEnabled(enabled)
|
|
||||||
);
|
|
||||||
} catch (IOException | RuntimeException exception) {
|
} catch (IOException | RuntimeException exception) {
|
||||||
try {
|
try {
|
||||||
worlds.setMobSpawning(ownerId, current.mobSpawningEnabled());
|
worlds.setMobSpawning(
|
||||||
|
ownerId,
|
||||||
|
current.hostileMobSpawningEnabled(),
|
||||||
|
current.passiveMobSpawningEnabled()
|
||||||
|
);
|
||||||
} catch (RuntimeException rollbackFailure) {
|
} catch (RuntimeException rollbackFailure) {
|
||||||
exception.addSuppressed(rollbackFailure);
|
exception.addSuppressed(rollbackFailure);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ public record PocketBaseState(
|
|||||||
int level,
|
int level,
|
||||||
Optional<PocketPortalLocation> entrance,
|
Optional<PocketPortalLocation> entrance,
|
||||||
Optional<PocketPortalLocation> returnPortal,
|
Optional<PocketPortalLocation> returnPortal,
|
||||||
boolean mobSpawningEnabled,
|
boolean hostileMobSpawningEnabled,
|
||||||
|
boolean passiveMobSpawningEnabled,
|
||||||
PocketBaseBiome biome
|
PocketBaseBiome biome
|
||||||
) {
|
) {
|
||||||
public PocketBaseState {
|
public PocketBaseState {
|
||||||
@@ -32,73 +33,64 @@ public record PocketBaseState(
|
|||||||
Optional<PocketPortalLocation> entrance
|
Optional<PocketPortalLocation> entrance
|
||||||
) {
|
) {
|
||||||
this(
|
this(
|
||||||
ownerId, level, entrance, Optional.empty(), false, PocketBaseBiome.THE_VOID
|
ownerId, level, entrance, Optional.empty(), false, false,
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PocketBaseState(
|
|
||||||
UUID ownerId,
|
|
||||||
int level,
|
|
||||||
Optional<PocketPortalLocation> entrance,
|
|
||||||
boolean mobSpawningEnabled
|
|
||||||
) {
|
|
||||||
this(
|
|
||||||
ownerId, level, entrance, Optional.empty(), mobSpawningEnabled,
|
|
||||||
PocketBaseBiome.THE_VOID
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PocketBaseState(
|
|
||||||
UUID ownerId,
|
|
||||||
int level,
|
|
||||||
Optional<PocketPortalLocation> entrance,
|
|
||||||
Optional<PocketPortalLocation> returnPortal,
|
|
||||||
boolean mobSpawningEnabled
|
|
||||||
) {
|
|
||||||
this(
|
|
||||||
ownerId, level, entrance, returnPortal, mobSpawningEnabled,
|
|
||||||
PocketBaseBiome.THE_VOID
|
PocketBaseBiome.THE_VOID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PocketBaseState locked(UUID ownerId) {
|
public static PocketBaseState locked(UUID ownerId) {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, 0, Optional.empty(), Optional.empty(), false,
|
ownerId, 0, Optional.empty(), Optional.empty(), false, false,
|
||||||
PocketBaseBiome.THE_VOID
|
PocketBaseBiome.THE_VOID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withLevel(int newLevel) {
|
public PocketBaseState withLevel(int newLevel) {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, newLevel, entrance, returnPortal, mobSpawningEnabled, biome
|
ownerId, newLevel, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||||
|
passiveMobSpawningEnabled, biome
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withEntrance(PocketPortalLocation portal) {
|
public PocketBaseState withEntrance(PocketPortalLocation portal) {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, level, Optional.of(portal), returnPortal, mobSpawningEnabled, biome
|
ownerId, level, Optional.of(portal), returnPortal,
|
||||||
|
hostileMobSpawningEnabled, passiveMobSpawningEnabled, biome
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withoutEntrance() {
|
public PocketBaseState withoutEntrance() {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, level, Optional.empty(), returnPortal, mobSpawningEnabled, biome
|
ownerId, level, Optional.empty(), returnPortal, hostileMobSpawningEnabled,
|
||||||
|
passiveMobSpawningEnabled, biome
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withReturnPortal(PocketPortalLocation portal) {
|
public PocketBaseState withReturnPortal(PocketPortalLocation portal) {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, level, entrance, Optional.of(portal), mobSpawningEnabled, biome
|
ownerId, level, entrance, Optional.of(portal), hostileMobSpawningEnabled,
|
||||||
|
passiveMobSpawningEnabled, biome
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withMobSpawningEnabled(boolean enabled) {
|
public PocketBaseState withHostileMobSpawningEnabled(boolean enabled) {
|
||||||
return new PocketBaseState(ownerId, level, entrance, returnPortal, enabled, biome);
|
return new PocketBaseState(
|
||||||
|
ownerId, level, entrance, returnPortal, enabled,
|
||||||
|
passiveMobSpawningEnabled, biome
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PocketBaseState withPassiveMobSpawningEnabled(boolean enabled) {
|
||||||
|
return new PocketBaseState(
|
||||||
|
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||||
|
enabled, biome
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketBaseState withBiome(PocketBaseBiome selectedBiome) {
|
public PocketBaseState withBiome(PocketBaseBiome selectedBiome) {
|
||||||
return new PocketBaseState(
|
return new PocketBaseState(
|
||||||
ownerId, level, entrance, returnPortal, mobSpawningEnabled, selectedBiome
|
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||||
|
passiveMobSpawningEnabled, selectedBiome
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,11 @@ final class PocketBaseWorldService {
|
|||||||
for (PocketBaseState state : states.values()) {
|
for (PocketBaseState state : states.values()) {
|
||||||
if (state.level() > 0) {
|
if (state.level() > 0) {
|
||||||
setBiome(state.ownerId(), state.level(), state.biome());
|
setBiome(state.ownerId(), state.level(), state.biome());
|
||||||
setMobSpawning(state.ownerId(), state.mobSpawningEnabled());
|
setMobSpawning(
|
||||||
|
state.ownerId(),
|
||||||
|
state.hostileMobSpawningEnabled(),
|
||||||
|
state.passiveMobSpawningEnabled()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,8 +95,12 @@ final class PocketBaseWorldService {
|
|||||||
return ensureWorld(ownerId);
|
return ensureWorld(ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMobSpawning(UUID ownerId, boolean enabled) {
|
void setMobSpawning(
|
||||||
ensureWorld(ownerId).setSpawnFlags(enabled, enabled);
|
UUID ownerId,
|
||||||
|
boolean hostileEnabled,
|
||||||
|
boolean passiveEnabled
|
||||||
|
) {
|
||||||
|
ensureWorld(ownerId).setSpawnFlags(hostileEnabled, passiveEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBiome(UUID ownerId, int level, PocketBaseBiome biome) {
|
void setBiome(UUID ownerId, int level, PocketBaseBiome biome) {
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ public final class YamlPocketBaseRepository {
|
|||||||
level,
|
level,
|
||||||
loadPortal(yaml, path + ".entrance"),
|
loadPortal(yaml, path + ".entrance"),
|
||||||
loadPortal(yaml, path + ".return-portal"),
|
loadPortal(yaml, path + ".return-portal"),
|
||||||
yaml.getBoolean(path + ".mob-spawning-enabled", false),
|
loadMobPreference(yaml, path, "hostile-mob-spawning-enabled"),
|
||||||
|
loadMobPreference(yaml, path, "passive-mob-spawning-enabled"),
|
||||||
loadBiome(yaml, path)
|
loadBiome(yaml, path)
|
||||||
);
|
);
|
||||||
states.put(ownerId, state);
|
states.put(ownerId, state);
|
||||||
@@ -64,7 +65,14 @@ public final class YamlPocketBaseRepository {
|
|||||||
for (PocketBaseState state : states.values()) {
|
for (PocketBaseState state : states.values()) {
|
||||||
String path = "owners." + state.ownerId();
|
String path = "owners." + state.ownerId();
|
||||||
yaml.set(path + ".level", state.level());
|
yaml.set(path + ".level", state.level());
|
||||||
yaml.set(path + ".mob-spawning-enabled", state.mobSpawningEnabled());
|
yaml.set(
|
||||||
|
path + ".hostile-mob-spawning-enabled",
|
||||||
|
state.hostileMobSpawningEnabled()
|
||||||
|
);
|
||||||
|
yaml.set(
|
||||||
|
path + ".passive-mob-spawning-enabled",
|
||||||
|
state.passiveMobSpawningEnabled()
|
||||||
|
);
|
||||||
yaml.set(path + ".world-type", state.biome().worldType().commandName());
|
yaml.set(path + ".world-type", state.biome().worldType().commandName());
|
||||||
yaml.set(path + ".biome", state.biome().commandName());
|
yaml.set(path + ".biome", state.biome().commandName());
|
||||||
state.entrance().ifPresent(portal -> savePortal(yaml, path + ".entrance", portal));
|
state.entrance().ifPresent(portal -> savePortal(yaml, path + ".entrance", portal));
|
||||||
@@ -90,6 +98,17 @@ public final class YamlPocketBaseRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean loadMobPreference(
|
||||||
|
YamlConfiguration yaml,
|
||||||
|
String path,
|
||||||
|
String categoryKey
|
||||||
|
) {
|
||||||
|
return yaml.getBoolean(
|
||||||
|
path + "." + categoryKey,
|
||||||
|
yaml.getBoolean(path + ".mob-spawning-enabled", false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static PocketBaseBiome loadBiome(YamlConfiguration yaml, String path) {
|
private static PocketBaseBiome loadBiome(YamlConfiguration yaml, String path) {
|
||||||
String worldTypeName = yaml.getString(path + ".world-type");
|
String worldTypeName = yaml.getString(path + ".world-type");
|
||||||
String biomeName = yaml.getString(path + ".biome");
|
String biomeName = yaml.getString(path + ".biome");
|
||||||
|
|||||||
@@ -119,10 +119,23 @@ final class BaseSettingsCommandTest {
|
|||||||
new String[] {"pocket", "type", "nether", "c"}
|
new String[] {"pocket", "type", "nether", "c"}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
assertEquals(
|
||||||
|
List.of("hostile"),
|
||||||
|
command.onTabComplete(
|
||||||
|
null, null, "basesettings", new String[] {"pocket", "mobs", "h"}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
List.of("passive"),
|
||||||
|
command.onTabComplete(
|
||||||
|
null, null, "basesettings", new String[] {"pocket", "mobs", "p"}
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
List.of("enable"),
|
List.of("enable"),
|
||||||
command.onTabComplete(
|
command.onTabComplete(
|
||||||
null, null, "basesettings", new String[] {"pocket", "mobs", "e"}
|
null, null, "basesettings",
|
||||||
|
new String[] {"pocket", "mobs", "hostile", "e"}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
for (String setting : List.of("navigation", "flight", "border", "spawnable", "bossbar")) {
|
for (String setting : List.of("navigation", "flight", "border", "spawnable", "bossbar")) {
|
||||||
@@ -296,7 +309,7 @@ final class BaseSettingsCommandTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void pocketOwnerCanEnableNaturalMobSpawning() throws Exception {
|
void pocketOwnerCanEnableHostileMobSpawningWithoutChangingPassive() throws Exception {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
Player player = mock(Player.class);
|
Player player = mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(playerId);
|
when(player.getUniqueId()).thenReturn(playerId);
|
||||||
@@ -305,11 +318,13 @@ final class BaseSettingsCommandTest {
|
|||||||
when(stateManager.player(playerId, "Builder"))
|
when(stateManager.player(playerId, "Builder"))
|
||||||
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
||||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||||
when(pocketBases.state(playerId)).thenReturn(
|
PocketBaseState current = new PocketBaseState(
|
||||||
new PocketBaseState(playerId, 1, java.util.Optional.empty(), false)
|
playerId, 1, java.util.Optional.empty(), java.util.Optional.empty(),
|
||||||
|
false, true, PocketBaseBiome.THE_VOID
|
||||||
);
|
);
|
||||||
when(pocketBases.setMobSpawning(playerId, true)).thenReturn(
|
when(pocketBases.state(playerId)).thenReturn(current);
|
||||||
new PocketBaseState(playerId, 1, java.util.Optional.empty(), true)
|
when(pocketBases.setHostileMobSpawning(playerId, true)).thenReturn(
|
||||||
|
current.withHostileMobSpawningEnabled(true)
|
||||||
);
|
);
|
||||||
BaseSettingsCommand command = new BaseSettingsCommand(
|
BaseSettingsCommand command = new BaseSettingsCommand(
|
||||||
stateManager,
|
stateManager,
|
||||||
@@ -318,13 +333,14 @@ final class BaseSettingsCommandTest {
|
|||||||
pocketBases
|
pocketBases
|
||||||
);
|
);
|
||||||
|
|
||||||
command.onCommand(
|
command.onCommand(player, null, "basesettings", new String[] {
|
||||||
player, null, "basesettings", new String[] {"pocket", "mobs", "enable"}
|
"pocket", "mobs", "hostile", "enable"
|
||||||
);
|
});
|
||||||
|
|
||||||
verify(pocketBases).setMobSpawning(playerId, true);
|
verify(pocketBases).setHostileMobSpawning(playerId, true);
|
||||||
|
verify(pocketBases, never()).setPassiveMobSpawning(playerId, true);
|
||||||
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
||||||
message -> message.contains("mob spawning") && message.contains("enabled")
|
message -> message.contains("hostile mob spawning") && message.contains("enabled")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,9 +355,9 @@ final class BaseSettingsCommandTest {
|
|||||||
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
||||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||||
when(pocketBases.state(playerId)).thenReturn(
|
when(pocketBases.state(playerId)).thenReturn(
|
||||||
new PocketBaseState(playerId, 1, java.util.Optional.empty(), false)
|
new PocketBaseState(playerId, 1, java.util.Optional.empty())
|
||||||
);
|
);
|
||||||
when(pocketBases.setMobSpawning(playerId, true))
|
when(pocketBases.setPassiveMobSpawning(playerId, true))
|
||||||
.thenThrow(new IOException("save failed"));
|
.thenThrow(new IOException("save failed"));
|
||||||
BaseSettingsCommand command = new BaseSettingsCommand(
|
BaseSettingsCommand command = new BaseSettingsCommand(
|
||||||
stateManager,
|
stateManager,
|
||||||
@@ -350,9 +366,9 @@ final class BaseSettingsCommandTest {
|
|||||||
pocketBases
|
pocketBases
|
||||||
);
|
);
|
||||||
|
|
||||||
command.onCommand(
|
command.onCommand(player, null, "basesettings", new String[] {
|
||||||
player, null, "basesettings", new String[] {"pocket", "mobs", "enable"}
|
"pocket", "mobs", "passive", "enable"
|
||||||
);
|
});
|
||||||
|
|
||||||
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
||||||
message -> message.contains("could not be changed")
|
message -> message.contains("could not be changed")
|
||||||
@@ -380,11 +396,11 @@ final class BaseSettingsCommandTest {
|
|||||||
pocketBases
|
pocketBases
|
||||||
);
|
);
|
||||||
|
|
||||||
command.onCommand(
|
command.onCommand(player, null, "basesettings", new String[] {
|
||||||
player, null, "basesettings", new String[] {"pocket", "mobs", "enable"}
|
"pocket", "mobs", "hostile", "enable"
|
||||||
);
|
});
|
||||||
|
|
||||||
verify(pocketBases, never()).setMobSpawning(playerId, true);
|
verify(pocketBases, never()).setHostileMobSpawning(playerId, true);
|
||||||
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
||||||
message -> message.contains("Pocket Base I") && message.contains("locked")
|
message -> message.contains("Pocket Base I") && message.contains("locked")
|
||||||
));
|
));
|
||||||
@@ -429,7 +445,7 @@ final class BaseSettingsCommandTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void statusDisplaysPocketMobSpawningPreference() {
|
void statusDisplaysPocketMobSpawningPreferences() {
|
||||||
UUID playerId = UUID.randomUUID();
|
UUID playerId = UUID.randomUUID();
|
||||||
Player player = mock(Player.class);
|
Player player = mock(Player.class);
|
||||||
when(player.getUniqueId()).thenReturn(playerId);
|
when(player.getUniqueId()).thenReturn(playerId);
|
||||||
@@ -439,7 +455,10 @@ final class BaseSettingsCommandTest {
|
|||||||
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
.thenReturn(PlayerState.newPlayer(playerId, "Builder"));
|
||||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||||
when(pocketBases.state(playerId)).thenReturn(
|
when(pocketBases.state(playerId)).thenReturn(
|
||||||
new PocketBaseState(playerId, 1, java.util.Optional.empty(), false)
|
new PocketBaseState(
|
||||||
|
playerId, 1, java.util.Optional.empty(), java.util.Optional.empty(),
|
||||||
|
true, false, PocketBaseBiome.THE_VOID
|
||||||
|
)
|
||||||
);
|
);
|
||||||
BaseSettingsCommand command = new BaseSettingsCommand(
|
BaseSettingsCommand command = new BaseSettingsCommand(
|
||||||
stateManager,
|
stateManager,
|
||||||
@@ -453,7 +472,8 @@ final class BaseSettingsCommandTest {
|
|||||||
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
verify(player).sendMessage(org.mockito.ArgumentMatchers.<String>argThat(
|
||||||
message -> message.contains("Pocket Base 1")
|
message -> message.contains("Pocket Base 1")
|
||||||
&& message.contains("type=void/the_void")
|
&& message.contains("type=void/the_void")
|
||||||
&& message.contains("mob spawning=disabled")
|
&& message.contains("hostile spawning=enabled")
|
||||||
|
&& message.contains("passive spawning=disabled")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ final class PocketBaseManagerTest {
|
|||||||
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
||||||
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
||||||
when(states.state(ownerId)).thenReturn(new PocketBaseState(
|
when(states.state(ownerId)).thenReturn(new PocketBaseState(
|
||||||
ownerId, 1, Optional.empty(), Optional.of(relocated), false
|
ownerId, 1, Optional.empty(), Optional.of(relocated), false, false,
|
||||||
|
PocketBaseBiome.THE_VOID
|
||||||
));
|
));
|
||||||
PocketBaseManager manager = new PocketBaseManager(
|
PocketBaseManager manager = new PocketBaseManager(
|
||||||
states,
|
states,
|
||||||
@@ -58,9 +59,12 @@ final class PocketBaseManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void persistsAndAppliesMobSpawningPreference() throws Exception {
|
void persistsAndAppliesHostileMobSpawningWithoutChangingPassive() throws Exception {
|
||||||
UUID ownerId = UUID.randomUUID();
|
UUID ownerId = UUID.randomUUID();
|
||||||
PocketBaseState current = new PocketBaseState(ownerId, 1, Optional.empty(), false);
|
PocketBaseState current = new PocketBaseState(
|
||||||
|
ownerId, 1, Optional.empty(), Optional.empty(), false, true,
|
||||||
|
PocketBaseBiome.THE_VOID
|
||||||
|
);
|
||||||
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
||||||
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
||||||
when(states.state(ownerId)).thenReturn(current);
|
when(states.state(ownerId)).thenReturn(current);
|
||||||
@@ -76,10 +80,12 @@ final class PocketBaseManagerTest {
|
|||||||
new PluginSettingsProvider(PluginSettings.from(Map.of()))
|
new PluginSettingsProvider(PluginSettings.from(Map.of()))
|
||||||
);
|
);
|
||||||
|
|
||||||
manager.setMobSpawning(ownerId, true);
|
PocketBaseState updated = manager.setHostileMobSpawning(ownerId, true);
|
||||||
|
|
||||||
|
assertEquals(true, updated.hostileMobSpawningEnabled());
|
||||||
|
assertEquals(true, updated.passiveMobSpawningEnabled());
|
||||||
InOrder order = inOrder(worlds, states);
|
InOrder order = inOrder(worlds, states);
|
||||||
order.verify(worlds).setMobSpawning(ownerId, true);
|
order.verify(worlds).setMobSpawning(ownerId, true, true);
|
||||||
order.verify(states).updateAndSave(
|
order.verify(states).updateAndSave(
|
||||||
org.mockito.ArgumentMatchers.eq(ownerId), org.mockito.ArgumentMatchers.any()
|
org.mockito.ArgumentMatchers.eq(ownerId), org.mockito.ArgumentMatchers.any()
|
||||||
);
|
);
|
||||||
@@ -137,9 +143,12 @@ final class PocketBaseManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void restoresWorldSettingWhenPersistenceFails() throws Exception {
|
void restoresBothWorldSettingsWhenPersistenceFails() throws Exception {
|
||||||
UUID ownerId = UUID.randomUUID();
|
UUID ownerId = UUID.randomUUID();
|
||||||
PocketBaseState current = new PocketBaseState(ownerId, 1, Optional.empty(), false);
|
PocketBaseState current = new PocketBaseState(
|
||||||
|
ownerId, 1, Optional.empty(), Optional.empty(), true, false,
|
||||||
|
PocketBaseBiome.THE_VOID
|
||||||
|
);
|
||||||
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
||||||
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
PocketBaseWorldService worlds = mock(PocketBaseWorldService.class);
|
||||||
when(states.state(ownerId)).thenReturn(current);
|
when(states.state(ownerId)).thenReturn(current);
|
||||||
@@ -151,9 +160,10 @@ final class PocketBaseManagerTest {
|
|||||||
new PluginSettingsProvider(PluginSettings.from(Map.of()))
|
new PluginSettingsProvider(PluginSettings.from(Map.of()))
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThrows(IOException.class, () -> manager.setMobSpawning(ownerId, true));
|
assertThrows(IOException.class,
|
||||||
|
() -> manager.setPassiveMobSpawning(ownerId, true));
|
||||||
|
|
||||||
verify(worlds).setMobSpawning(ownerId, true);
|
verify(worlds).setMobSpawning(ownerId, true, true);
|
||||||
verify(worlds).setMobSpawning(ownerId, false);
|
verify(worlds).setMobSpawning(ownerId, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,10 +93,13 @@ final class PocketBaseWorldServiceTest {
|
|||||||
|
|
||||||
service.loadExisting(Map.of(
|
service.loadExisting(Map.of(
|
||||||
ownerId,
|
ownerId,
|
||||||
new PocketBaseState(ownerId, 1, Optional.empty(), true)
|
new PocketBaseState(
|
||||||
|
ownerId, 1, Optional.empty(), Optional.empty(), true, false,
|
||||||
|
PocketBaseBiome.THE_VOID
|
||||||
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
verify(world).setSpawnFlags(true, true);
|
verify(world).setSpawnFlags(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ final class YamlPocketBaseRepositoryTest {
|
|||||||
worldId, "pocket", 20, 65, 12, PocketPortalAxis.Z
|
worldId, "pocket", 20, 65, 12, PocketPortalAxis.Z
|
||||||
)),
|
)),
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
PocketBaseBiome.CRIMSON_FOREST
|
PocketBaseBiome.CRIMSON_FOREST
|
||||||
);
|
);
|
||||||
YamlPocketBaseRepository repository = new YamlPocketBaseRepository(
|
YamlPocketBaseRepository repository = new YamlPocketBaseRepository(
|
||||||
@@ -50,8 +51,23 @@ final class YamlPocketBaseRepositoryTest {
|
|||||||
|
|
||||||
PocketBaseState loaded = repository.load().get(ownerId);
|
PocketBaseState loaded = repository.load().get(ownerId);
|
||||||
|
|
||||||
assertFalse(loaded.mobSpawningEnabled());
|
assertFalse(loaded.hostileMobSpawningEnabled());
|
||||||
|
assertFalse(loaded.passiveMobSpawningEnabled());
|
||||||
assertTrue(loaded.returnPortal().isEmpty());
|
assertTrue(loaded.returnPortal().isEmpty());
|
||||||
assertEquals(PocketBaseBiome.THE_VOID, loaded.biome());
|
assertEquals(PocketBaseBiome.THE_VOID, loaded.biome());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void migratesLegacyMobPreferenceToBothCategories() throws Exception {
|
||||||
|
UUID ownerId = UUID.randomUUID();
|
||||||
|
Path stateFile = temporaryDirectory.resolve("pocket-bases.yml");
|
||||||
|
Files.writeString(stateFile, "owners:\n " + ownerId
|
||||||
|
+ ":\n level: 1\n mob-spawning-enabled: true\n");
|
||||||
|
YamlPocketBaseRepository repository = new YamlPocketBaseRepository(stateFile);
|
||||||
|
|
||||||
|
PocketBaseState loaded = repository.load().get(ownerId);
|
||||||
|
|
||||||
|
assertTrue(loaded.hostileMobSpawningEnabled());
|
||||||
|
assertTrue(loaded.passiveMobSpawningEnabled());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user