From d0ed8a5fe7eb65dd3b78aa7963c19d9b9a4fe085 Mon Sep 17 00:00:00 2001 From: loki5512344 Date: Mon, 1 Jun 2026 22:21:40 +0200 Subject: [PATCH] Connect game phases, implement gameplay, add lobby commands, remove perks - Fix GameSession.determineNextPhase() to cycle through all 4 phases - Implement GameplayPhase with generator tracking and win/lose conditions - MapBuilder now uses the game world instead of the first world - Add /dbd lobby (teleport to lobby) and /dbd setlobby (set lobby spawn) - Remove all perk classes (IPerk, PerkRegistry, 7 perk implementations) - Fix HexTotem to not reference removed HexRuinPerk --- .../java/dev/loki/command/DBDCommand.java | 33 +++++- src/main/java/dev/loki/core/GameSession.java | 31 +++++- src/main/java/dev/loki/map/MapBuilder.java | 6 +- src/main/java/dev/loki/perk/BasePerk.java | 79 ------------- src/main/java/dev/loki/perk/IPerk.java | 30 ----- src/main/java/dev/loki/perk/PerkRegistry.java | 60 ---------- src/main/java/dev/loki/perk/PerkTrigger.java | 23 ---- src/main/java/dev/loki/perk/PerkType.java | 16 --- .../dev/loki/perk/killer/BBQChiliPerk.java | 105 ------------------ .../perk/killer/CorruptInterventionPerk.java | 97 ---------------- .../dev/loki/perk/killer/HexRuinPerk.java | 94 ---------------- .../loki/perk/survivor/BorrowedTimePerk.java | 76 ------------- .../dev/loki/perk/survivor/DeadHardPerk.java | 76 ------------- .../dev/loki/perk/survivor/SelfCarePerk.java | 53 --------- .../loki/perk/survivor/SprintBurstPerk.java | 80 ------------- .../java/dev/loki/phase/GameplayPhase.java | 76 +++++++++++-- src/main/java/dev/loki/totem/HexTotem.java | 3 +- src/main/resources/plugin.yml | 2 +- 18 files changed, 132 insertions(+), 808 deletions(-) delete mode 100644 src/main/java/dev/loki/perk/BasePerk.java delete mode 100644 src/main/java/dev/loki/perk/IPerk.java delete mode 100644 src/main/java/dev/loki/perk/PerkRegistry.java delete mode 100644 src/main/java/dev/loki/perk/PerkTrigger.java delete mode 100644 src/main/java/dev/loki/perk/PerkType.java delete mode 100644 src/main/java/dev/loki/perk/killer/BBQChiliPerk.java delete mode 100644 src/main/java/dev/loki/perk/killer/CorruptInterventionPerk.java delete mode 100644 src/main/java/dev/loki/perk/killer/HexRuinPerk.java delete mode 100644 src/main/java/dev/loki/perk/survivor/BorrowedTimePerk.java delete mode 100644 src/main/java/dev/loki/perk/survivor/DeadHardPerk.java delete mode 100644 src/main/java/dev/loki/perk/survivor/SelfCarePerk.java delete mode 100644 src/main/java/dev/loki/perk/survivor/SprintBurstPerk.java diff --git a/src/main/java/dev/loki/command/DBDCommand.java b/src/main/java/dev/loki/command/DBDCommand.java index f7906e2..69640ac 100644 --- a/src/main/java/dev/loki/command/DBDCommand.java +++ b/src/main/java/dev/loki/command/DBDCommand.java @@ -41,6 +41,8 @@ public class DBDCommand implements TabExecutor { case "create" -> handleCreate(sender); case "stop" -> handleStop(sender); case "reload" -> handleReload(sender); + case "lobby" -> handleLobby(sender); + case "setlobby" -> handleSetLobby(sender); default -> { sendUsage(sender); yield true; @@ -116,6 +118,32 @@ public class DBDCommand implements TabExecutor { return true; } + private boolean handleLobby(CommandSender sender) { + if (!(sender instanceof Player player)) { + sender.sendMessage(Component.text("Только игроки!", NamedTextColor.RED)); + return true; + } + plugin.getLobbyManager().teleportToLobby(player); + player.sendMessage(Component.text("[DBD] Вы телепортированы в лобби!", NamedTextColor.GREEN)); + return true; + } + + private boolean handleSetLobby(CommandSender sender) { + if (!sender.hasPermission("mdbd.admin")) { + sender.sendMessage(Component.text("Нет прав!", NamedTextColor.RED)); + return true; + } + if (!(sender instanceof Player player)) { + sender.sendMessage(Component.text("Только игроки!", NamedTextColor.RED)); + return true; + } + plugin.getConfigManager().getLocations().setLobby(player.getLocation()); + plugin.getConfigManager().saveConfig("locations.yml", + plugin.getConfigManager().getLocations().getConfig()); + player.sendMessage(Component.text("[DBD] Лобби установлено!", NamedTextColor.GREEN)); + return true; + } + private boolean handleStop(CommandSender sender) { if (!sender.hasPermission("mdbd.admin")) { sender.sendMessage(Component.text("Нет прав!", NamedTextColor.RED)); @@ -130,11 +158,14 @@ public class DBDCommand implements TabExecutor { sender.sendMessage(Component.text("=== DBD Commands ===", NamedTextColor.GOLD)); sender.sendMessage(Component.text("/dbd join - присоединиться", NamedTextColor.GRAY)); sender.sendMessage(Component.text("/dbd leave - покинуть", NamedTextColor.GRAY)); + sender.sendMessage(Component.text("/dbd lobby - телепорт в лобби", NamedTextColor.GRAY)); if (sender.hasPermission("mdbd.admin")) { sender.sendMessage(Component.text("/dbd create - создать игру", NamedTextColor.GRAY)); sender.sendMessage(Component.text("/dbd forcestart - форс старт", NamedTextColor.GRAY)); sender.sendMessage(Component.text("/dbd stop - остановить", NamedTextColor.GRAY)); sender.sendMessage(Component.text("/dbd reload - перезагрузить конфиги", NamedTextColor.GRAY)); + sender.sendMessage(Component.text("/dbd lobby - телепорт в лобби", NamedTextColor.GRAY)); + sender.sendMessage(Component.text("/dbd setlobby - установить точку лобби", NamedTextColor.GRAY)); } } @@ -144,7 +175,7 @@ public class DBDCommand implements TabExecutor { if (args.length == 1) { List completions = new ArrayList<>(Arrays.asList("join", "leave")); if (sender.hasPermission("mdbd.admin")) { - completions.addAll(Arrays.asList("create", "forcestart", "stop", "reload")); + completions.addAll(Arrays.asList("create", "forcestart", "stop", "reload", "setlobby")); } return completions.stream() .filter(s -> s.startsWith(args[0].toLowerCase())) diff --git a/src/main/java/dev/loki/core/GameSession.java b/src/main/java/dev/loki/core/GameSession.java index 4b4f4e9..e5e1580 100644 --- a/src/main/java/dev/loki/core/GameSession.java +++ b/src/main/java/dev/loki/core/GameSession.java @@ -2,9 +2,14 @@ package dev.loki.core; import dev.loki.config.GameConfig; import dev.loki.mdbd; +import dev.loki.objective.GeneratorManager; +import dev.loki.phase.EndgamePhase; +import dev.loki.phase.GameplayPhase; import dev.loki.phase.LobbyPhase; import dev.loki.phase.Phase; +import dev.loki.phase.RoleAssignPhase; import dev.loki.player.BasePlayer; +import dev.loki.role.RoleAssigner; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitTask; @@ -19,12 +24,17 @@ public class GameSession { private Phase currentPhase; private BukkitTask tickTask; private int ticksElapsed; + private RoleAssigner roleAssigner; + private GeneratorManager generatorManager; public GameSession(mdbd plugin) { this.plugin = plugin; this.eventBus = new GameEventBus(); this.players = new HashMap<>(); this.ticksElapsed = 0; + this.roleAssigner = new RoleAssigner(plugin.getConfigManager().getLocations()); + this.generatorManager = new GeneratorManager( + plugin.getGeneratorData(), plugin.getConfigManager().getGame().getGeneratorRequired()); } public void start() { @@ -61,12 +71,19 @@ public class GameSession { Phase nextPhase = determineNextPhase(); if (nextPhase != null) { switchPhase(nextPhase); - } else { - stop(); } } private Phase determineNextPhase() { + if (currentPhase instanceof LobbyPhase) { + return new RoleAssignPhase(roleAssigner); + } + if (currentPhase instanceof RoleAssignPhase) { + return new GameplayPhase(generatorManager); + } + if (currentPhase instanceof GameplayPhase) { + return new EndgamePhase(); + } return null; } @@ -115,8 +132,16 @@ public class GameSession { return plugin.getConfigManager().getGame(); } + public RoleAssigner getRoleAssigner() { + return roleAssigner; + } + + public GeneratorManager getGeneratorManager() { + return generatorManager; + } + public void forceStart() { - if (currentPhase instanceof dev.loki.phase.LobbyPhase lobby) { + if (currentPhase instanceof LobbyPhase lobby) { lobby.forceStart(); } } diff --git a/src/main/java/dev/loki/map/MapBuilder.java b/src/main/java/dev/loki/map/MapBuilder.java index 360c7ae..167443e 100644 --- a/src/main/java/dev/loki/map/MapBuilder.java +++ b/src/main/java/dev/loki/map/MapBuilder.java @@ -20,8 +20,10 @@ public class MapBuilder { } public void buildMap(LocationsConfig config) { - World world = Bukkit.getWorlds().get(0); - if (world == null) return; + World world = plugin.getLobbyManager().getGameWorld(); + if (world == null) { + world = Bukkit.getWorlds().get(0); + } // Place generators List generators = config.getGenerators(); diff --git a/src/main/java/dev/loki/perk/BasePerk.java b/src/main/java/dev/loki/perk/BasePerk.java deleted file mode 100644 index 2dc56f7..0000000 --- a/src/main/java/dev/loki/perk/BasePerk.java +++ /dev/null @@ -1,79 +0,0 @@ -package dev.loki.perk; - -import dev.loki.player.BasePlayer; -import dev.loki.mdbd; - -public abstract class BasePerk implements IPerk { - protected final mdbd plugin; - protected final String id; - protected final String name; - protected final String description; - protected final PerkType type; - protected final boolean passive; - protected final int cooldownSeconds; - protected long cooldownEndTime = 0; - - protected BasePerk(mdbd plugin, String id, String name, String description, - PerkType type, boolean passive, int cooldownSeconds) { - this.plugin = plugin; - this.id = id; - this.name = name; - this.description = description; - this.type = type; - this.passive = passive; - this.cooldownSeconds = cooldownSeconds; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public PerkType getType() { - return type; - } - - @Override - public boolean isPassive() { - return passive; - } - - @Override - public int getCooldownSeconds() { - return cooldownSeconds; - } - - @Override - public boolean isOnCooldown() { - return System.currentTimeMillis() < cooldownEndTime; - } - - @Override - public void startCooldown() { - if (cooldownSeconds > 0) { - cooldownEndTime = System.currentTimeMillis() + (cooldownSeconds * 1000L); - } - } - - @Override - public void resetCooldown() { - cooldownEndTime = 0; - } - - protected void sendPerkMessage(BasePlayer player, String message) { - if (player.getPlayer() != null) { - player.getPlayer().sendMessage("§6[" + name + "] §7" + message); - } - } -} diff --git a/src/main/java/dev/loki/perk/IPerk.java b/src/main/java/dev/loki/perk/IPerk.java deleted file mode 100644 index 8e2ba04..0000000 --- a/src/main/java/dev/loki/perk/IPerk.java +++ /dev/null @@ -1,30 +0,0 @@ -package dev.loki.perk; - -import dev.loki.player.BasePlayer; - -public interface IPerk { - - String getId(); - - String getName(); - - String getDescription(); - - PerkType getType(); - - void onEquip(BasePlayer player); - - void onTrigger(BasePlayer player, PerkTrigger trigger, Object context); - - void onRemove(BasePlayer player); - - boolean isPassive(); - - int getCooldownSeconds(); - - boolean isOnCooldown(); - - void startCooldown(); - - void resetCooldown(); -} diff --git a/src/main/java/dev/loki/perk/PerkRegistry.java b/src/main/java/dev/loki/perk/PerkRegistry.java deleted file mode 100644 index 18aebf6..0000000 --- a/src/main/java/dev/loki/perk/PerkRegistry.java +++ /dev/null @@ -1,60 +0,0 @@ -package dev.loki.perk; - -import dev.loki.mdbd; -import dev.loki.perk.killer.BBQChiliPerk; -import dev.loki.perk.killer.CorruptInterventionPerk; -import dev.loki.perk.killer.HexRuinPerk; -import dev.loki.perk.survivor.BorrowedTimePerk; -import dev.loki.perk.survivor.DeadHardPerk; -import dev.loki.perk.survivor.SelfCarePerk; -import dev.loki.perk.survivor.SprintBurstPerk; - -import java.util.HashMap; -import java.util.Map; - -public class PerkRegistry { - private final Map perks = new HashMap<>(); - private final mdbd plugin; - - public PerkRegistry(mdbd plugin) { - this.plugin = plugin; - registerDefaultPerks(); - } - - private void registerDefaultPerks() { - register(new SelfCarePerk(plugin)); - register(new DeadHardPerk(plugin)); - register(new SprintBurstPerk(plugin)); - register(new BorrowedTimePerk(plugin)); - register(new HexRuinPerk(plugin)); - register(new CorruptInterventionPerk(plugin)); - register(new BBQChiliPerk(plugin)); - } - - public void register(IPerk perk) { - perks.put(perk.getId().toLowerCase(), perk); - plugin.getLogger().info("Registered perk: " + perk.getName()); - } - - public IPerk getPerk(String id) { - return perks.get(id.toLowerCase()); - } - - public Map getAllPerks() { - return new HashMap<>(perks); - } - - public Map getPerksByType(PerkType type) { - Map result = new HashMap<>(); - for (Map.Entry entry : perks.entrySet()) { - if (entry.getValue().getType() == type) { - result.put(entry.getKey(), entry.getValue()); - } - } - return result; - } - - public boolean hasPerk(String id) { - return perks.containsKey(id.toLowerCase()); - } -} diff --git a/src/main/java/dev/loki/perk/PerkTrigger.java b/src/main/java/dev/loki/perk/PerkTrigger.java deleted file mode 100644 index 7a01730..0000000 --- a/src/main/java/dev/loki/perk/PerkTrigger.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.loki.perk; - -public enum PerkTrigger { - ON_HIT, - ON_INJURED, - ON_DOWNED, - ON_HOOKED, - ON_UNHOOKED, - ON_HEAL_START, - ON_HEAL_COMPLETE, - ON_GENERATOR_START, - ON_GENERATOR_COMPLETE, - ON_SPRINT_START, - ON_CHASE_START, - ON_CHASE_END, - ON_TOTEM_BLESSED, - ON_TOTEM_CLEANSED, - ON_KILLER_HOOK, - ON_KILLER_HIT, - ON_KILLER_DASH, - ON_EXHAUSTION_START, - ON_EXHAUSTION_END -} diff --git a/src/main/java/dev/loki/perk/PerkType.java b/src/main/java/dev/loki/perk/PerkType.java deleted file mode 100644 index 50572eb..0000000 --- a/src/main/java/dev/loki/perk/PerkType.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.loki.perk; - -public enum PerkType { - SURVIVOR("Выживший"), - KILLER("Убийца"); - - private final String displayName; - - PerkType(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } -} diff --git a/src/main/java/dev/loki/perk/killer/BBQChiliPerk.java b/src/main/java/dev/loki/perk/killer/BBQChiliPerk.java deleted file mode 100644 index f258132..0000000 --- a/src/main/java/dev/loki/perk/killer/BBQChiliPerk.java +++ /dev/null @@ -1,105 +0,0 @@ -package dev.loki.perk.killer; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import dev.loki.player.Survivor; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class BBQChiliPerk extends BasePerk { - private static final int REVEAL_DURATION_SECONDS = 4; - private static final int AURA_RANGE = 100; - private static final int BONUS_STACKS = 4; - private final Map hookedPlayers = new HashMap<>(); - private int currentStacks = 0; - - public BBQChiliPerk(mdbd plugin) { - super(plugin, "bbq_chili", "Барбекю и Чили", - "После подвешивания видите ауру всех выживших на 4 секунды", - PerkType.KILLER, true, 0); - } - - @Override - public void onEquip(BasePlayer player) { - currentStacks = 0; - sendPerkMessage(player, "Активировано: ауры видны после подвешивания"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_KILLER_HOOK) { - if (context instanceof Survivor survivor) { - revealSurvivorAuras(player, survivor); - } - } - } - - private void revealSurvivorAuras(BasePlayer killer, Survivor hookedSurvivor) { - Player killerPlayer = killer.getPlayer(); - if (killerPlayer == null) return; - - currentStacks = Math.min(currentStacks + 1, BONUS_STACKS); - hookedPlayers.put(hookedSurvivor.getUuid(), currentStacks); - - Collection allPlayers = Bukkit.getOnlinePlayers(); - for (Player player : allPlayers) { - if (player.equals(killerPlayer)) continue; - if (player.getLocation().distance(killerPlayer.getLocation()) > AURA_RANGE) { - continue; - } - - revealAura(killerPlayer, player); - } - - sendPerkMessage(killer, "§cАуры выживших видны! (x" + currentStacks + " стаков)"); - - new BukkitRunnable() { - @Override - public void run() { - sendPerkMessage(killer, "§7Эффект ауры закончился"); - } - }.runTaskLater(plugin, REVEAL_DURATION_SECONDS * 20L); - } - - private void revealAura(Player killer, Player survivor) { - Location survivorLoc = survivor.getLocation(); - for (int i = 0; i < 3; i++) { - Location particleLoc = survivorLoc.clone().add(0, i * 0.5, 0); - killer.spawnParticle(Particle.GLOW, particleLoc, 5, 0.3, 0.5, 0.3, 0.01); - } - } - - @Override - public void onRemove(BasePlayer player) { - currentStacks = 0; - hookedPlayers.clear(); - sendPerkMessage(player, "Перк деактивирован"); - } - - public int getStacks() { - return currentStacks; - } - - public static int getRevealDuration() { - return REVEAL_DURATION_SECONDS; - } - - public static int getAuraRange() { - return AURA_RANGE; - } - - public static int getMaxStacks() { - return BONUS_STACKS; - } -} diff --git a/src/main/java/dev/loki/perk/killer/CorruptInterventionPerk.java b/src/main/java/dev/loki/perk/killer/CorruptInterventionPerk.java deleted file mode 100644 index db7950f..0000000 --- a/src/main/java/dev/loki/perk/killer/CorruptInterventionPerk.java +++ /dev/null @@ -1,97 +0,0 @@ -package dev.loki.perk.killer; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -public class CorruptInterventionPerk extends BasePerk { - private static final int BLOCK_DURATION_SECONDS = 120; - private static final int FARTHEST_GENERATORS = 3; - private final Set blockedGenerators = new HashSet<>(); - private boolean effectActive = false; - - public CorruptInterventionPerk(mdbd plugin) { - super(plugin, "corrupt_intervention", "Вмешательство Порчи", - "3 самых дальних генератора от киллера заблокированы на 120 секунд", - PerkType.KILLER, true, 0); - } - - @Override - public void onEquip(BasePlayer player) { - effectActive = true; - sendPerkMessage(player, "§cВмешательство активировано! Дальние генераторы заблокированы"); - startEffectTimer(); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_GENERATOR_START && effectActive) { - if (context instanceof UUID genId) { - if (blockedGenerators.contains(genId)) { - preventRepair(player, genId); - } - } - } - } - - private void preventRepair(BasePlayer player, UUID genId) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer == null) return; - bukkitPlayer.sendMessage("§cЭтот генератор заблокирован Порчей!"); - spawnBlockEffect(bukkitPlayer); - } - - private void spawnBlockEffect(Player player) { - Location loc = player.getLocation(); - player.getWorld().spawnParticle(Particle.WITCH, loc.add(0, 1, 0), 5, 0.5, 0.5, 0.5, 0); - } - - private void startEffectTimer() { - new BukkitRunnable() { - @Override - public void run() { - effectActive = false; - blockedGenerators.clear(); - } - }.runTaskLater(plugin, BLOCK_DURATION_SECONDS * 20L); - } - - @Override - public void onRemove(BasePlayer player) { - effectActive = false; - blockedGenerators.clear(); - sendPerkMessage(player, "Перк деактивирован"); - } - - public void blockGenerator(UUID generatorId) { - if (blockedGenerators.size() < FARTHEST_GENERATORS) { - blockedGenerators.add(generatorId); - } - } - - public boolean isGeneratorBlocked(UUID generatorId) { - return effectActive && blockedGenerators.contains(generatorId); - } - - public boolean isEffectActive() { - return effectActive; - } - - public static int getBlockDuration() { - return BLOCK_DURATION_SECONDS; - } - - public static int getFarthestGeneratorCount() { - return FARTHEST_GENERATORS; - } -} diff --git a/src/main/java/dev/loki/perk/killer/HexRuinPerk.java b/src/main/java/dev/loki/perk/killer/HexRuinPerk.java deleted file mode 100644 index e021904..0000000 --- a/src/main/java/dev/loki/perk/killer/HexRuinPerk.java +++ /dev/null @@ -1,94 +0,0 @@ -package dev.loki.perk.killer; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class HexRuinPerk extends BasePerk { - private static final double REGRESSION_RATE = 0.25; - private static final double KICK_REGRESSION = 2.5; - private final Map affectedGenerators = new HashMap<>(); - private boolean hexActive = true; - - public HexRuinPerk(mdbd plugin) { - super(plugin, "hex_ruin", "Порча: Губительность", - "Генераторы автоматически теряют прогресс когда не чинятся", - PerkType.KILLER, true, 0); - } - - @Override - public void onEquip(BasePlayer player) { - hexActive = true; - sendPerkMessage(player, "§cПорча активирована! Генераторы регрессируют"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - switch (trigger) { - case ON_GENERATOR_START -> handleGeneratorStart(player, context); - case ON_GENERATOR_COMPLETE -> handleGeneratorComplete(player, context); - case ON_TOTEM_CLEANSED -> handleTotemCleansed(player); - } - } - - private void handleGeneratorStart(BasePlayer player, Object context) { - if (!hexActive) return; - if (context instanceof UUID genId) { - affectedGenerators.put(genId, 0.0); - spawnHexParticles(player); - } - } - - private void handleGeneratorComplete(BasePlayer player, Object context) { - if (context instanceof UUID genId) { - affectedGenerators.remove(genId); - } - } - - private void handleTotemCleansed(BasePlayer player) { - hexActive = false; - affectedGenerators.clear(); - sendPerkMessage(player, "§cПорча очищена! Губительность деактивирована"); - } - - private void spawnHexParticles(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer == null) return; - for (int i = 0; i < 5; i++) { - Location loc = bukkitPlayer.getLocation().add( - Math.random() * 4 - 2, - Math.random() * 2, - Math.random() * 4 - 2 - ); - bukkitPlayer.getWorld().spawnParticle(Particle.SOUL_FIRE_FLAME, loc, 3, 0.2, 0.2, 0.2, 0.01); - } - } - - @Override - public void onRemove(BasePlayer player) { - hexActive = false; - affectedGenerators.clear(); - sendPerkMessage(player, "Перк деактивирован"); - } - - public static double getRegressionRate() { - return REGRESSION_RATE; - } - - public static double getKickRegression() { - return KICK_REGRESSION; - } - - public boolean isHexActive() { - return hexActive; - } -} diff --git a/src/main/java/dev/loki/perk/survivor/BorrowedTimePerk.java b/src/main/java/dev/loki/perk/survivor/BorrowedTimePerk.java deleted file mode 100644 index dc5619d..0000000 --- a/src/main/java/dev/loki/perk/survivor/BorrowedTimePerk.java +++ /dev/null @@ -1,76 +0,0 @@ -package dev.loki.perk.survivor; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -public class BorrowedTimePerk extends BasePerk { - private static final int ENDURANCE_DURATION_SECONDS = 15; - private static final int SPEED_BOOST_SECONDS = 2; - private static final int SPEED_AMPLIFIER = 1; - - public BorrowedTimePerk(mdbd plugin) { - super(plugin, "borrowed_time", "Заемное Время", - "После снятия с крюка получите 15 сек неуязвимости и рывок скорости", - PerkType.SURVIVOR, true, 0); - } - - @Override - public void onEquip(BasePlayer player) { - sendPerkMessage(player, "Активировано: защита после спасения"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_UNHOOKED) { - applyEndurance(player); - } - } - - private void applyEndurance(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer == null) return; - - bukkitPlayer.addPotionEffect(new PotionEffect( - PotionEffectType.RESISTANCE, - ENDURANCE_DURATION_SECONDS * 20, - 4, - false, false, true)); - - bukkitPlayer.addPotionEffect(new PotionEffect( - PotionEffectType.SPEED, - SPEED_BOOST_SECONDS * 20, - SPEED_AMPLIFIER, - false, false, true)); - - sendPerkMessage(player, "§aЗаемное Время активировано! 15 сек защиты"); - - new BukkitRunnable() { - @Override - public void run() { - if (player.getPlayer() != null) { - player.getPlayer().sendMessage("§cЗаемное Время закончилось"); - } - } - }.runTaskLater(plugin, ENDURANCE_DURATION_SECONDS * 20L); - } - - @Override - public void onRemove(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer != null) { - bukkitPlayer.removePotionEffect(PotionEffectType.RESISTANCE); - } - sendPerkMessage(player, "Перк деактивирован"); - } - - public static int getEnduranceDuration() { - return ENDURANCE_DURATION_SECONDS; - } -} diff --git a/src/main/java/dev/loki/perk/survivor/DeadHardPerk.java b/src/main/java/dev/loki/perk/survivor/DeadHardPerk.java deleted file mode 100644 index 9095bfa..0000000 --- a/src/main/java/dev/loki/perk/survivor/DeadHardPerk.java +++ /dev/null @@ -1,76 +0,0 @@ -package dev.loki.perk.survivor; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import dev.loki.player.PlayerState; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class DeadHardPerk extends BasePerk { - private static final int DASH_DISTANCE = 4; - private static final int INVULNERABILITY_TICKS = 20; - private static final int EXHAUSTION_SECONDS = 60; - - public DeadHardPerk(mdbd plugin) { - super(plugin, "dead_hard", "Тяжелый Рывок", - "При ранении активируйте для рывка и неуязвимости", - PerkType.SURVIVOR, false, EXHAUSTION_SECONDS); - } - - @Override - public void onEquip(BasePlayer player) { - sendPerkMessage(player, "Готов к использованию"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_KILLER_HIT && !isOnCooldown()) { - if (shouldActivate(player)) { - performDash(player); - } - } - } - - private boolean shouldActivate(BasePlayer player) { - return player.getState() == PlayerState.INJURED; - } - - private void performDash(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer == null) return; - - Vector direction = bukkitPlayer.getLocation().getDirection(); - direction.setY(0).normalize().multiply(DASH_DISTANCE); - - Location target = bukkitPlayer.getLocation().add(direction); - bukkitPlayer.teleport(target); - bukkitPlayer.getWorld().spawnParticle(Particle.CLOUD, bukkitPlayer.getLocation(), 10); - - startCooldown(); - sendPerkMessage(player, "Рывок выполнен!"); - - new BukkitRunnable() { - @Override - public void run() { - if (player.getPlayer() != null) { - player.getPlayer().sendMessage("§aТяжелый Рывок готов к использованию!"); - } - } - }.runTaskLater(plugin, cooldownSeconds * 20L); - } - - @Override - public void onRemove(BasePlayer player) { - sendPerkMessage(player, "Перк деактивирован"); - } - - public static int getInvulnerabilityTicks() { - return INVULNERABILITY_TICKS; - } -} diff --git a/src/main/java/dev/loki/perk/survivor/SelfCarePerk.java b/src/main/java/dev/loki/perk/survivor/SelfCarePerk.java deleted file mode 100644 index 7780cd7..0000000 --- a/src/main/java/dev/loki/perk/survivor/SelfCarePerk.java +++ /dev/null @@ -1,53 +0,0 @@ -package dev.loki.perk.survivor; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import dev.loki.player.PlayerState; - -public class SelfCarePerk extends BasePerk { - private static final double HEAL_RATE = 0.5; - private static final int SELF_HEAL_TIME = 24; - - public SelfCarePerk(mdbd plugin) { - super(plugin, "self_care", "Самолечение", - "Позволяет лечить себя без аптечки на 50% скорости", - PerkType.SURVIVOR, true, 0); - } - - @Override - public void onEquip(BasePlayer player) { - sendPerkMessage(player, "Активировано: вы можете лечить себя без аптечки"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_HEAL_START) { - handleSelfHeal(player, context); - } - } - - private void handleSelfHeal(BasePlayer player, Object context) { - if (player.getState() != PlayerState.INJURED) { - return; - } - if (context instanceof Boolean && (Boolean) context) { - sendPerkMessage(player, "Вы начали лечить себя..."); - } - } - - @Override - public void onRemove(BasePlayer player) { - sendPerkMessage(player, "Перк деактивирован"); - } - - public static double getHealRate() { - return HEAL_RATE; - } - - public static int getSelfHealTime() { - return SELF_HEAL_TIME; - } -} diff --git a/src/main/java/dev/loki/perk/survivor/SprintBurstPerk.java b/src/main/java/dev/loki/perk/survivor/SprintBurstPerk.java deleted file mode 100644 index cc26397..0000000 --- a/src/main/java/dev/loki/perk/survivor/SprintBurstPerk.java +++ /dev/null @@ -1,80 +0,0 @@ -package dev.loki.perk.survivor; - -import dev.loki.mdbd; -import dev.loki.perk.BasePerk; -import dev.loki.perk.PerkTrigger; -import dev.loki.perk.PerkType; -import dev.loki.player.BasePlayer; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -public class SprintBurstPerk extends BasePerk { - private static final int SPRINT_DURATION_SECONDS = 3; - private static final int EXHAUSTION_SECONDS = 40; - private static final int SPEED_AMPLIFIER = 2; - - public SprintBurstPerk(mdbd plugin) { - super(plugin, "sprint_burst", "Рывок Скорости", - "При старте бега получите 150% скорости на 3 секунды", - PerkType.SURVIVOR, false, EXHAUSTION_SECONDS); - } - - @Override - public void onEquip(BasePlayer player) { - sendPerkMessage(player, "Готов к использованию"); - } - - @Override - public void onTrigger(BasePlayer player, PerkTrigger trigger, Object context) { - if (trigger == PerkTrigger.ON_SPRINT_START && !isOnCooldown()) { - activateSprint(player); - } - } - - private void activateSprint(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer == null) return; - - bukkitPlayer.addPotionEffect(new PotionEffect( - PotionEffectType.SPEED, - SPRINT_DURATION_SECONDS * 20, - SPEED_AMPLIFIER, - false, false, true)); - - startCooldown(); - sendPerkMessage(player, "§aРывок активирован!"); - - new BukkitRunnable() { - @Override - public void run() { - if (player.getPlayer() != null) { - player.getPlayer().sendMessage("§cИзнурение... Рывок на перезарядке"); - } - } - }.runTaskLater(plugin, SPRINT_DURATION_SECONDS * 20L); - - new BukkitRunnable() { - @Override - public void run() { - if (player.getPlayer() != null) { - player.getPlayer().sendMessage("§aРывок Скорости снова готов!"); - } - } - }.runTaskLater(plugin, cooldownSeconds * 20L); - } - - @Override - public void onRemove(BasePlayer player) { - Player bukkitPlayer = player.getPlayer(); - if (bukkitPlayer != null) { - bukkitPlayer.removePotionEffect(PotionEffectType.SPEED); - } - sendPerkMessage(player, "Перк деактивирован"); - } - - public static int getSprintDuration() { - return SPRINT_DURATION_SECONDS; - } -} diff --git a/src/main/java/dev/loki/phase/GameplayPhase.java b/src/main/java/dev/loki/phase/GameplayPhase.java index 1a8ea25..9a7a00f 100644 --- a/src/main/java/dev/loki/phase/GameplayPhase.java +++ b/src/main/java/dev/loki/phase/GameplayPhase.java @@ -1,36 +1,92 @@ package dev.loki.phase; import dev.loki.core.GameSession; +import dev.loki.objective.Generator; +import dev.loki.objective.GeneratorManager; +import dev.loki.player.BasePlayer; +import dev.loki.player.PlayerState; import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; public class GameplayPhase implements Phase { - private int gameTicks; + private final GeneratorManager generatorManager; + private int tickCounter; private boolean shouldEnd; + private boolean allGensDone; + + public GameplayPhase(GeneratorManager generatorManager) { + this.generatorManager = generatorManager; + this.tickCounter = 0; + this.shouldEnd = false; + this.allGensDone = false; + } @Override public void enter(GameSession session) { Bukkit.broadcastMessage("[DBD] Игра началась! Выжившие, чините генераторы!"); - gameTicks = 0; - shouldEnd = false; + tickCounter = 0; } @Override public void tick(GameSession session) { - gameTicks++; - // TODO: Check endgame conditions + tickCounter++; + + generatorManager.tick(); + + if (tickCounter % 20 == 0) { + checkGeneratorProgress(session); + checkWinConditions(session); + } + } + + private void checkGeneratorProgress(GameSession session) { + if (allGensDone) return; + + if (generatorManager.areAllRequiredCompleted()) { + allGensDone = true; + Bukkit.broadcastMessage("[DBD] §a§lВсе генераторы починены! Открывайте ворота!"); + for (BasePlayer bp : session.getPlayers().values()) { + Player p = bp.getPlayer(); + if (p != null) { + p.playSound(p.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_BLAST, 1.0f, 1.0f); + } + } + } + } + + private void checkWinConditions(GameSession session) { + int aliveSurvivors = 0; + int escapedSurvivors = 0; + boolean killerDead = true; + + for (BasePlayer bp : session.getPlayers().values()) { + if (bp.isKiller()) { + killerDead = false; + continue; + } + PlayerState state = bp.getState(); + if (state == PlayerState.ESCAPED) { + escapedSurvivors++; + } else if (state != PlayerState.DEAD && state != PlayerState.HOOKED) { + aliveSurvivors++; + } + } + + boolean allSurvivorsDead = (aliveSurvivors == 0 && escapedSurvivors == 0); + + if (allSurvivorsDead || escapedSurvivors == session.getPlayerCount() - 1) { + shouldEnd = true; + } } @Override public void exit(GameSession session) { - Bukkit.broadcastMessage("[DBD] Игра завершена!"); + Bukkit.broadcastMessage("[DBD] §6Игровая фаза завершена!"); } @Override public boolean isComplete() { return shouldEnd; } - - public void forceEnd() { - shouldEnd = true; - } } diff --git a/src/main/java/dev/loki/totem/HexTotem.java b/src/main/java/dev/loki/totem/HexTotem.java index f0699d7..3f91340 100644 --- a/src/main/java/dev/loki/totem/HexTotem.java +++ b/src/main/java/dev/loki/totem/HexTotem.java @@ -1,6 +1,5 @@ package dev.loki.totem; -import dev.loki.perk.killer.HexRuinPerk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; @@ -81,6 +80,6 @@ public class HexTotem extends Totem { } public Class getHexType() { - return HexRuinPerk.class; + return null; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8f168aa..3502c01 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,7 +6,7 @@ api-version: '1.21' commands: dbd: description: "Главная команда DBD плагина" - usage: "/dbd " + usage: "/dbd " permission: mdbd.player dbdsetup: description: "Команды настройки карты и объектов"