package dev.loki.gate; import dev.loki.config.GameConfig; import dev.loki.player.Survivor; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class GateOpening { private static final double INTERACTION_RADIUS = 3.0; private final GateManager gateManager; private final int openTicks; private final Map openingPlayers; public GateOpening(GateManager gateManager, GameConfig config) { this.gateManager = gateManager; this.openTicks = config.getConfig().getInt("endgame.gate-open-seconds", 20) * 20; this.openingPlayers = new HashMap<>(); } public boolean tryStartOpening(Survivor survivor, org.bukkit.plugin.Plugin plugin) { if (isOpening(survivor)) return false; Player player = survivor.getPlayer(); if (player == null) return false; ExitGate gate = gateManager.getGateAt(player.getLocation(), INTERACTION_RADIUS); if (gate == null) { player.sendMessage("§cНет ворот поблизости!"); return false; } if (!gate.isPowered()) { player.sendMessage("§cВорота обесточены!"); return false; } if (!gate.isClosed() && !gate.isOpening()) { player.sendMessage("§aВорота уже открыты!"); return false; } startOpening(survivor, gate, plugin); return true; } public void stopOpening(Survivor survivor) { OpeningProgress progress = openingPlayers.remove(survivor.getUuid()); if (progress != null) { Player player = survivor.getPlayer(); if (player != null) { player.sendMessage("§7Открытие прервано!"); } } } public boolean isOpening(Survivor survivor) { return openingPlayers.containsKey(survivor.getUuid()); } private void startOpening(Survivor survivor, ExitGate gate, org.bukkit.plugin.Plugin plugin) { Player player = survivor.getPlayer(); if (player == null) return; openingPlayers.put(survivor.getUuid(), new OpeningProgress(gate, 0)); player.sendMessage("§aОткрываем ворота... (зажмите ПКМ)"); new OpeningTask(survivor, gate, plugin).runTaskTimer(plugin, 0L, 1L); } private void completeOpening(Survivor survivor, ExitGate gate) { Player player = survivor.getPlayer(); if (player != null) { player.sendMessage("§aВорота открыты!"); player.getWorld().playSound(gate.getLocation(), Sound.BLOCK_IRON_DOOR_OPEN, 1.0f, 1.0f); } gate.updateProgress(1.0); openingPlayers.remove(survivor.getUuid()); } private void playOpeningEffect(Player player, ExitGate gate, int progress) { if (progress % 20 == 0) { player.getWorld().playSound(gate.getLocation(), Sound.BLOCK_METAL_HIT, 0.3f, 1.0f); } } private class OpeningProgress { final ExitGate gate; int ticks; OpeningProgress(ExitGate gate, int ticks) { this.gate = gate; this.ticks = ticks; } } private class OpeningTask extends BukkitRunnable { private final Survivor survivor; private final ExitGate gate; OpeningTask(Survivor survivor, ExitGate gate, org.bukkit.plugin.Plugin plugin) { this.survivor = survivor; this.gate = gate; } @Override public void run() { Player player = survivor.getPlayer(); if (player == null || !player.isOnline()) { stopOpening(survivor); cancel(); return; } OpeningProgress progress = openingPlayers.get(survivor.getUuid()); if (progress == null || progress.gate != gate) { cancel(); return; } if (!gate.isInRange(player.getLocation(), INTERACTION_RADIUS)) { stopOpening(survivor); cancel(); return; } progress.ticks++; playOpeningEffect(player, gate, progress.ticks); double progressPct = progress.ticks / (double) openTicks; gate.updateProgress(progressPct); if (progress.ticks >= openTicks) { completeOpening(survivor, gate); cancel(); } } } }