mdbd/src/main/java/dev/loki/phase/GameplayWinConditions.java
2026-06-10 23:00:12 +02:00

136 lines
No EOL
4.9 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.config.GameConfig;
import dev.loki.core.GameSession;
import dev.loki.hook.*;
import dev.loki.player.BasePlayer;
import dev.loki.player.Killer;
import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import dev.loki.ui.TitleUI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
/**
* Handles win condition checking during gameplay phase.
*/
public class GameplayWinConditions {
private boolean shouldEnd;
private String winReason; // "killer_win", "survivors_win", null
public boolean isShouldEnd() {
return shouldEnd;
}
public String getWinReason() {
return winReason;
}
/**
* Check all win conditions each second (20 ticks).
*/
public void checkWinConditions(GameSession session) {
int aliveSurvivors = countAliveSurvivors(session);
Killer killer = getKiller(session);
// Killer disconnect: if killer player is null/offline, survivors win
if (killer == null || killer.getPlayer() == null || !killer.getPlayer().isOnline()) {
winReason = "survivors_win";
Bukkit.broadcast(Component.text("[DBD] Маньяк покинул игру! Выжившие победили!", NamedTextColor.GREEN));
announceSurvivorsWin(session);
shouldEnd = true;
return;
}
// Killer wins: all survivors are downed/hooked/carried/dead
if (allSurvivorsIncapacitated(session)) {
winReason = "killer_win";
Bukkit.broadcast(Component.text("[DBD] Все выжившие обезврежены!", NamedTextColor.DARK_RED));
announceKillerWin(session);
shouldEnd = true;
return;
}
// Survivors win: all generators done and at least one escaped
if (hasEscapedSurvivor(session)) {
winReason = "survivors_win";
announceSurvivorsWin(session);
shouldEnd = true;
}
}
/** True if NO survivor can act (all are DOWNED, HOOKED, CARRIED, or DEAD). */
private boolean allSurvivorsIncapacitated(GameSession session) {
boolean hasSurvivors = false;
for (BasePlayer bp : session.getPlayers().values()) {
if (bp.isKiller()) continue;
hasSurvivors = true;
PlayerState st = bp.getState();
if (st != PlayerState.DOWNED && st != PlayerState.HOOKED
&& st != PlayerState.CARRIED && st != PlayerState.DEAD) {
return false; // at least one survivor can still act
}
}
return hasSurvivors; // true if there are survivors and all are incapacitated
}
private int countAliveSurvivors(GameSession session) {
int count = 0;
for (BasePlayer bp : session.getPlayers().values()) {
if (bp.isKiller()) continue;
Survivor s = (Survivor) bp;
if (!s.isDeadOrEscaped()) count++;
}
return count;
}
private boolean hasEscapedSurvivor(GameSession session) {
for (BasePlayer bp : session.getPlayers().values()) {
if (bp.isKiller()) continue;
if (bp.getState() == PlayerState.ESCAPED) return true;
}
return false;
}
private Killer getKiller(GameSession session) {
for (BasePlayer bp : session.getPlayers().values()) {
if (bp.isKiller()) return (Killer) bp;
}
return null;
}
public void announceKillerWin(GameSession session) {
winReason = "killer_win";
Bukkit.broadcast(Component.text("[DBD] Маньяк победил! Все выжившие мертвы!", NamedTextColor.DARK_RED));
for (BasePlayer bp : session.getPlayers().values()) {
Player p = bp.getPlayer();
if (p == null || !p.isOnline()) continue;
if (!bp.isKiller() && bp.getState() == PlayerState.DEAD) {
p.setGameMode(GameMode.SPECTATOR);
} else {
p.setGameMode(GameMode.SURVIVAL);
}
p.playSound(p.getLocation(), Sound.ENTITY_WITHER_DEATH, 1.0f, 1.0f);
}
// Teleport handled by EndgamePhase.exit()
}
public void announceSurvivorsWin(GameSession session) {
winReason = "survivors_win";
Bukkit.broadcast(Component.text("[DBD] Выжившие победили!", NamedTextColor.GREEN));
for (BasePlayer bp : session.getPlayers().values()) {
Player p = bp.getPlayer();
if (p == null || !p.isOnline()) continue;
p.setGameMode(GameMode.SURVIVAL);
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.2f);
}
// Teleport handled by EndgamePhase.exit()
}
// Removed scheduleTeleportToLobby — teleport now happens only in EndgamePhase.exit()
}