From c98f89c225698491ee814e15ee55b94e3c0e2794 Mon Sep 17 00:00:00 2001 From: Michael Burgess Date: Sun, 9 Aug 2026 12:16:24 -0400 Subject: [PATCH] Add shift-left-click on the sign as a shortcut to destroy the gate Same permission check as /sg destroy (owner with stargate.destroy, or stargate.admin). Also breaks the physical sign block via breakNaturally() so it drops like a normal mined sign instead of just vanishing, matching what happens when StructureProtectListener reacts to an actual BlockBreakEvent on the sign. --- README.md | 3 +++ .../paper/listener/SignInteractListener.java | 20 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2ba6256..8241257 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,9 @@ material, unsealed interior, too far from the sign, etc. - **Left-click** the sign: dials the shown destination - chevrons light in sequence, then the interior becomes the event horizon (`gate.iris-open-material`, default water) and travel opens up. It auto-closes after `dialing.open-seconds`. +- **Shift + left-click** the sign: destroys the gate on the spot (same permission + check as `/sg destroy` - owner or `stargate.admin`), breaking the sign as if + you'd mined it. Quicker than looking at the sign and typing the command. - Travel is **one-way**: only the gate you dialed *from* can send anything anywhere. Walking (or wandering, or drifting) into its event horizon teleports whatever entered to the destination, arriving just clear of its iris (never inside it) and diff --git a/stargate-paper/src/main/java/dev/skywalker3200/stargate/paper/listener/SignInteractListener.java b/stargate-paper/src/main/java/dev/skywalker3200/stargate/paper/listener/SignInteractListener.java index 2c2327d..a4563bb 100644 --- a/stargate-paper/src/main/java/dev/skywalker3200/stargate/paper/listener/SignInteractListener.java +++ b/stargate-paper/src/main/java/dev/skywalker3200/stargate/paper/listener/SignInteractListener.java @@ -17,7 +17,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import java.util.List; -/** Right-click a gate's sign to cycle its destination, left-click to dial it. */ +/** Right-click a gate's sign to cycle its destination, left-click to dial it, shift-left-click to destroy it. */ public class SignInteractListener implements Listener { private final StargatePlugin plugin; @@ -55,10 +55,26 @@ public class SignInteractListener implements Listener { SignRenderer.render(rg, gateManager); player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1f); } else if (event.getAction() == Action.LEFT_CLICK_BLOCK) { - dial(rg, player); + if (player.isSneaking()) { + destroy(rg, block, player); + } else { + dial(rg, player); + } } } + private void destroy(RuntimeGate rg, Block signBlock, org.bukkit.entity.Player player) { + boolean allowed = player.hasPermission("stargate.admin") + || (rg.getGate().getOwner() != null && rg.getGate().getOwner().equals(player.getUniqueId()) && player.hasPermission("stargate.destroy")); + if (!allowed) { + player.sendMessage(Component.text("You can't destroy this stargate.", NamedTextColor.RED)); + return; + } + gateManager.destroyGate(rg); + signBlock.breakNaturally(); + player.sendMessage(Component.text("Destroyed '" + rg.getGate().getName() + "'.", NamedTextColor.YELLOW)); + } + private void dial(RuntimeGate from, org.bukkit.entity.Player player) { if (from.isOpen()) { player.sendMessage(Component.text("This gate is already active.", NamedTextColor.RED));