mdbd/src/main/java/dev/loki/phase/EndgamePhase.java

252 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dev.loki.phase;
import dev.loki.core.GameSession;
import dev.loki.gate.GateManager;
import dev.loki.gate.GateOpening;
import dev.loki.hatch.Hatch;
import dev.loki.hatch.HatchCondition;
import dev.loki.hatch.HatchEscape;
import dev.loki.player.BasePlayer;
import dev.loki.player.Killer;
import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.List;
public class EndgamePhase implements Phase {
private final int collapseSeconds;
private final int openTicks;
private int remainingTicks;
private boolean complete;
private boolean gatesActivated;
private GateManager gateManager;
private GateOpening gateOpening;
private Hatch hatch;
private HatchCondition hatchCondition;
private HatchEscape hatchEscape;
public EndgamePhase() {
this.collapseSeconds = 120;
this.openTicks = 20 * 20;
}
public EndgamePhase(int collapseSeconds, GateManager gateManager,
Hatch hatch, HatchCondition hatchCondition) {
this.collapseSeconds = collapseSeconds;
this.openTicks = 20 * 20;
this.gateManager = gateManager;
this.hatch = hatch;
this.hatchCondition = hatchCondition;
this.hatchEscape = new HatchEscape(hatch);
}
@Override
public void enter(GameSession session) {
this.remainingTicks = collapseSeconds * 20;
this.complete = false;
this.gatesActivated = false;
activateEndgame(session);
announceEndgameStart(session);
}
private void activateEndgame(GameSession session) {
if (gateManager != null && !gatesActivated) {
gateManager.activateEndgame();
gatesActivated = true;
}
checkHatchConditions(session);
session.getPlugin().getLogger().info("Endgame started!");
}
private void checkHatchConditions(GameSession session) {
if (hatch == null || hatchCondition == null) return;
int repairedGens = countRepairedGenerators(session);
hatchCondition.checkAndReveal(hatch, session.getPlayers().values(), repairedGens);
if (isLastSurvivor(session)) {
hatchCondition.checkAndOpen(hatch, session.getPlayers().values(), repairedGens);
if (hatch.isOpen()) {
hatchEscape.notifyNearbyPlayers();
}
}
}
private boolean isLastSurvivor(GameSession session) {
if (hatchCondition == null) return false;
return hatchCondition.isLastSurvivor(session.getPlayers().values());
}
private int countRepairedGenerators(GameSession session) {
return 5;
}
private void announceEndgameStart(GameSession session) {
for (BasePlayer player : session.getPlayers().values()) {
Player bukkitPlayer = player.getPlayer();
if (bukkitPlayer != null) {
bukkitPlayer.sendTitle("§4§lЭНДГЕЙМ!",
"§cКоллапс через 2 минуты!", 10, 70, 20);
bukkitPlayer.playSound(bukkitPlayer.getLocation(),
Sound.ENTITY_WITHER_SPAWN, 1.0f, 0.8f);
}
}
}
@Override
public void tick(GameSession session) {
remainingTicks--;
int secondsLeft = remainingTicks / 20;
updateGates(session);
updateHatch(session);
checkWinConditions(session);
sendCountdown(session, secondsLeft);
if (remainingTicks <= 0) {
triggerCollapse(session);
complete = true;
}
}
private void updateGates(GameSession session) {
if (gateManager == null) return;
gateManager.updateAllGates(1.0 / openTicks);
}
private void updateHatch(GameSession session) {
if (hatch == null || !hatch.isOpen()) return;
for (BasePlayer player : session.getPlayers().values()) {
if (player.isKiller()) continue;
if (player.getState() != PlayerState.HEALTHY &&
player.getState() != PlayerState.INJURED) continue;
if (hatchEscape.canEscape((Survivor) player)) {
hatchEscape.tryEscape((Survivor) player);
}
}
}
private void checkWinConditions(GameSession session) {
boolean allEscapedOrDead = true;
int survivorsAlive = 0;
for (BasePlayer player : session.getPlayers().values()) {
if (player.isKiller()) continue;
PlayerState state = player.getState();
if (state != PlayerState.DEAD && state != PlayerState.ESCAPED) {
allEscapedOrDead = false;
survivorsAlive++;
}
}
if (allEscapedOrDead || survivorsAlive == 0) {
complete = true;
}
}
private void sendCountdown(GameSession session, int secondsLeft) {
if (secondsLeft > 0 && secondsLeft <= 10) {
for (BasePlayer player : session.getPlayers().values()) {
Player bukkitPlayer = player.getPlayer();
if (bukkitPlayer != null) {
bukkitPlayer.sendTitle("§4" + secondsLeft, "", 0, 25, 0);
bukkitPlayer.playSound(bukkitPlayer.getLocation(),
Sound.BLOCK_NOTE_BLOCK_HAT, 0.5f, 1.0f);
}
}
}
}
private void triggerCollapse(GameSession session) {
for (BasePlayer player : session.getPlayers().values()) {
if (player.getState() == PlayerState.DEAD ||
player.getState() == PlayerState.ESCAPED) continue;
Player bukkitPlayer = player.getPlayer();
if (bukkitPlayer == null) continue;
if (!player.isKiller()) {
bukkitPlayer.setHealth(0);
player.setState(PlayerState.DEAD);
} else {
((Killer) player).setCarrying(false);
}
bukkitPlayer.sendTitle("§4§lКОЛЛАПС!",
"§cКарта разрушена!", 10, 70, 20);
}
}
@Override
public void exit(GameSession session) {
announceEndgameEnd(session);
if (hatch != null) {
hatch.reset();
}
new BukkitRunnable() {
@Override
public void run() {
session.stop();
}
}.runTaskLater(session.getPlugin(), 100L);
}
private void announceEndgameEnd(GameSession session) {
List<String> results = new ArrayList<>();
results.add("§6§l=== РЕЗУЛЬТАТЫ ===");
int escaped = 0;
int died = 0;
for (BasePlayer player : session.getPlayers().values()) {
if (player.isKiller()) continue;
PlayerState state = player.getState();
Player bukkitPlayer = player.getPlayer();
String name = bukkitPlayer != null ? bukkitPlayer.getName() : "Unknown";
if (state == PlayerState.ESCAPED) {
results.add("§a✔ " + name + " — Сбежал");
escaped++;
} else {
results.add("§c✘ " + name + " — Погиб");
died++;
}
}
results.add("§7Выживших: §a" + escaped + " §7/ Погибших: §c" + died);
String resultMessage = String.join("\n", results);
for (BasePlayer player : session.getPlayers().values()) {
Player bukkitPlayer = player.getPlayer();
if (bukkitPlayer != null) {
bukkitPlayer.sendMessage(resultMessage);
}
}
}
@Override
public boolean isComplete() {
return complete;
}
public int getRemainingSeconds() {
return remainingTicks / 20;
}
}