Stage 13: Perks and Totems

This commit is contained in:
loki5512344 2026-05-31 20:49:37 +02:00
parent d1f854fc79
commit 37e67ce97d
23 changed files with 2070 additions and 25 deletions

View file

@ -0,0 +1,147 @@
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();
}
}
}
}