147 lines
4.6 KiB
Java
147 lines
4.6 KiB
Java
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<UUID, OpeningProgress> 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();
|
||
}
|
||
}
|
||
}
|
||
}
|