This commit is contained in:
@@ -25,7 +25,8 @@ slightly faster round. Last player standing wins.
|
|||||||
All admin/config commands live under `/blockparty` (alias `/bp`) and work from console
|
All admin/config commands live under `/blockparty` (alias `/bp`) and work from console
|
||||||
where it makes sense (`create`, `delete`, `enable`, `disable`, `info`, `list`, `reload`).
|
where it makes sense (`create`, `delete`, `enable`, `disable`, `info`, `list`, `reload`).
|
||||||
Commands that require a physical location (`setlobby`, `setspawn`, `setspectator`,
|
Commands that require a physical location (`setlobby`, `setspawn`, `setspectator`,
|
||||||
`setbillboard`, `pos1`, `pos2`) require a player sender.
|
`setbillboard`, `pos1`, `pos2`) require a player sender. `delbillboard`, `billboards`, `info`
|
||||||
|
work fine from console.
|
||||||
|
|
||||||
### Admin
|
### Admin
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
@@ -38,8 +39,9 @@ Commands that require a physical location (`setlobby`, `setspawn`, `setspectator
|
|||||||
| `/blockparty setlobby <arena>` | Set the waiting-room location |
|
| `/blockparty setlobby <arena>` | Set the waiting-room location |
|
||||||
| `/blockparty setspawn <arena>` | Set the in-game spawn location |
|
| `/blockparty setspawn <arena>` | Set the in-game spawn location |
|
||||||
| `/blockparty setspectator <arena>` | Set the spectator/eliminated location |
|
| `/blockparty setspectator <arena>` | Set the spectator/eliminated location |
|
||||||
| `/blockparty setbillboard <arena>` | (Optional) place a display block here that mirrors the current target color |
|
| `/blockparty setbillboard <arena> [name]` | (Optional) place a named display block here that mirrors the current target color; `name` defaults to `default`, so you can have any number by giving each a unique name |
|
||||||
| `/blockparty delbillboard <arena>` | Remove the billboard, if one is set |
|
| `/blockparty delbillboard <arena> [name]` | Remove a named billboard (defaults to `default`) |
|
||||||
|
| `/blockparty billboards <arena>` | List an arena's billboards and whether each is enabled |
|
||||||
| `/blockparty pos1 <arena>` | Set floor region corner 1 |
|
| `/blockparty pos1 <arena>` | Set floor region corner 1 |
|
||||||
| `/blockparty pos2 <arena>` | Set floor region corner 2 |
|
| `/blockparty pos2 <arena>` | Set floor region corner 2 |
|
||||||
| `/blockparty setfloor <arena> <mat1,mat2,...>` | Set the allowed floor materials |
|
| `/blockparty setfloor <arena> <mat1,mat2,...>` | Set the allowed floor materials |
|
||||||
@@ -86,8 +88,9 @@ Commands that require a physical location (`setlobby`, `setspawn`, `setspectator
|
|||||||
each round (BlockParty does not scan the world every round — it restores from the saved
|
each round (BlockParty does not scan the world every round — it restores from the saved
|
||||||
layout for performance and determinism).
|
layout for performance and determinism).
|
||||||
8. Optionally, stand somewhere visible near/above the floor and run `/bp setbillboard lobby1`
|
8. Optionally, stand somewhere visible near/above the floor and run `/bp setbillboard lobby1`
|
||||||
|
(or `/bp setbillboard lobby1 <name>` to add more than one, e.g. one per side of the arena)
|
||||||
to place a big display block that mirrors the round's target color — purely cosmetic and
|
to place a big display block that mirrors the round's target color — purely cosmetic and
|
||||||
entirely optional (see "Billboard" below).
|
entirely optional (see "Billboards" below).
|
||||||
9. `/bp info lobby1` to confirm there are no validation errors.
|
9. `/bp info lobby1` to confirm there are no validation errors.
|
||||||
10. `/bp enable lobby1`.
|
10. `/bp enable lobby1`.
|
||||||
11. Players run `/bp join lobby1`. Once `min-players` is reached the countdown starts
|
11. Players run `/bp join lobby1`. Once `min-players` is reached the countdown starts
|
||||||
@@ -112,22 +115,29 @@ Commands that require a physical location (`setlobby`, `setspawn`, `setspectator
|
|||||||
(`generated-layout`) so it can be restored exactly, every round, without re-scanning or
|
(`generated-layout`) so it can be restored exactly, every round, without re-scanning or
|
||||||
re-randomizing the world.
|
re-randomizing the world.
|
||||||
|
|
||||||
### Billboard
|
### Billboards
|
||||||
|
|
||||||
An arena billboard is a `BlockDisplay` entity that visually shows the currently selected
|
An arena billboard is a `BlockDisplay` entity that visually shows the currently selected
|
||||||
target color/block each round, in addition to the title/actionbar/hotbar-item cues. It is
|
target color/block each round, in addition to the title/actionbar/hotbar-item cues. An arena
|
||||||
entirely optional:
|
may have any number of them (e.g. one visible from each side of the floor), each independently
|
||||||
|
named, positioned and toggled. Entirely optional:
|
||||||
|
|
||||||
- Per-arena: only spawned if `/bp setbillboard <arena>` has been run (stored as `billboard`
|
- Per-billboard: `/bp setbillboard <arena> [name]` places/updates one at your current location;
|
||||||
in the arena's yml). `/bp delbillboard <arena>` removes it.
|
`name` defaults to `default` if omitted, so the simple single-billboard flow needs no name at
|
||||||
- Per-arena toggle: `billboard-enabled` in the arena's yml (default `true`) lets you keep the
|
all. Give each a distinct `name` to have several at once (e.g. `/bp setbillboard lobby1 north`,
|
||||||
location set but temporarily turn it off without deleting it.
|
`/bp setbillboard lobby1 south`). `/bp delbillboard <arena> [name]` removes one. `/bp billboards
|
||||||
- Global toggle: `ui.billboard` in `config.yml` (default `true`) disables billboards across
|
<arena>` lists an arena's billboards and whether each is enabled.
|
||||||
|
- Per-billboard toggle: stored per name in the arena's yml (`billboards.<name>.enabled`, default
|
||||||
|
`true`) — set to `false` to keep the location saved but temporarily stop displaying it, without
|
||||||
|
running `delbillboard`.
|
||||||
|
- Global toggle: `ui.billboard` in `config.yml` (default `true`) disables every billboard on
|
||||||
every arena at once, e.g. for performance-constrained servers.
|
every arena at once, e.g. for performance-constrained servers.
|
||||||
|
|
||||||
The entity is non-persistent (not saved to the world, so it never survives a server restart on
|
Every billboard shows the same current target color in sync — they're just multiple vantage
|
||||||
its own — BlockParty re-creates it on demand) and is despawned automatically when the arena is
|
points on the same information. Entities are non-persistent (not saved to the world, so they
|
||||||
disabled, deleted, or the plugin shuts down, so it never leaks entities.
|
never survive a server restart on their own — BlockParty re-creates them on demand) and are all
|
||||||
|
despawned automatically when the arena is disabled, deleted, or the plugin shuts down, so
|
||||||
|
nothing leaks.
|
||||||
|
|
||||||
## Player usage
|
## Player usage
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,16 @@ import org.joml.Vector3f;
|
|||||||
import us.tss3.blockparty.BlockPartyPlugin;
|
import us.tss3.blockparty.BlockPartyPlugin;
|
||||||
import us.tss3.blockparty.config.ArenaConfig;
|
import us.tss3.blockparty.config.ArenaConfig;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Owns an optional {@link BlockDisplay} entity that visually mirrors an arena's currently
|
* Owns any number of named, optional {@link BlockDisplay} entities that visually mirror an
|
||||||
* selected target color. Purely cosmetic: fully optional (global toggle + per-arena
|
* arena's currently selected target color. Purely cosmetic: fully optional (global toggle +
|
||||||
* toggle/location), and every method safely no-ops when disabled, unset, or the arena's
|
* per-billboard toggle/location), and every method safely no-ops when disabled, unset, or the
|
||||||
* world isn't loaded.
|
* arena's world isn't loaded.
|
||||||
*/
|
*/
|
||||||
public class BillboardManager {
|
public class BillboardManager {
|
||||||
|
|
||||||
@@ -25,75 +27,96 @@ public class BillboardManager {
|
|||||||
|
|
||||||
private final BlockPartyPlugin plugin;
|
private final BlockPartyPlugin plugin;
|
||||||
private final ArenaConfig config;
|
private final ArenaConfig config;
|
||||||
private UUID entityId;
|
/** billboard name -> live display entity id, only present while spawned. */
|
||||||
|
private final Map<String, UUID> entityIds = new HashMap<>();
|
||||||
|
|
||||||
public BillboardManager(BlockPartyPlugin plugin, ArenaConfig config) {
|
public BillboardManager(BlockPartyPlugin plugin, ArenaConfig config) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isActive() {
|
private boolean globallyActive() {
|
||||||
return plugin.getConfigManager().isBillboardEnabled() && config.hasBillboard()
|
return plugin.getConfigManager().isBillboardEnabled() && config.hasAnyBillboards();
|
||||||
&& config.getBillboard().getWorld() != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shows (spawning the display entity if needed) the given material as the current target. */
|
/** Shows the given material as the current target on every enabled, valid billboard. */
|
||||||
public void show(Material material) {
|
public void show(Material material) {
|
||||||
if (!isActive()) {
|
if (!globallyActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String name : config.getBillboards().keySet()) {
|
||||||
|
showOne(name, material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showOne(String name, Material material) {
|
||||||
|
Location loc = config.getBillboard(name);
|
||||||
|
if (loc == null || loc.getWorld() == null || !config.isBillboardEnabled(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
BlockDisplay display = resolve();
|
BlockDisplay display = resolve(name);
|
||||||
if (display == null) {
|
if (display == null) {
|
||||||
display = spawn();
|
display = spawn(name, loc);
|
||||||
}
|
}
|
||||||
if (display != null) {
|
if (display != null) {
|
||||||
display.setBlock(material.createBlockData());
|
display.setBlock(material.createBlockData());
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to update billboard for arena '" + config.getName() + "'", ex);
|
plugin.getLogger().log(Level.WARNING, "Failed to update billboard '" + name
|
||||||
|
+ "' for arena '" + config.getName() + "'", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Blanks the display (e.g. between matches) without destroying the entity. */
|
/** Blanks every spawned display (e.g. between matches) without destroying the entities. */
|
||||||
public void clear() {
|
public void clear() {
|
||||||
BlockDisplay display = resolve();
|
for (String name : entityIds.keySet().toArray(new String[0])) {
|
||||||
|
BlockDisplay display = resolve(name);
|
||||||
if (display != null) {
|
if (display != null) {
|
||||||
display.setBlock(Material.AIR.createBlockData());
|
display.setBlock(Material.AIR.createBlockData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Fully removes the display entity. Safe to call even if nothing was ever spawned. */
|
/** Fully removes every display entity. Safe to call even if nothing was ever spawned. */
|
||||||
public void despawn() {
|
public void despawn() {
|
||||||
BlockDisplay display = resolve();
|
for (String name : entityIds.keySet().toArray(new String[0])) {
|
||||||
|
BlockDisplay display = resolve(name);
|
||||||
if (display != null) {
|
if (display != null) {
|
||||||
display.remove();
|
display.remove();
|
||||||
}
|
}
|
||||||
entityId = null;
|
entityIds.remove(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Forces the entity to be re-created at its (possibly updated) configured location next time it's shown. */
|
/** Removes a single named billboard's live entity (e.g. after deletion or relocation). */
|
||||||
public void invalidate() {
|
public void despawnOne(String name) {
|
||||||
despawn();
|
BlockDisplay display = resolve(name);
|
||||||
|
if (display != null) {
|
||||||
|
display.remove();
|
||||||
|
}
|
||||||
|
entityIds.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockDisplay resolve() {
|
/** Forces a specific billboard to be re-created at its (possibly updated) location next show(). */
|
||||||
if (entityId == null) {
|
public void invalidate(String name) {
|
||||||
|
despawnOne(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockDisplay resolve(String name) {
|
||||||
|
UUID id = entityIds.get(name);
|
||||||
|
if (id == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Entity entity = plugin.getServer().getEntity(entityId);
|
Entity entity = plugin.getServer().getEntity(id);
|
||||||
if (entity instanceof BlockDisplay display && !display.isDead()) {
|
if (entity instanceof BlockDisplay display && !display.isDead()) {
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
entityId = null;
|
entityIds.remove(name);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockDisplay spawn() {
|
private BlockDisplay spawn(String name, Location loc) {
|
||||||
Location loc = config.getBillboard();
|
|
||||||
if (loc == null || loc.getWorld() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BlockDisplay display = loc.getWorld().spawn(loc, BlockDisplay.class, bd -> {
|
BlockDisplay display = loc.getWorld().spawn(loc, BlockDisplay.class, bd -> {
|
||||||
bd.setPersistent(false);
|
bd.setPersistent(false);
|
||||||
bd.setGlowing(true);
|
bd.setGlowing(true);
|
||||||
@@ -103,7 +126,7 @@ public class BillboardManager {
|
|||||||
new Vector3f(1.5f, 1.5f, 1.5f),
|
new Vector3f(1.5f, 1.5f, 1.5f),
|
||||||
NO_ROTATION));
|
NO_ROTATION));
|
||||||
});
|
});
|
||||||
entityId = display.getUniqueId();
|
entityIds.put(name, display.getUniqueId());
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
|
|||||||
case "setspectator" -> setSpectator(sender, args);
|
case "setspectator" -> setSpectator(sender, args);
|
||||||
case "setbillboard" -> setBillboard(sender, args);
|
case "setbillboard" -> setBillboard(sender, args);
|
||||||
case "delbillboard" -> delBillboard(sender, args);
|
case "delbillboard" -> delBillboard(sender, args);
|
||||||
|
case "billboards" -> listBillboards(sender, args);
|
||||||
case "pos1" -> pos1(sender, args);
|
case "pos1" -> pos1(sender, args);
|
||||||
case "pos2" -> pos2(sender, args);
|
case "pos2" -> pos2(sender, args);
|
||||||
case "setfloor" -> setFloor(sender, args);
|
case "setfloor" -> setFloor(sender, args);
|
||||||
@@ -78,8 +79,9 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
|
|||||||
"/blockparty setlobby <arena>",
|
"/blockparty setlobby <arena>",
|
||||||
"/blockparty setspawn <arena>",
|
"/blockparty setspawn <arena>",
|
||||||
"/blockparty setspectator <arena>",
|
"/blockparty setspectator <arena>",
|
||||||
"/blockparty setbillboard <arena>",
|
"/blockparty setbillboard <arena> [name]",
|
||||||
"/blockparty delbillboard <arena>",
|
"/blockparty delbillboard <arena> [name]",
|
||||||
|
"/blockparty billboards <arena>",
|
||||||
"/blockparty pos1 <arena>",
|
"/blockparty pos1 <arena>",
|
||||||
"/blockparty pos2 <arena>",
|
"/blockparty pos2 <arena>",
|
||||||
"/blockparty setfloor <arena>",
|
"/blockparty setfloor <arena>",
|
||||||
@@ -198,25 +200,56 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
|
|||||||
|
|
||||||
private void setBillboard(CommandSender sender, String[] args) {
|
private void setBillboard(CommandSender sender, String[] args) {
|
||||||
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
|
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
|
||||||
|
String billboardName = args.length > 2 ? args[2] : "default";
|
||||||
withArena(sender, args, arena -> {
|
withArena(sender, args, arena -> {
|
||||||
arena.getConfig().setBillboard(((Player) sender).getLocation());
|
arena.getConfig().setBillboard(billboardName, ((Player) sender).getLocation());
|
||||||
arena.getConfig().setBillboardEnabled(true);
|
arena.getConfig().setBillboardEnabled(billboardName, true);
|
||||||
arena.getBillboardManager().invalidate();
|
arena.getBillboardManager().invalidate(billboardName);
|
||||||
plugin.getArenaManager().save(arena);
|
plugin.getArenaManager().save(arena);
|
||||||
sender.sendMessage(plugin.getMessages().get("admin.billboard-set", Map.of("arena", arena.getConfig().getName())));
|
sender.sendMessage(plugin.getMessages().get("admin.billboard-set",
|
||||||
|
Map.of("arena", arena.getConfig().getName(), "name", billboardName)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void delBillboard(CommandSender sender, String[] args) {
|
private void delBillboard(CommandSender sender, String[] args) {
|
||||||
if (!requireAdmin(sender, "blockparty.admin.setup")) return;
|
if (!requireAdmin(sender, "blockparty.admin.setup")) return;
|
||||||
|
String billboardName = args.length > 2 ? args[2] : "default";
|
||||||
withArena(sender, args, arena -> {
|
withArena(sender, args, arena -> {
|
||||||
arena.getBillboardManager().despawn();
|
if (!arena.getConfig().hasBillboard(billboardName)) {
|
||||||
arena.getConfig().setBillboard(null);
|
sender.sendMessage(plugin.getMessages().get("admin.billboard-unknown",
|
||||||
|
Map.of("arena", arena.getConfig().getName(), "name", billboardName)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arena.getBillboardManager().despawnOne(billboardName);
|
||||||
|
arena.getConfig().removeBillboard(billboardName);
|
||||||
plugin.getArenaManager().save(arena);
|
plugin.getArenaManager().save(arena);
|
||||||
sender.sendMessage(plugin.getMessages().get("admin.billboard-removed", Map.of("arena", arena.getConfig().getName())));
|
sender.sendMessage(plugin.getMessages().get("admin.billboard-removed",
|
||||||
|
Map.of("arena", arena.getConfig().getName(), "name", billboardName)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void listBillboards(CommandSender sender, String[] args) {
|
||||||
|
String name = argOrCurrentArenaless(args);
|
||||||
|
if (name == null) {
|
||||||
|
sender.sendMessage("Usage: /blockparty billboards <arena>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var opt = plugin.getArenaManager().get(name);
|
||||||
|
if (opt.isEmpty()) {
|
||||||
|
sender.sendMessage(plugin.getMessages().get("errors.unknown-arena", Map.of("arena", name)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ArenaConfig cfg = opt.get().getConfig();
|
||||||
|
sender.sendMessage("§6=== Billboards: " + cfg.getName() + " ===");
|
||||||
|
if (cfg.getBillboards().isEmpty()) {
|
||||||
|
sender.sendMessage("§7(none set)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String bbName : cfg.getBillboards().keySet()) {
|
||||||
|
sender.sendMessage("§7- §f" + bbName + " §7(enabled: " + cfg.isBillboardEnabled(bbName) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void pos1(CommandSender sender, String[] args) {
|
private void pos1(CommandSender sender, String[] args) {
|
||||||
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
|
if (!requireAdmin(sender, "blockparty.admin.setup") || !requirePlayer(sender)) return;
|
||||||
withArena(sender, args, arena -> {
|
withArena(sender, args, arena -> {
|
||||||
@@ -335,7 +368,7 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
|
|||||||
sender.sendMessage("§7Lobby set: §f" + (cfg.getLobby() != null));
|
sender.sendMessage("§7Lobby set: §f" + (cfg.getLobby() != null));
|
||||||
sender.sendMessage("§7Spawn set: §f" + (cfg.getSpawn() != null));
|
sender.sendMessage("§7Spawn set: §f" + (cfg.getSpawn() != null));
|
||||||
sender.sendMessage("§7Spectator set: §f" + (cfg.getSpectator() != null));
|
sender.sendMessage("§7Spectator set: §f" + (cfg.getSpectator() != null));
|
||||||
sender.sendMessage("§7Billboard set: §f" + (cfg.getBillboard() != null) + (cfg.getBillboard() != null ? " (enabled: " + cfg.isBillboardEnabled() + ")" : ""));
|
sender.sendMessage("§7Billboards: §f" + cfg.getBillboards().size() + " (see /bp billboards " + cfg.getName() + ")");
|
||||||
sender.sendMessage("§7Floor region set: §f" + cfg.hasFloorRegion());
|
sender.sendMessage("§7Floor region set: §f" + cfg.hasFloorRegion());
|
||||||
sender.sendMessage("§7Floor generated: §f" + cfg.hasGeneratedLayout());
|
sender.sendMessage("§7Floor generated: §f" + cfg.hasGeneratedLayout());
|
||||||
sender.sendMessage("§7Floor materials: §f" + cfg.getFloorMaterials().size());
|
sender.sendMessage("§7Floor materials: §f" + cfg.getFloorMaterials().size());
|
||||||
@@ -453,7 +486,7 @@ public class BlockPartyCommand implements CommandExecutor, TabCompleter {
|
|||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
return List.of("help", "join", "leave", "arenas", "stats", "create", "delete", "enable", "disable",
|
return List.of("help", "join", "leave", "arenas", "stats", "create", "delete", "enable", "disable",
|
||||||
"setlobby", "setspawn", "setspectator", "setbillboard", "delbillboard", "pos1", "pos2", "setfloor", "generate", "info", "list", "reload")
|
"setlobby", "setspawn", "setspectator", "setbillboard", "delbillboard", "billboards", "pos1", "pos2", "setfloor", "generate", "info", "list", "reload")
|
||||||
.stream().filter(s -> s.startsWith(args[0].toLowerCase())).collect(Collectors.toList());
|
.stream().filter(s -> s.startsWith(args[0].toLowerCase())).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
if (args.length == 2) {
|
if (args.length == 2) {
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/** Mutable POJO describing a single arena's configuration, mirrors arenas/<name>.yml. */
|
/** Mutable POJO describing a single arena's configuration, mirrors arenas/<name>.yml. */
|
||||||
public class ArenaConfig {
|
public class ArenaConfig {
|
||||||
@@ -15,8 +20,10 @@ public class ArenaConfig {
|
|||||||
private Location lobby;
|
private Location lobby;
|
||||||
private Location spawn;
|
private Location spawn;
|
||||||
private Location spectator;
|
private Location spectator;
|
||||||
private Location billboard;
|
/** Named billboards: displays that mirror the current round's target color. Any number
|
||||||
private boolean billboardEnabled = true;
|
* may be set (e.g. one per side of the arena), each independently enabled/disabled. */
|
||||||
|
private final Map<String, Location> billboards = new LinkedHashMap<>();
|
||||||
|
private final Set<String> disabledBillboards = new HashSet<>();
|
||||||
private int[] pos1; // x,y,z block coords
|
private int[] pos1; // x,y,z block coords
|
||||||
private int[] pos2;
|
private int[] pos2;
|
||||||
|
|
||||||
@@ -86,24 +93,42 @@ public class ArenaConfig {
|
|||||||
this.spectator = spectator;
|
this.spectator = spectator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getBillboard() {
|
/** All configured billboards by name, in insertion order. */
|
||||||
return billboard;
|
public Map<String, Location> getBillboards() {
|
||||||
|
return Collections.unmodifiableMap(billboards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBillboard(Location billboard) {
|
public Location getBillboard(String name) {
|
||||||
this.billboard = billboard;
|
return billboards.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBillboardEnabled() {
|
public void setBillboard(String name, Location location) {
|
||||||
return billboardEnabled;
|
billboards.put(name, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBillboardEnabled(boolean billboardEnabled) {
|
public void removeBillboard(String name) {
|
||||||
this.billboardEnabled = billboardEnabled;
|
billboards.remove(name);
|
||||||
|
disabledBillboards.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasBillboard() {
|
public boolean hasBillboard(String name) {
|
||||||
return billboard != null && billboardEnabled;
|
return billboards.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAnyBillboards() {
|
||||||
|
return !billboards.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBillboardEnabled(String name) {
|
||||||
|
return !disabledBillboards.contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBillboardEnabled(String name, boolean enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
disabledBillboards.remove(name);
|
||||||
|
} else {
|
||||||
|
disabledBillboards.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getPos1() {
|
public int[] getPos1() {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package us.tss3.blockparty.config;
|
package us.tss3.blockparty.config;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import us.tss3.blockparty.logic.ArenaConfigValidator;
|
import us.tss3.blockparty.logic.ArenaConfigValidator;
|
||||||
@@ -57,8 +59,21 @@ public class ArenaConfigLoader {
|
|||||||
cfg.setLobby(LocationUtil.fromSection(yml.getConfigurationSection("lobby")));
|
cfg.setLobby(LocationUtil.fromSection(yml.getConfigurationSection("lobby")));
|
||||||
cfg.setSpawn(LocationUtil.fromSection(yml.getConfigurationSection("spawn")));
|
cfg.setSpawn(LocationUtil.fromSection(yml.getConfigurationSection("spawn")));
|
||||||
cfg.setSpectator(LocationUtil.fromSection(yml.getConfigurationSection("spectator")));
|
cfg.setSpectator(LocationUtil.fromSection(yml.getConfigurationSection("spectator")));
|
||||||
cfg.setBillboard(LocationUtil.fromSection(yml.getConfigurationSection("billboard")));
|
ConfigurationSection billboardsSection = yml.getConfigurationSection("billboards");
|
||||||
cfg.setBillboardEnabled(yml.getBoolean("billboard-enabled", true));
|
if (billboardsSection != null) {
|
||||||
|
for (String bbName : billboardsSection.getKeys(false)) {
|
||||||
|
ConfigurationSection bbSection = billboardsSection.getConfigurationSection(bbName);
|
||||||
|
if (bbSection == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Location loc = LocationUtil.fromSection(bbSection.getConfigurationSection("location"));
|
||||||
|
if (loc == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cfg.setBillboard(bbName, loc);
|
||||||
|
cfg.setBillboardEnabled(bbName, bbSection.getBoolean("enabled", true));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (yml.contains("pos1")) {
|
if (yml.contains("pos1")) {
|
||||||
cfg.setPos1(new int[]{yml.getInt("pos1.x"), yml.getInt("pos1.y"), yml.getInt("pos1.z")});
|
cfg.setPos1(new int[]{yml.getInt("pos1.x"), yml.getInt("pos1.y"), yml.getInt("pos1.z")});
|
||||||
}
|
}
|
||||||
@@ -108,10 +123,14 @@ public class ArenaConfigLoader {
|
|||||||
if (cfg.getSpectator() != null) {
|
if (cfg.getSpectator() != null) {
|
||||||
LocationUtil.toSection(yml.createSection("spectator"), cfg.getSpectator());
|
LocationUtil.toSection(yml.createSection("spectator"), cfg.getSpectator());
|
||||||
}
|
}
|
||||||
if (cfg.getBillboard() != null) {
|
if (!cfg.getBillboards().isEmpty()) {
|
||||||
LocationUtil.toSection(yml.createSection("billboard"), cfg.getBillboard());
|
ConfigurationSection billboardsSection = yml.createSection("billboards");
|
||||||
|
for (var entry : cfg.getBillboards().entrySet()) {
|
||||||
|
ConfigurationSection bbSection = billboardsSection.createSection(entry.getKey());
|
||||||
|
LocationUtil.toSection(bbSection.createSection("location"), entry.getValue());
|
||||||
|
bbSection.set("enabled", cfg.isBillboardEnabled(entry.getKey()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
yml.set("billboard-enabled", cfg.isBillboardEnabled());
|
|
||||||
if (cfg.getPos1() != null) {
|
if (cfg.getPos1() != null) {
|
||||||
yml.set("pos1.x", cfg.getPos1()[0]);
|
yml.set("pos1.x", cfg.getPos1()[0]);
|
||||||
yml.set("pos1.y", cfg.getPos1()[1]);
|
yml.set("pos1.y", cfg.getPos1()[1]);
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ admin:
|
|||||||
lobby-set: "<green>Lobby set for '%arena%'.</green>"
|
lobby-set: "<green>Lobby set for '%arena%'.</green>"
|
||||||
spawn-set: "<green>Spawn set for '%arena%'.</green>"
|
spawn-set: "<green>Spawn set for '%arena%'.</green>"
|
||||||
spectator-set: "<green>Spectator location set for '%arena%'.</green>"
|
spectator-set: "<green>Spectator location set for '%arena%'.</green>"
|
||||||
billboard-set: "<green>Billboard set for '%arena%'. It will display the target color each round.</green>"
|
billboard-set: "<green>Billboard '%name%' set for '%arena%'. It will display the target color each round.</green>"
|
||||||
billboard-removed: "<green>Billboard removed for '%arena%'.</green>"
|
billboard-removed: "<green>Billboard '%name%' removed for '%arena%'.</green>"
|
||||||
|
billboard-unknown: "<red>No billboard named '%name%' exists for '%arena%'.</red>"
|
||||||
pos1-set: "<green>Position 1 set for '%arena%'.</green>"
|
pos1-set: "<green>Position 1 set for '%arena%'.</green>"
|
||||||
pos2-set: "<green>Position 2 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>"
|
pos1-set-we: "<green>Position 1 set for '%arena%' from your WorldEdit selection.</green>"
|
||||||
|
|||||||
Reference in New Issue
Block a user