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.
This commit is contained in:
Michael Burgess
2026-08-09 12:16:24 -04:00
parent 0c74b68cbe
commit c98f89c225
2 changed files with 21 additions and 2 deletions
+3
View File
@@ -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
@@ -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));