feat(pocket-base): unlock flight by completing raids
This commit is contained in:
@@ -1,21 +1,31 @@
|
||||
package games.dmg.spigotbase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.raid.RaidFinishEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
final class BaseFlightController implements Runnable {
|
||||
final class BaseFlightController implements Runnable, Listener {
|
||||
private static final int POCKET_FLIGHT_BUFFER = 16;
|
||||
private final Server server;
|
||||
private final BaseStateManager stateManager;
|
||||
private final SecondaryProgressionService progressionService;
|
||||
private final BaseBoundsService boundsService;
|
||||
private final PluginSettingsProvider settings;
|
||||
private final PocketBaseManager pocketBases;
|
||||
private final Logger logger;
|
||||
private final Set<UUID> grantedFlight = new HashSet<>();
|
||||
private final Set<UUID> warned = new HashSet<>();
|
||||
|
||||
@@ -25,12 +35,60 @@ final class BaseFlightController implements Runnable {
|
||||
SecondaryProgressionService progressionService,
|
||||
BaseBoundsService boundsService,
|
||||
PluginSettingsProvider settings
|
||||
) {
|
||||
this(server, stateManager, progressionService, boundsService, settings, null,
|
||||
Logger.getLogger(BaseFlightController.class.getName()));
|
||||
}
|
||||
|
||||
BaseFlightController(
|
||||
Server server,
|
||||
BaseStateManager stateManager,
|
||||
SecondaryProgressionService progressionService,
|
||||
BaseBoundsService boundsService,
|
||||
PluginSettingsProvider settings,
|
||||
PocketBaseManager pocketBases,
|
||||
Logger logger
|
||||
) {
|
||||
this.server = server;
|
||||
this.stateManager = stateManager;
|
||||
this.progressionService = progressionService;
|
||||
this.boundsService = boundsService;
|
||||
this.settings = settings;
|
||||
this.pocketBases = pocketBases;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRaidFinish(RaidFinishEvent event) {
|
||||
if (pocketBases == null) {
|
||||
return;
|
||||
}
|
||||
Optional<UUID> owner = pocketBases.ownerForPocketWorld(event.getWorld().getUID());
|
||||
if (owner.isEmpty() || event.getWinners().stream().noneMatch(
|
||||
winner -> winner.getUniqueId().equals(owner.orElseThrow()))) {
|
||||
return;
|
||||
}
|
||||
UUID ownerId = owner.orElseThrow();
|
||||
if (pocketBases.state(ownerId).flightUnlocked()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pocketBases.unlockFlight(ownerId);
|
||||
} catch (IOException | RuntimeException exception) {
|
||||
logger.log(Level.SEVERE, "Could not unlock Pocket Base flight", exception);
|
||||
return;
|
||||
}
|
||||
event.getWinners().stream()
|
||||
.filter(winner -> winner.getUniqueId().equals(ownerId))
|
||||
.findFirst()
|
||||
.orElseThrow()
|
||||
.sendTitle(
|
||||
ChatColor.GOLD + "Pocket Base Flight Unlocked",
|
||||
ChatColor.YELLOW + "Flight is now available in your Pocket Base",
|
||||
settings.current().titleFadeInTicks(),
|
||||
settings.current().titleStayTicks(),
|
||||
settings.current().titleFadeOutTicks()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,8 +147,20 @@ final class BaseFlightController implements Runnable {
|
||||
}
|
||||
|
||||
private void applyFlight(Player player, PlayerState state) {
|
||||
if (player.getGameMode() != GameMode.SURVIVAL
|
||||
|| !state.flightEnabled() || state.flightLevel() < 1 || state.base().isEmpty()) {
|
||||
if (player.getGameMode() != GameMode.SURVIVAL) {
|
||||
removeGrantedFlight(player);
|
||||
return;
|
||||
}
|
||||
if (pocketBases != null) {
|
||||
Optional<UUID> pocketOwner = pocketBases.ownerForPocketWorld(
|
||||
player.getWorld().getUID()
|
||||
);
|
||||
if (pocketOwner.isPresent()) {
|
||||
applyPocketFlight(player, pocketOwner.orElseThrow());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!state.flightEnabled() || state.flightLevel() < 1 || state.base().isEmpty()) {
|
||||
removeGrantedFlight(player);
|
||||
return;
|
||||
}
|
||||
@@ -127,6 +197,43 @@ final class BaseFlightController implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void applyPocketFlight(Player player, UUID ownerId) {
|
||||
PocketBaseState pocket = pocketBases.state(ownerId);
|
||||
if (!ownerId.equals(player.getUniqueId()) || !pocket.flightUnlocked()
|
||||
|| pocket.level() < 1) {
|
||||
removeGrantedFlight(player);
|
||||
return;
|
||||
}
|
||||
int halfSize = pocketBases.policy().size(pocket.level()) / 2;
|
||||
int x = player.getLocation().getBlockX();
|
||||
int z = player.getLocation().getBlockZ();
|
||||
if (x < -halfSize - POCKET_FLIGHT_BUFFER
|
||||
|| x >= halfSize + POCKET_FLIGHT_BUFFER
|
||||
|| z < -halfSize - POCKET_FLIGHT_BUFFER
|
||||
|| z >= halfSize + POCKET_FLIGHT_BUFFER) {
|
||||
removeGrantedFlight(player);
|
||||
return;
|
||||
}
|
||||
if (!player.getAllowFlight()) {
|
||||
player.setAllowFlight(true);
|
||||
grantedFlight.add(player.getUniqueId());
|
||||
}
|
||||
boolean inBuffer = !pocketBases.policy().contains(pocket.level(), x, z);
|
||||
if (inBuffer && player.isFlying()) {
|
||||
if (warned.add(player.getUniqueId())) {
|
||||
player.sendTitle(
|
||||
ChatColor.RED + "Leaving Your Pocket Base",
|
||||
ChatColor.YELLOW + "Turn back before Pocket Base flight ends",
|
||||
0,
|
||||
Math.min(30, settings.current().titleStayTicks()),
|
||||
settings.current().titleFadeOutTicks()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
warned.remove(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean withinVerticalRange(Player player, PlayerState state, BaseLocation base) {
|
||||
int y = player.getLocation().getBlockY();
|
||||
if (state.flightLevel() == 3) {
|
||||
|
||||
@@ -565,7 +565,9 @@ final class BaseSettingsCommand implements CommandExecutor, TabCompleter {
|
||||
+ "; hostile spawning="
|
||||
+ (pocket.hostileMobSpawningEnabled() ? "enabled" : "disabled")
|
||||
+ "; passive spawning="
|
||||
+ (pocket.passiveMobSpawningEnabled() ? "enabled" : "disabled"));
|
||||
+ (pocket.passiveMobSpawningEnabled() ? "enabled" : "disabled")
|
||||
+ "; flight="
|
||||
+ (pocket.flightUnlocked() ? "unlocked" : "complete a raid to unlock"));
|
||||
}
|
||||
|
||||
private void showCooldownPath(Player player, PlayerState state) {
|
||||
|
||||
@@ -159,7 +159,10 @@ final class BaseSettingsDialogFactory {
|
||||
: "Biome: " + pocket.biome().worldType().commandName() + "/"
|
||||
+ pocket.biome().commandName() + "\nHostile mobs: "
|
||||
+ enabled(pocket.hostileMobSpawningEnabled()) + " • Passive mobs: "
|
||||
+ enabled(pocket.passiveMobSpawningEnabled())
|
||||
+ enabled(pocket.passiveMobSpawningEnabled()) + "\nFlight: "
|
||||
+ (pocket.flightUnlocked()
|
||||
? "Unlocked"
|
||||
: "Complete a raid to unlock")
|
||||
),
|
||||
dialogs,
|
||||
1,
|
||||
|
||||
@@ -92,6 +92,17 @@ final class PocketBaseManager {
|
||||
}
|
||||
}
|
||||
|
||||
PocketBaseState unlockFlight(UUID ownerId) throws IOException {
|
||||
PocketBaseState current = states.state(ownerId);
|
||||
if (current.level() < 1) {
|
||||
throw new IllegalStateException("Pocket Base I is still locked");
|
||||
}
|
||||
if (current.flightUnlocked()) {
|
||||
return current;
|
||||
}
|
||||
return states.updateAndSave(ownerId, PocketBaseState::withFlightUnlocked);
|
||||
}
|
||||
|
||||
PocketBaseState setHostileMobSpawning(UUID ownerId, boolean enabled)
|
||||
throws IOException {
|
||||
PocketBaseState current = states.state(ownerId);
|
||||
|
||||
@@ -10,7 +10,8 @@ public record PocketBaseState(
|
||||
Optional<PocketPortalLocation> returnPortal,
|
||||
boolean hostileMobSpawningEnabled,
|
||||
boolean passiveMobSpawningEnabled,
|
||||
PocketBaseBiome biome
|
||||
PocketBaseBiome biome,
|
||||
boolean flightUnlocked
|
||||
) {
|
||||
public PocketBaseState {
|
||||
if (ownerId == null) {
|
||||
@@ -27,6 +28,21 @@ public record PocketBaseState(
|
||||
}
|
||||
}
|
||||
|
||||
public PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance,
|
||||
Optional<PocketPortalLocation> returnPortal,
|
||||
boolean hostileMobSpawningEnabled,
|
||||
boolean passiveMobSpawningEnabled,
|
||||
PocketBaseBiome biome
|
||||
) {
|
||||
this(
|
||||
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, biome, false
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
@@ -34,63 +50,70 @@ public record PocketBaseState(
|
||||
) {
|
||||
this(
|
||||
ownerId, level, entrance, Optional.empty(), false, false,
|
||||
PocketBaseBiome.THE_VOID
|
||||
PocketBaseBiome.THE_VOID, false
|
||||
);
|
||||
}
|
||||
|
||||
public static PocketBaseState locked(UUID ownerId) {
|
||||
return new PocketBaseState(
|
||||
ownerId, 0, Optional.empty(), Optional.empty(), false, false,
|
||||
PocketBaseBiome.THE_VOID
|
||||
PocketBaseBiome.THE_VOID, false
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withLevel(int newLevel) {
|
||||
return new PocketBaseState(
|
||||
ownerId, newLevel, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, biome
|
||||
passiveMobSpawningEnabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withEntrance(PocketPortalLocation portal) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, Optional.of(portal), returnPortal,
|
||||
hostileMobSpawningEnabled, passiveMobSpawningEnabled, biome
|
||||
hostileMobSpawningEnabled, passiveMobSpawningEnabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withoutEntrance() {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, Optional.empty(), returnPortal, hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, biome
|
||||
passiveMobSpawningEnabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withReturnPortal(PocketPortalLocation portal) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, Optional.of(portal), hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, biome
|
||||
passiveMobSpawningEnabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withHostileMobSpawningEnabled(boolean enabled) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, returnPortal, enabled,
|
||||
passiveMobSpawningEnabled, biome
|
||||
passiveMobSpawningEnabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withPassiveMobSpawningEnabled(boolean enabled) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||
enabled, biome
|
||||
enabled, biome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withBiome(PocketBaseBiome selectedBiome) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, selectedBiome
|
||||
passiveMobSpawningEnabled, selectedBiome, flightUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withFlightUnlocked() {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, returnPortal, hostileMobSpawningEnabled,
|
||||
passiveMobSpawningEnabled, biome, true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ public final class SpigotBasePlugin extends JavaPlugin {
|
||||
settingsProvider
|
||||
);
|
||||
flightController = new BaseFlightController(
|
||||
getServer(), stateManager, secondaryProgressionService, boundsService, settingsProvider
|
||||
getServer(), stateManager, secondaryProgressionService, boundsService,
|
||||
settingsProvider, pocketBaseManager, getLogger()
|
||||
);
|
||||
VisitorPolicy visitorPolicy = new VisitorPolicy();
|
||||
teleportManager = new BaseTeleportManager(
|
||||
@@ -84,6 +85,7 @@ public final class SpigotBasePlugin extends JavaPlugin {
|
||||
getLogger()
|
||||
);
|
||||
getServer().getPluginManager().registerEvents(progressListener, this);
|
||||
getServer().getPluginManager().registerEvents(flightController, this);
|
||||
getServer().getPluginManager().registerEvents(teleportManager, this);
|
||||
getServer().getPluginManager().registerEvents(pocketBaseController, this);
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ public final class YamlPocketBaseRepository {
|
||||
loadPortal(yaml, path + ".return-portal"),
|
||||
loadMobPreference(yaml, path, "hostile-mob-spawning-enabled"),
|
||||
loadMobPreference(yaml, path, "passive-mob-spawning-enabled"),
|
||||
loadBiome(yaml, path)
|
||||
loadBiome(yaml, path),
|
||||
yaml.getBoolean(path + ".flight-unlocked", false)
|
||||
);
|
||||
states.put(ownerId, state);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
@@ -73,6 +74,7 @@ public final class YamlPocketBaseRepository {
|
||||
path + ".passive-mob-spawning-enabled",
|
||||
state.passiveMobSpawningEnabled()
|
||||
);
|
||||
yaml.set(path + ".flight-unlocked", state.flightUnlocked());
|
||||
yaml.set(path + ".world-type", state.biome().worldType().commandName());
|
||||
yaml.set(path + ".biome", state.biome().commandName());
|
||||
state.entrance().ifPresent(portal -> savePortal(yaml, path + ".entrance", portal));
|
||||
|
||||
@@ -12,11 +12,14 @@ import static org.mockito.Mockito.when;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.raid.RaidFinishEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -47,6 +50,7 @@ final class BaseFlightControllerTest {
|
||||
PlayerInventory inventory = mock(PlayerInventory.class);
|
||||
|
||||
doReturn(List.of(player)).when(server).getOnlinePlayers();
|
||||
when(server.getPlayer(playerId)).thenReturn(player);
|
||||
when(player.getUniqueId()).thenReturn(playerId);
|
||||
when(player.getName()).thenReturn("Alex");
|
||||
when(player.getGameMode()).thenReturn(org.bukkit.GameMode.SURVIVAL);
|
||||
@@ -62,6 +66,219 @@ final class BaseFlightControllerTest {
|
||||
when(player.getAllowFlight()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ownerWinningRaidInOwnPocketBaseUnlocksFlight() throws Exception {
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Player winner = mock(Player.class);
|
||||
RaidFinishEvent event = mock(RaidFinishEvent.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
PocketBaseState locked = new PocketBaseState(playerId, 1, Optional.empty());
|
||||
PocketBaseState unlocked = locked.withFlightUnlocked();
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(event.getWorld()).thenReturn(pocketWorld);
|
||||
when(event.getWinners()).thenReturn(List.of(winner));
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(winner.getUniqueId()).thenReturn(playerId);
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(playerId));
|
||||
when(pocketBases.state(playerId)).thenReturn(locked);
|
||||
when(pocketBases.unlockFlight(playerId)).thenReturn(unlocked);
|
||||
|
||||
pocketController.onRaidFinish(event);
|
||||
|
||||
verify(pocketBases).unlockFlight(playerId);
|
||||
verify(winner).sendTitle(anyString(), anyString(), anyInt(), anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void raidDoesNotUnlockFlightWhenPocketOwnerIsNotAWinner() throws Exception {
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Player visitor = mock(Player.class);
|
||||
RaidFinishEvent event = mock(RaidFinishEvent.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(event.getWorld()).thenReturn(pocketWorld);
|
||||
when(event.getWinners()).thenReturn(List.of(visitor));
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(visitor.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(ownerId));
|
||||
|
||||
pocketController.onRaidFinish(event);
|
||||
|
||||
verify(pocketBases, never()).unlockFlight(ownerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void unlockedOwnerReceivesFlightInsidePocketBaseBuffer() {
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Location location = mock(Location.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
PocketBaseState pocket = new PocketBaseState(playerId, 1, Optional.empty())
|
||||
.withFlightUnlocked();
|
||||
PlayerState noNormalFlight = PlayerState.newPlayer(playerId, "Alex");
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(stateManager.player(playerId, "Alex")).thenReturn(noNormalFlight);
|
||||
when(player.getWorld()).thenReturn(pocketWorld);
|
||||
when(player.getLocation()).thenReturn(location);
|
||||
when(player.getAllowFlight()).thenReturn(false);
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(location.getX()).thenReturn(40.5);
|
||||
when(location.getZ()).thenReturn(0.5);
|
||||
when(location.getBlockX()).thenReturn(40);
|
||||
when(location.getBlockZ()).thenReturn(0);
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(playerId));
|
||||
when(pocketBases.state(playerId)).thenReturn(pocket);
|
||||
when(pocketBases.policy()).thenReturn(
|
||||
new PocketBasePolicy(PluginSettings.from(Map.of()))
|
||||
);
|
||||
|
||||
pocketController.run();
|
||||
|
||||
verify(player).setAllowFlight(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void flyingInPocketBaseBufferShowsLeavingWarning() {
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Location location = mock(Location.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
PocketBaseState pocket = new PocketBaseState(playerId, 1, Optional.empty())
|
||||
.withFlightUnlocked();
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(stateManager.player(playerId, "Alex")).thenReturn(
|
||||
PlayerState.newPlayer(playerId, "Alex")
|
||||
);
|
||||
when(player.getWorld()).thenReturn(pocketWorld);
|
||||
when(player.getLocation()).thenReturn(location);
|
||||
when(player.isFlying()).thenReturn(true);
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(location.getBlockX()).thenReturn(40);
|
||||
when(location.getBlockZ()).thenReturn(0);
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(playerId));
|
||||
when(pocketBases.state(playerId)).thenReturn(pocket);
|
||||
when(pocketBases.policy()).thenReturn(
|
||||
new PocketBasePolicy(PluginSettings.from(Map.of()))
|
||||
);
|
||||
|
||||
pocketController.run();
|
||||
|
||||
verify(player).sendTitle(anyString(), anyString(), anyInt(), anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void pocketBaseFlightEndsBeyondSixteenBlockBuffer() {
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Location location = mock(Location.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
PocketBaseState pocket = new PocketBaseState(playerId, 1, Optional.empty())
|
||||
.withFlightUnlocked();
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(stateManager.player(playerId, "Alex")).thenReturn(
|
||||
PlayerState.newPlayer(playerId, "Alex")
|
||||
);
|
||||
when(player.getWorld()).thenReturn(pocketWorld);
|
||||
when(player.getLocation()).thenReturn(location);
|
||||
when(player.getAllowFlight()).thenReturn(false);
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(location.getBlockX()).thenReturn(40, 48);
|
||||
when(location.getBlockZ()).thenReturn(0);
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(playerId));
|
||||
when(pocketBases.state(playerId)).thenReturn(pocket);
|
||||
when(pocketBases.policy()).thenReturn(
|
||||
new PocketBasePolicy(PluginSettings.from(Map.of()))
|
||||
);
|
||||
|
||||
pocketController.run();
|
||||
pocketController.run();
|
||||
|
||||
verify(player).setFlying(false);
|
||||
verify(player).setAllowFlight(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void visitorDoesNotReceiveUnlockedOwnersPocketBaseFlight() {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
World pocketWorld = mock(World.class);
|
||||
Location location = mock(Location.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
PocketBaseState pocket = new PocketBaseState(ownerId, 1, Optional.empty())
|
||||
.withFlightUnlocked();
|
||||
BaseFlightController pocketController = new BaseFlightController(
|
||||
server,
|
||||
stateManager,
|
||||
new SecondaryProgressionService(PluginSettings.from(Map.of())),
|
||||
new BaseBoundsService(PluginSettings.from(Map.of())),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of())),
|
||||
pocketBases,
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
|
||||
when(stateManager.player(playerId, "Alex")).thenReturn(
|
||||
PlayerState.newPlayer(playerId, "Alex")
|
||||
);
|
||||
when(player.getWorld()).thenReturn(pocketWorld);
|
||||
when(player.getLocation()).thenReturn(location);
|
||||
when(player.getAllowFlight()).thenReturn(false);
|
||||
when(pocketWorld.getUID()).thenReturn(pocketWorldId);
|
||||
when(pocketBases.ownerForPocketWorld(pocketWorldId)).thenReturn(Optional.of(ownerId));
|
||||
when(pocketBases.state(ownerId)).thenReturn(pocket);
|
||||
|
||||
pocketController.run();
|
||||
|
||||
verify(player, never()).setAllowFlight(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void walkingInWarningBufferDoesNotShowLeavingBaseWarning() {
|
||||
when(player.isFlying()).thenReturn(false);
|
||||
|
||||
@@ -489,6 +489,7 @@ final class BaseSettingsCommandTest {
|
||||
&& message.contains("type=void/the_void")
|
||||
&& message.contains("hostile spawning=enabled")
|
||||
&& message.contains("passive spawning=disabled")
|
||||
&& message.contains("flight=complete a raid to unlock")
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,13 @@ final class BaseSettingsDialogFactoryTest {
|
||||
specification
|
||||
);
|
||||
assertTrue(root.content().message().contains("Base 4/4"));
|
||||
BaseSettingsDialogFactory.ListSpec pocketSettings = assertInstanceOf(
|
||||
BaseSettingsDialogFactory.ListSpec.class,
|
||||
root.dialogs().get(3)
|
||||
);
|
||||
assertTrue(pocketSettings.content().message().contains(
|
||||
"Flight: Complete a raid to unlock"
|
||||
));
|
||||
List<String> commands = commands(root);
|
||||
assertTrue(commands.contains("/basesettings status"));
|
||||
assertTrue(commands.contains("/basesettings visitors blocked"));
|
||||
|
||||
@@ -2,6 +2,7 @@ package games.dmg.spigotbase;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -58,6 +59,32 @@ final class PocketBaseManagerTest {
|
||||
assertEquals(generated, manager.returnPortal(ownerId));
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistsPocketBaseFlightUnlock() throws Exception {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
PocketBaseState current = new PocketBaseState(ownerId, 1, Optional.empty());
|
||||
PocketBaseStateManager states = mock(PocketBaseStateManager.class);
|
||||
when(states.state(ownerId)).thenReturn(current);
|
||||
when(states.updateAndSave(org.mockito.ArgumentMatchers.eq(ownerId),
|
||||
org.mockito.ArgumentMatchers.any())).thenAnswer(invocation -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
UnaryOperator<PocketBaseState> operation = invocation.getArgument(1);
|
||||
return operation.apply(current);
|
||||
});
|
||||
PocketBaseManager manager = new PocketBaseManager(
|
||||
states,
|
||||
mock(PocketBaseWorldService.class),
|
||||
new PluginSettingsProvider(PluginSettings.from(Map.of()))
|
||||
);
|
||||
|
||||
PocketBaseState updated = manager.unlockFlight(ownerId);
|
||||
|
||||
assertTrue(updated.flightUnlocked());
|
||||
verify(states).updateAndSave(
|
||||
org.mockito.ArgumentMatchers.eq(ownerId), org.mockito.ArgumentMatchers.any()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistsAndAppliesHostileMobSpawningWithoutChangingPassive() throws Exception {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
|
||||
@@ -31,7 +31,8 @@ final class YamlPocketBaseRepositoryTest {
|
||||
)),
|
||||
true,
|
||||
false,
|
||||
PocketBaseBiome.CRIMSON_FOREST
|
||||
PocketBaseBiome.CRIMSON_FOREST,
|
||||
true
|
||||
);
|
||||
YamlPocketBaseRepository repository = new YamlPocketBaseRepository(
|
||||
temporaryDirectory.resolve("pocket-bases.yml")
|
||||
@@ -55,6 +56,7 @@ final class YamlPocketBaseRepositoryTest {
|
||||
assertFalse(loaded.passiveMobSpawningEnabled());
|
||||
assertTrue(loaded.returnPortal().isEmpty());
|
||||
assertEquals(PocketBaseBiome.THE_VOID, loaded.biome());
|
||||
assertFalse(loaded.flightUnlocked());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user