This commit is contained in:
loki5512344 2026-06-10 23:00:12 +02:00
parent 89dc9eb00d
commit 957ab4a5a2
149 changed files with 5379 additions and 3263 deletions

View file

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