feat(pocket-base): allow return portal relocation
This commit is contained in:
@@ -79,10 +79,6 @@ final class PocketBaseController implements Listener, Runnable {
|
||||
if (pocket.level() < 1) {
|
||||
return;
|
||||
}
|
||||
PlayerState owner = baseStates.player(player.getUniqueId(), player.getName());
|
||||
if (owner.baseLevel() < 4 || owner.base().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Block clicked = event.getClickedBlock();
|
||||
World world = clicked.getWorld();
|
||||
Material frameMaterial = Material.valueOf(
|
||||
@@ -98,6 +94,37 @@ final class PocketBaseController implements Listener, Runnable {
|
||||
if (portal.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Optional<UUID> pocketOwner = pocketBases.ownerForPocketWorld(world.getUID());
|
||||
if (pocketOwner.isPresent()) {
|
||||
if (!pocketOwner.orElseThrow().equals(player.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
if (PocketPortalGeometry.frameBlocks(portal.orElseThrow()).stream()
|
||||
.anyMatch(candidate -> !pocketBases.policy().contains(
|
||||
pocket.level(), candidate.x(), candidate.z()
|
||||
))) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The complete return portal must be inside your Pocket Base boundary.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pocketBases.activateReturnPortal(player.getUniqueId(), portal.orElseThrow());
|
||||
} catch (IOException | RuntimeException exception) {
|
||||
logger.log(Level.SEVERE, "Could not activate Pocket Base return portal", exception);
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The Pocket Base return portal could not be activated.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(ChatColor.GREEN + "Pocket Base return portal activated.");
|
||||
return;
|
||||
}
|
||||
PlayerState owner = baseStates.player(player.getUniqueId(), player.getName());
|
||||
if (owner.baseLevel() < 4 || owner.base().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BaseArea area = baseBounds.area(owner);
|
||||
if (PocketPortalGeometry.frameBlocks(portal.orElseThrow()).stream().anyMatch(candidate ->
|
||||
!area.contains(world.getUID(), candidate.x(), candidate.y(), candidate.z()))) {
|
||||
|
||||
@@ -60,6 +60,17 @@ final class PocketBaseManager {
|
||||
}
|
||||
}
|
||||
|
||||
PocketBaseState activateReturnPortal(
|
||||
UUID ownerId,
|
||||
PocketPortalLocation portal
|
||||
) throws IOException {
|
||||
PocketBaseState current = states.state(ownerId);
|
||||
if (current.level() < 1) {
|
||||
throw new IllegalStateException("Pocket Base I is still locked");
|
||||
}
|
||||
return states.updateAndSave(ownerId, state -> state.withReturnPortal(portal));
|
||||
}
|
||||
|
||||
PocketBaseState setMobSpawning(UUID ownerId, boolean enabled) throws IOException {
|
||||
PocketBaseState current = states.state(ownerId);
|
||||
if (current.level() < 1) {
|
||||
@@ -90,11 +101,13 @@ final class PocketBaseManager {
|
||||
}
|
||||
|
||||
PocketPortalLocation returnPortal(UUID ownerId) {
|
||||
return worlds.returnPortal(ownerId);
|
||||
return states.state(ownerId).returnPortal().orElseGet(
|
||||
() -> worlds.returnPortal(ownerId)
|
||||
);
|
||||
}
|
||||
|
||||
boolean returnPortalIsIntact(UUID ownerId) {
|
||||
return worlds.returnPortalIsIntact(ownerId);
|
||||
return worlds.returnPortalIsIntact(ownerId, returnPortal(ownerId));
|
||||
}
|
||||
|
||||
World pocketWorld(UUID ownerId) {
|
||||
|
||||
@@ -7,6 +7,7 @@ public record PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance,
|
||||
Optional<PocketPortalLocation> returnPortal,
|
||||
boolean mobSpawningEnabled
|
||||
) {
|
||||
public PocketBaseState {
|
||||
@@ -17,8 +18,9 @@ public record PocketBaseState(
|
||||
throw new IllegalArgumentException("Pocket Base level must not be negative");
|
||||
}
|
||||
entrance = entrance == null ? Optional.empty() : entrance;
|
||||
if (level == 0 && entrance.isPresent()) {
|
||||
throw new IllegalArgumentException("a locked Pocket Base cannot have an entrance");
|
||||
returnPortal = returnPortal == null ? Optional.empty() : returnPortal;
|
||||
if (level == 0 && (entrance.isPresent() || returnPortal.isPresent())) {
|
||||
throw new IllegalArgumentException("a locked Pocket Base cannot have a portal");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,26 +29,49 @@ public record PocketBaseState(
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance
|
||||
) {
|
||||
this(ownerId, level, entrance, false);
|
||||
this(ownerId, level, entrance, Optional.empty(), false);
|
||||
}
|
||||
|
||||
public PocketBaseState(
|
||||
UUID ownerId,
|
||||
int level,
|
||||
Optional<PocketPortalLocation> entrance,
|
||||
boolean mobSpawningEnabled
|
||||
) {
|
||||
this(ownerId, level, entrance, Optional.empty(), mobSpawningEnabled);
|
||||
}
|
||||
|
||||
public static PocketBaseState locked(UUID ownerId) {
|
||||
return new PocketBaseState(ownerId, 0, Optional.empty(), false);
|
||||
return new PocketBaseState(
|
||||
ownerId, 0, Optional.empty(), Optional.empty(), false
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withLevel(int newLevel) {
|
||||
return new PocketBaseState(ownerId, newLevel, entrance, mobSpawningEnabled);
|
||||
return new PocketBaseState(
|
||||
ownerId, newLevel, entrance, returnPortal, mobSpawningEnabled
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withEntrance(PocketPortalLocation portal) {
|
||||
return new PocketBaseState(ownerId, level, Optional.of(portal), mobSpawningEnabled);
|
||||
return new PocketBaseState(
|
||||
ownerId, level, Optional.of(portal), returnPortal, mobSpawningEnabled
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withoutEntrance() {
|
||||
return new PocketBaseState(ownerId, level, Optional.empty(), mobSpawningEnabled);
|
||||
return new PocketBaseState(
|
||||
ownerId, level, Optional.empty(), returnPortal, mobSpawningEnabled
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withReturnPortal(PocketPortalLocation portal) {
|
||||
return new PocketBaseState(
|
||||
ownerId, level, entrance, Optional.of(portal), mobSpawningEnabled
|
||||
);
|
||||
}
|
||||
|
||||
public PocketBaseState withMobSpawningEnabled(boolean enabled) {
|
||||
return new PocketBaseState(ownerId, level, entrance, enabled);
|
||||
return new PocketBaseState(ownerId, level, entrance, returnPortal, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,11 @@ final class PocketBaseWorldService {
|
||||
);
|
||||
}
|
||||
|
||||
boolean returnPortalIsIntact(UUID ownerId) {
|
||||
PocketPortalLocation portal = returnPortal(ownerId);
|
||||
boolean returnPortalIsIntact(UUID ownerId, PocketPortalLocation portal) {
|
||||
World world = ensureWorld(ownerId);
|
||||
if (!portal.worldId().equals(world.getUID())) {
|
||||
return false;
|
||||
}
|
||||
Material frame = Material.valueOf(settings.current().pocketBasePortalFrameMaterial());
|
||||
return PocketPortalGeometry.frameBlocks(portal).stream()
|
||||
.allMatch(position -> world.getBlockAt(
|
||||
|
||||
@@ -43,6 +43,7 @@ public final class YamlPocketBaseRepository {
|
||||
ownerId,
|
||||
level,
|
||||
loadPortal(yaml, path + ".entrance"),
|
||||
loadPortal(yaml, path + ".return-portal"),
|
||||
yaml.getBoolean(path + ".mob-spawning-enabled", false)
|
||||
);
|
||||
states.put(ownerId, state);
|
||||
@@ -64,6 +65,9 @@ public final class YamlPocketBaseRepository {
|
||||
yaml.set(path + ".level", state.level());
|
||||
yaml.set(path + ".mob-spawning-enabled", state.mobSpawningEnabled());
|
||||
state.entrance().ifPresent(portal -> savePortal(yaml, path + ".entrance", portal));
|
||||
state.returnPortal().ifPresent(portal ->
|
||||
savePortal(yaml, path + ".return-portal", portal)
|
||||
);
|
||||
}
|
||||
Path temporary = Files.createTempFile(parent, "spigot-base-pocket-", ".yml");
|
||||
try {
|
||||
@@ -96,7 +100,7 @@ public final class YamlPocketBaseRepository {
|
||||
if (worldId == null || worldName == null || axis == null
|
||||
|| !yaml.isInt(path + ".x") || !yaml.isInt(path + ".y")
|
||||
|| !yaml.isInt(path + ".z")) {
|
||||
throw new IllegalArgumentException("invalid Pocket Base entrance");
|
||||
throw new IllegalArgumentException("invalid Pocket Base portal");
|
||||
}
|
||||
return Optional.of(new PocketPortalLocation(
|
||||
UUID.fromString(worldId),
|
||||
|
||||
Reference in New Issue
Block a user