fix: wand listener, killer/survivor spawn commands, double phase exit, generatorManager null check
This commit is contained in:
parent
1adb8c84fd
commit
b339f4c029
5 changed files with 125 additions and 21 deletions
|
|
@ -83,6 +83,13 @@ public class SetupCommand implements TabExecutor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called by PlayerInteractListener when wand is used. */
|
||||||
|
public void setWandPos(Player player, int num, Location loc) {
|
||||||
|
String key = player.getUniqueId().toString();
|
||||||
|
selectionCorners.put(key + "_pos" + num, loc);
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>[Wand] Точка " + num + ": " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean saveTemplate(Player player, String[] args) {
|
private boolean saveTemplate(Player player, String[] args) {
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
player.sendMessage(TextUtil.color("<#FF0000>Использование: /dbdsetup save <name>"));
|
player.sendMessage(TextUtil.color("<#FF0000>Использование: /dbdsetup save <name>"));
|
||||||
|
|
@ -132,28 +139,65 @@ public class SetupCommand implements TabExecutor {
|
||||||
|
|
||||||
private boolean setObject(Player player, String[] args) {
|
private boolean setObject(Player player, String[] args) {
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
player.sendMessage(TextUtil.color("<#FF0000>Использование: /dbdsetup set <generator|hook|pallet|chest|totem|gate|lobby>"));
|
player.sendMessage(TextUtil.color("<#FF0000>Использование: /dbdsetup set <тип>"));
|
||||||
|
player.sendMessage(TextUtil.color("<#FFD700>Типы: generator, hook, pallet, gate, killer-spawn, survivor-spawn, lobby"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Location loc = player.getLocation().getBlock().getLocation();
|
// For spawns and hooks use exact player location (with yaw/pitch)
|
||||||
|
// For block-based objects (generator) use block location
|
||||||
String type = args[1].toLowerCase();
|
String type = args[1].toLowerCase();
|
||||||
var locations = plugin.getConfigManager().getLocations();
|
var locations = plugin.getConfigManager().getLocations();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "generator" -> locations.addLocation("generators", loc);
|
case "generator" -> {
|
||||||
case "hook" -> locations.addLocation("hooks", loc);
|
Location loc = player.getLocation().getBlock().getLocation();
|
||||||
case "pallet" -> locations.addLocation("pallets", loc);
|
loc.add(0.5, 0, 0.5); // center of block
|
||||||
case "chest" -> locations.addLocation("chests", loc);
|
locations.addLocation("generators", loc);
|
||||||
case "totem" -> locations.addLocation("totems", loc);
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
case "gate" -> locations.addLocation("exitgates", loc);
|
player.sendMessage(TextUtil.color("<#00FF00>Генератор установлен на " + formatLoc(loc)));
|
||||||
case "lobby" -> locations.setLobby(loc);
|
}
|
||||||
|
case "hook" -> {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
locations.addLocation("hooks", loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>Крюк установлен на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
case "pallet" -> {
|
||||||
|
Location loc = player.getLocation().getBlock().getLocation();
|
||||||
|
locations.addLocation("pallets", loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>Паллет установлен на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
case "gate" -> {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
locations.addLocation("exitgates", loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>Ворота установлены на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
case "killer-spawn", "killer_spawn" -> {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
locations.setKillerSpawn(loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
player.sendMessage(TextUtil.color("<#FF4444>Спавн киллера установлен на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
case "survivor-spawn", "survivor_spawn" -> {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
locations.addLocation("survivor-spawns", loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
int count = locations.getSurvivorSpawns().size();
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>Спавн выжившего #" + count + " установлен на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
|
case "lobby" -> {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
locations.setLobby(loc);
|
||||||
|
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
||||||
|
player.sendMessage(TextUtil.color("<#00FF00>Лобби установлено на " + formatLoc(loc)));
|
||||||
|
}
|
||||||
default -> {
|
default -> {
|
||||||
player.sendMessage(TextUtil.color("<#FF0000>Неизвестный тип: " + type));
|
player.sendMessage(TextUtil.color("<#FF0000>Неизвестный тип: " + type));
|
||||||
return true;
|
player.sendMessage(TextUtil.color("<#FFD700>Типы: generator, hook, pallet, gate, killer-spawn, survivor-spawn, lobby"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugin.getConfigManager().saveConfig("locations.yml", locations.getConfig());
|
|
||||||
player.sendMessage(TextUtil.color("<#00FF00>Установлен: " + type + " на " + formatLoc(loc)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +254,7 @@ public class SetupCommand implements TabExecutor {
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
if (args.length == 2 && args[0].equalsIgnoreCase("set")) {
|
if (args.length == 2 && args[0].equalsIgnoreCase("set")) {
|
||||||
return Arrays.asList("generator", "hook", "pallet", "chest", "totem", "gate", "lobby")
|
return Arrays.asList("generator", "hook", "pallet", "gate", "killer-spawn", "survivor-spawn", "lobby")
|
||||||
.stream()
|
.stream()
|
||||||
.filter(s -> s.startsWith(args[1].toLowerCase()))
|
.filter(s -> s.startsWith(args[1].toLowerCase()))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,16 @@ public class LocationsConfig {
|
||||||
return spawns.isEmpty() ? null : spawns.get(0);
|
return spawns.isEmpty() ? null : spawns.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setKillerSpawn(Location loc) {
|
||||||
|
// killer-spawn is a single location stored as a list with one entry
|
||||||
|
List<String> list = new java.util.ArrayList<>();
|
||||||
|
list.add(String.format("%s,%.2f,%.2f,%.2f,%.1f,%.1f",
|
||||||
|
loc.getWorld().getName(),
|
||||||
|
loc.getX(), loc.getY(), loc.getZ(),
|
||||||
|
loc.getYaw(), loc.getPitch()));
|
||||||
|
config.set("killer-spawn", list);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Location> getSurvivorSpawns() {
|
public List<Location> getSurvivorSpawns() {
|
||||||
return loadLocationList("survivor-spawns");
|
return loadLocationList("survivor-spawns");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,11 @@ public class GameSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transitionToNextPhase() {
|
private void transitionToNextPhase() {
|
||||||
|
Phase next = determineNextPhase();
|
||||||
|
if (next != null) {
|
||||||
currentPhase.exit(this);
|
currentPhase.exit(this);
|
||||||
Phase nextPhase = determineNextPhase();
|
currentPhase = next;
|
||||||
if (nextPhase != null) {
|
currentPhase.enter(this);
|
||||||
switchPhase(nextPhase);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
package dev.loki.listener;
|
package dev.loki.listener;
|
||||||
|
|
||||||
|
import dev.loki.command.SetupCommand;
|
||||||
import dev.loki.core.GameManager;
|
import dev.loki.core.GameManager;
|
||||||
import dev.loki.objective.GeneratorManager;
|
import dev.loki.objective.GeneratorManager;
|
||||||
import dev.loki.player.BasePlayer;
|
import dev.loki.player.BasePlayer;
|
||||||
import dev.loki.player.PlayerState;
|
import dev.loki.player.PlayerState;
|
||||||
|
import dev.loki.util.TextUtil;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -21,6 +25,7 @@ public class PlayerInteractListener implements Listener {
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final GameManager gameManager;
|
private final GameManager gameManager;
|
||||||
private final GeneratorManager generatorManager;
|
private final GeneratorManager generatorManager;
|
||||||
|
private SetupCommand setupCommand;
|
||||||
|
|
||||||
private BiConsumer<Player, Action> onGeneratorInteract;
|
private BiConsumer<Player, Action> onGeneratorInteract;
|
||||||
private BiConsumer<Player, Boolean> onAttack;
|
private BiConsumer<Player, Boolean> onAttack;
|
||||||
|
|
@ -38,6 +43,10 @@ public class PlayerInteractListener implements Listener {
|
||||||
this.generatorManager = generatorManager;
|
this.generatorManager = generatorManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSetupCommand(SetupCommand setupCommand) {
|
||||||
|
this.setupCommand = setupCommand;
|
||||||
|
}
|
||||||
|
|
||||||
public void setOnGeneratorInteract(BiConsumer<Player, Action> h) { this.onGeneratorInteract = h; }
|
public void setOnGeneratorInteract(BiConsumer<Player, Action> h) { this.onGeneratorInteract = h; }
|
||||||
public void setOnAttack(BiConsumer<Player, Boolean> h) { this.onAttack = h; }
|
public void setOnAttack(BiConsumer<Player, Boolean> h) { this.onAttack = h; }
|
||||||
public void setOnPalletInteract(BiConsumer<Player, Boolean> h) { this.onPalletInteract = h; }
|
public void setOnPalletInteract(BiConsumer<Player, Boolean> h) { this.onPalletInteract = h; }
|
||||||
|
|
@ -49,6 +58,10 @@ public class PlayerInteractListener implements Listener {
|
||||||
public void onInteract(PlayerInteractEvent event) {
|
public void onInteract(PlayerInteractEvent event) {
|
||||||
if (event.getHand() != EquipmentSlot.HAND) return;
|
if (event.getHand() != EquipmentSlot.HAND) return;
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
// Handle wand regardless of game state
|
||||||
|
if (handleWand(event, player)) return;
|
||||||
|
|
||||||
if (!gameManager.isInGame(player.getUniqueId())) return;
|
if (!gameManager.isInGame(player.getUniqueId())) return;
|
||||||
var session = gameManager.getPlayerSession(player.getUniqueId());
|
var session = gameManager.getPlayerSession(player.getUniqueId());
|
||||||
if (session == null) return;
|
if (session == null) return;
|
||||||
|
|
@ -63,6 +76,41 @@ public class PlayerInteractListener implements Listener {
|
||||||
else if (action.isLeftClick()) handleLeftClick(event, player, bp);
|
else if (action.isLeftClick()) handleLeftClick(event, player, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the DBD wand (STICK with custom display name).
|
||||||
|
* LMB on block = pos1, RMB on block = pos2.
|
||||||
|
* Returns true if the event was consumed by the wand.
|
||||||
|
*/
|
||||||
|
private boolean handleWand(PlayerInteractEvent event, Player player) {
|
||||||
|
if (setupCommand == null) return false;
|
||||||
|
if (!player.hasPermission("mdbd.admin")) return false;
|
||||||
|
|
||||||
|
ItemStack item = event.getItem();
|
||||||
|
if (item == null || item.getType() != Material.STICK) return false;
|
||||||
|
if (!item.hasItemMeta()) return false;
|
||||||
|
|
||||||
|
var meta = item.getItemMeta();
|
||||||
|
// Check it's the DBD wand by display name component
|
||||||
|
if (meta.displayName() == null) return false;
|
||||||
|
String plain = net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText()
|
||||||
|
.serialize(meta.displayName());
|
||||||
|
if (!plain.contains("DBD Wand")) return false;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
Action action = event.getAction();
|
||||||
|
if (action == Action.LEFT_CLICK_BLOCK || action == Action.LEFT_CLICK_AIR) {
|
||||||
|
setupCommand.setWandPos(player, 1, event.getClickedBlock() != null
|
||||||
|
? event.getClickedBlock().getLocation()
|
||||||
|
: player.getLocation().getBlock().getLocation());
|
||||||
|
} else if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) {
|
||||||
|
setupCommand.setWandPos(player, 2, event.getClickedBlock() != null
|
||||||
|
? event.getClickedBlock().getLocation()
|
||||||
|
: player.getLocation().getBlock().getLocation());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isIncapacitated(BasePlayer bp) {
|
private boolean isIncapacitated(BasePlayer bp) {
|
||||||
return bp.getState() == PlayerState.DOWNED || bp.getState() == PlayerState.HOOKED;
|
return bp.getState() == PlayerState.DOWNED || bp.getState() == PlayerState.HOOKED;
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +125,7 @@ public class PlayerInteractListener implements Listener {
|
||||||
|
|
||||||
private void handleRightClick(PlayerInteractEvent event, Player player, BasePlayer bp) {
|
private void handleRightClick(PlayerInteractEvent event, Player player, BasePlayer bp) {
|
||||||
if (event.getClickedBlock() == null) {
|
if (event.getClickedBlock() == null) {
|
||||||
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager.isInAnyZone(player)) {
|
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager != null && generatorManager.isInAnyZone(player)) {
|
||||||
onGeneratorInteract.accept(player, event.getAction());
|
onGeneratorInteract.accept(player, event.getAction());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +133,7 @@ public class PlayerInteractListener implements Listener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager.isInAnyZone(player)) {
|
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager != null && generatorManager.isInAnyZone(player)) {
|
||||||
onGeneratorInteract.accept(player, event.getAction());
|
onGeneratorInteract.accept(player, event.getAction());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,9 @@ public final class mdbd extends JavaPlugin {
|
||||||
new GeneratorSelectListener(dbdAdminCommand, generatorData), this);
|
new GeneratorSelectListener(dbdAdminCommand, generatorData), this);
|
||||||
getServer().getPluginManager().registerEvents(
|
getServer().getPluginManager().registerEvents(
|
||||||
new PlayerQuitListener(this, gameManager), this);
|
new PlayerQuitListener(this, gameManager), this);
|
||||||
getServer().getPluginManager().registerEvents(
|
var interactListener = new PlayerInteractListener(this, gameManager, null);
|
||||||
new PlayerInteractListener(this, gameManager, null), this);
|
interactListener.setSetupCommand(setupCommand);
|
||||||
|
getServer().getPluginManager().registerEvents(interactListener, this);
|
||||||
|
|
||||||
getLogger().info("Mdbd Plugin enabled successfully!");
|
getLogger().info("Mdbd Plugin enabled successfully!");
|
||||||
getLogger().info("Loaded " + templateManager.getAllTemplates().size() + " templates");
|
getLogger().info("Loaded " + templateManager.getAllTemplates().size() + " templates");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue