fix
This commit is contained in:
parent
89dc9eb00d
commit
957ab4a5a2
149 changed files with 5379 additions and 3263 deletions
136
src/main/java/dev/loki/phase/GameplayWinConditions.java
Normal file
136
src/main/java/dev/loki/phase/GameplayWinConditions.java
Normal 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()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue