Add optional WorldEdit soft-dependency; use its wand selection for pos1/pos2
Build / build (push) Successful in 1m19s

This commit is contained in:
Michael Burgess
2026-08-07 10:43:06 -04:00
parent d1d61c5d68
commit 412c9411b8
8 changed files with 107 additions and 4 deletions
@@ -13,6 +13,7 @@ import us.tss3.blockparty.config.ArenaConfig;
import us.tss3.blockparty.logic.ArenaPhase;
import us.tss3.blockparty.persistence.PlayerStats;
import us.tss3.blockparty.session.PlayerSession;
import us.tss3.blockparty.worldedit.WorldEditHook;
import java.util.ArrayList;
import java.util.List;
@@ -219,7 +220,16 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
private void pos1(CommandSender sender, String[] args) {
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
withArena(sender, args, arena -> {
Location loc = ((Player) sender).getLocation();
Player player = (Player) sender;
WorldEditHook.Corners selection = worldEditSelection(player);
if (selection != null) {
arena.getConfig().setPos1(selection.min());
arena.getConfig().setWorldName(selection.worldName());
plugin.getArenaManager().save(arena);
sender.sendMessage(plugin.getMessages().get("admin.pos1-set-we", Map.of("arena", arena.getConfig().getName())));
return;
}
Location loc = player.getLocation();
arena.getConfig().setPos1(new int[]{loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()});
arena.getConfig().setWorldName(loc.getWorld().getName());
plugin.getArenaManager().save(arena);
@@ -230,13 +240,36 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
private void pos2(CommandSender sender, String[] args) {
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
withArena(sender, args, arena -> {
Location loc = ((Player) sender).getLocation();
Player player = (Player) sender;
WorldEditHook.Corners selection = worldEditSelection(player);
if (selection != null) {
arena.getConfig().setPos2(selection.max());
plugin.getArenaManager().save(arena);
sender.sendMessage(plugin.getMessages().get("admin.pos2-set-we", Map.of("arena", arena.getConfig().getName())));
return;
}
Location loc = player.getLocation();
arena.getConfig().setPos2(new int[]{loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()});
plugin.getArenaManager().save(arena);
sender.sendMessage(plugin.getMessages().get("admin.pos2-set", Map.of("arena", arena.getConfig().getName())));
});
}
/** Returns the player's active WorldEdit selection if the WorldEdit plugin is installed,
* the integration is enabled, and they have one - otherwise null so callers fall back to
* the player's standing location. WorldEdit classes are only referenced once its plugin
* is confirmed present, so a server without WorldEdit installed never loads them. */
private WorldEditHook.Corners worldEditSelection(Player player) {
if (!plugin.getConfigManager().isWorldEditEnabled() || Bukkit.getPluginManager().getPlugin("WorldEdit") == null) {
return null;
}
try {
return WorldEditHook.getSelection(player);
} catch (Throwable t) {
return null;
}
}
private void setFloor(CommandSender sender, String[] args) {
if (!requireAdmin(sender, "blockparty.admin.setup")) return;
// /bp setfloor <arena> <mat1,mat2,...>
@@ -65,6 +65,10 @@ public class ConfigManager {
return config.getBoolean("integrations.vault", true);
}
public boolean isWorldEditEnabled() {
return config.getBoolean("integrations.worldedit", true);
}
public List<String> getDefaultFloorMaterials() {
return config.getStringList("default-floor-materials");
}
@@ -0,0 +1,43 @@
package us.tss3.blockparty.worldedit;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import org.bukkit.entity.Player;
/**
* Reads a player's active WorldEdit selection (made with the WE wand / {@code //pos1} and
* {@code //pos2}) so BlockParty's floor-region commands can adopt it directly instead of
* requiring the player to stand at each corner separately. This class is only ever touched
* once the caller has confirmed the WorldEdit plugin is actually present (see
* BlockPartyCommand#worldEditSelection), so a server without WorldEdit installed never
* attempts to load these classes.
*/
public final class WorldEditHook {
private WorldEditHook() {
}
/** Two opposite corners of a cuboid selection, plus the world they're in. */
public record Corners(int[] min, int[] max, String worldName) {
}
/** Returns the player's current WorldEdit cuboid selection corners, or null if they have
* no active/complete selection (or anything about the lookup fails). */
public static Corners getSelection(Player player) {
try {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(BukkitAdapter.adapt(player));
Region region = session.getSelection(BukkitAdapter.adapt(player.getWorld()));
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
return new Corners(
new int[]{min.x(), min.y(), min.z()},
new int[]{max.x(), max.y(), max.z()},
player.getWorld().getName());
} catch (Exception ex) {
return null;
}
}
}
+3
View File
@@ -80,3 +80,6 @@ integrations:
placeholderapi: true
# If false, money rewards are skipped even when Vault is installed (console commands are unaffected).
vault: true
# If true (default) and WorldEdit is installed, /blockparty pos1 and pos2 use your active
# WorldEdit wand selection instead of your standing location, when you have one selected.
worldedit: true
+2
View File
@@ -24,6 +24,8 @@ admin:
billboard-removed: "<green>Billboard removed for '%arena%'.</green>"
pos1-set: "<green>Position 1 set for '%arena%'.</green>"
pos2-set: "<green>Position 2 set for '%arena%'.</green>"
pos1-set-we: "<green>Position 1 set for '%arena%' from your WorldEdit selection.</green>"
pos2-set-we: "<green>Position 2 set for '%arena%' from your WorldEdit selection.</green>"
floor-set: "<green>Floor palette for '%arena%' set to %count% material(s).</green>"
floor-generated: "<green>Floor generated for '%arena%'.</green>"
reloaded: "<green>BlockParty configuration reloaded.</green>"
+1 -1
View File
@@ -4,7 +4,7 @@ main: us.tss3.blockparty.BlockPartyPlugin
api-version: '1.21'
author: tss3
description: Colored-floor elimination minigame.
softdepend: [PlaceholderAPI, Vault]
softdepend: [PlaceholderAPI, Vault, WorldEdit]
commands:
blockparty: