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, - **Left-click** the sign: dials the shown destination - chevrons light in sequence,
then the interior becomes the event horizon (`gate.iris-open-material`, default then the interior becomes the event horizon (`gate.iris-open-material`, default
water) and travel opens up. It auto-closes after `dialing.open-seconds`. 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. - 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 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 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; 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 { public class SignInteractListener implements Listener {
private final StargatePlugin plugin; private final StargatePlugin plugin;
@@ -55,10 +55,26 @@ public class SignInteractListener implements Listener {
SignRenderer.render(rg, gateManager); SignRenderer.render(rg, gateManager);
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1f); player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1f);
} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) { } 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) { private void dial(RuntimeGate from, org.bukkit.entity.Player player) {
if (from.isOpen()) { if (from.isOpen()) {
player.sendMessage(Component.text("This gate is already active.", NamedTextColor.RED)); player.sendMessage(Component.text("This gate is already active.", NamedTextColor.RED));