252 lines
7.7 KiB
Java
252 lines
7.7 KiB
Java
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;
|
||
}
|
||
}
|