From 00aa7566adea9465e24304c36a8d72dc3323986b Mon Sep 17 00:00:00 2001 From: Dylan Garvis Date: Mon, 10 Aug 2026 19:58:09 -0400 Subject: [PATCH] feat(commands): add base command aliases --- README.md | 8 ++--- design/log.md | 6 ++++ .../us-001-unlock-and-establish-base.md | 1 + .../us-005-unlock-base-teleportation.md | 1 + .../us-008-unlock-visitor-access.md | 1 + .../dmg/spigotbase/BaseTeleportManager.java | 2 +- src/main/resources/plugin.yml | 3 ++ .../dmg/spigotbase/PluginMetadataTest.java | 32 +++++++++++++++++++ 8 files changed, 49 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e47f7e0..35317f9 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,13 @@ The plugin JAR is written to `build/libs/`. ## Player commands ```text -/setbase -/base -/base upgrade +/setbase (alias: /sethome) +/base (alias: /home) +/base upgrade (alias: /home upgrade) /basenavigation /baseflight /basevisitors -/gotobase +/gotobase (alias: /visit ) /baseprogress /baseprogress bossbar ``` diff --git a/design/log.md b/design/log.md index 92b7e90..756c51c 100644 --- a/design/log.md +++ b/design/log.md @@ -40,3 +40,9 @@ description: Chronological record of material decisions affecting the Spigot Bas - Made progression materials, visitor currency, boss-bar duration, particle count, and title timing configurable. - Preserved unknown forward-compatible YAML fields for retained player records while continuing to reject invalid progression state. - Completed and verified all approved user stories with the automated Gradle check lifecycle. + +## 2026-08-10 — Player command aliases + +- Added `/sethome` for `/setbase`, `/home` for `/base`, and `/visit` for `/gotobase`. +- Visitor autocomplete remains available for eligible offline bases through the `/visit` alias. +- Verified the aliases and plugin build with `./gradlew clean check jar`. diff --git a/design/user-stories/us-001-unlock-and-establish-base.md b/design/user-stories/us-001-unlock-and-establish-base.md index 49af35e..de30f80 100644 --- a/design/user-stories/us-001-unlock-and-establish-base.md +++ b/design/user-stories/us-001-unlock-and-establish-base.md @@ -17,6 +17,7 @@ As a **player**, I want to earn and set a personal base so that later quality-of - [x] Player-placed blocks may contribute when broken; natural-generation detection is not required. - [x] Base I unlocks when the player reaches the configured threshold, which defaults to 250 qualifying blocks. - [x] `/setbase` is unavailable before Base I and explains the unmet requirement. +- [x] `/sethome` is an alias for `/setbase` with identical behavior. - [x] After Base I unlocks, `/setbase` records the player's current world and block location as the center of a cylindrical base. - [x] The initial cylinder has a configurable 10-block horizontal radius and extends a configurable 25 blocks above and 25 blocks below the set Y coordinate. - [x] The first successful `/setbase` is immediately available. diff --git a/design/user-stories/us-005-unlock-base-teleportation.md b/design/user-stories/us-005-unlock-base-teleportation.md index 83d68ce..75274e6 100644 --- a/design/user-stories/us-005-unlock-base-teleportation.md +++ b/design/user-stories/us-005-unlock-base-teleportation.md @@ -15,6 +15,7 @@ As a **player with Base II**, I want to earn `/base` so that I can return safely - [x] Only placements made in Survival mode and within the base's current horizontal and vertical bounds count. - [x] Player-placed blocks and replacement of previously broken blocks may contribute repeatedly. - [x] Base III unlocks `/base` with a configurable 30-second warm-up and three-hour cooldown by default. +- [x] `/home` is an alias for `/base`, including `/home upgrade`. - [x] Looking around without changing block coordinates does not cancel the warm-up. - [x] Changing block X, Y, or Z, taking damage, teleporting, changing worlds, dying, disconnecting, or starting a conflicting teleport cancels the warm-up. - [x] Cancellation clearly informs the player and does not consume the cooldown. diff --git a/design/user-stories/us-008-unlock-visitor-access.md b/design/user-stories/us-008-unlock-visitor-access.md index b6403cf..d057c04 100644 --- a/design/user-stories/us-008-unlock-visitor-access.md +++ b/design/user-stories/us-008-unlock-visitor-access.md @@ -18,6 +18,7 @@ As a **player with Base III**, I want to open my base to visitors so that other - [x] `/basevisitors` lets a Base IV owner toggle visitor access on and off. - [x] The visitor-access preference persists across reconnects and restarts. - [x] `/gotobase ` autocompletes bases that the requesting player is currently eligible to visit. +- [x] `/visit ` aliases `/gotobase ` with identical autocomplete, including eligible bases whose owners are offline. - [x] Enabled bases remain visitable while their owners are offline. - [x] A visitor teleport uses the destination owner's current warm-up tier. - [x] Looking around is permitted, while movement between block coordinates, damage, teleportation, world change, death, logout, or a conflicting teleport cancels the visitor warm-up. diff --git a/src/main/java/games/dmg/spigotbase/BaseTeleportManager.java b/src/main/java/games/dmg/spigotbase/BaseTeleportManager.java index 330115d..e49118a 100644 --- a/src/main/java/games/dmg/spigotbase/BaseTeleportManager.java +++ b/src/main/java/games/dmg/spigotbase/BaseTeleportManager.java @@ -189,7 +189,7 @@ final class BaseTeleportManager implements Listener { public void onCommand(PlayerCommandPreprocessEvent event) { String command = event.getMessage().toLowerCase(Locale.ROOT).split("\\s+", 2)[0]; if (command.equals("/base") || command.equals("/gotobase") - || command.equals("/spawn") || command.equals("/home") + || command.equals("/visit") || command.equals("/spawn") || command.equals("/home") || command.equals("/tp") || command.equals("/teleport")) { cancel(event.getPlayer(), "Base teleport cancelled by another teleport command."); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9c1efa1..e61ee53 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,9 +8,11 @@ commands: setbase: description: Set your unlocked personal base. usage: /setbase + aliases: [sethome] base: description: Teleport to or upgrade your base. usage: /base [upgrade] + aliases: [home] basenavigation: description: Toggle particle navigation toward your base. usage: /basenavigation [on|off] @@ -23,6 +25,7 @@ commands: gotobase: description: Visit an available player base. usage: /gotobase + aliases: [visit] baseprogress: description: View progression or toggle progress boss bars. usage: /baseprogress [bossbar] diff --git a/src/test/java/games/dmg/spigotbase/PluginMetadataTest.java b/src/test/java/games/dmg/spigotbase/PluginMetadataTest.java index 269c4eb..01bb403 100644 --- a/src/test/java/games/dmg/spigotbase/PluginMetadataTest.java +++ b/src/test/java/games/dmg/spigotbase/PluginMetadataTest.java @@ -4,11 +4,36 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.InputStream; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; import org.yaml.snakeyaml.Yaml; final class PluginMetadataTest { + @Test + void sethomeAliasesSetbase() { + Map commands = commands(); + + Map setbase = (Map) commands.get("setbase"); + assertEquals(List.of("sethome"), setbase.get("aliases")); + } + + @Test + void homeAliasesBase() { + Map commands = commands(); + + Map base = (Map) commands.get("base"); + assertEquals(List.of("home"), base.get("aliases")); + } + + @Test + void visitAliasesGotobase() { + Map commands = commands(); + + Map gotobase = (Map) commands.get("gotobase"); + assertEquals(List.of("visit"), gotobase.get("aliases")); + } + @Test void declaresPluginEntrypointCommandsAndPermissions() { InputStream stream = getClass().getClassLoader().getResourceAsStream("plugin.yml"); @@ -30,4 +55,11 @@ final class PluginMetadataTest { Map permissions = (Map) plugin.get("permissions"); assertNotNull(permissions.get("spigotbase.admin")); } + + private Map commands() { + InputStream stream = getClass().getClassLoader().getResourceAsStream("plugin.yml"); + assertNotNull(stream); + Map plugin = new Yaml().load(stream); + return (Map) plugin.get("commands"); + } }