remove: hatch (люк) and windows (окна) from code and config

This commit is contained in:
loki5512344 2026-06-15 12:45:56 +02:00
parent be86fe5960
commit bb293c5d03
15 changed files with 57 additions and 458 deletions

View file

@ -109,10 +109,6 @@ public class GameConfig {
setDefault("colors.progress-bar-incomplete", "&#FF0000"); setDefault("colors.progress-bar-incomplete", "&#FF0000");
setDefault("colors.progress-bar-background", "&#333333"); setDefault("colors.progress-bar-background", "&#333333");
// Hatch
setDefault("hatch.min-survivors-for-open", 1);
setDefault("hatch.require-more-gens-than-survivors", true);
// Block types for spawning // Block types for spawning
setDefault("blocks.generator", "BLAST_FURNACE"); setDefault("blocks.generator", "BLAST_FURNACE");
setDefault("blocks.chest", "CHEST"); setDefault("blocks.chest", "CHEST");

View file

@ -34,9 +34,6 @@ public class LocationsConfig {
if (!config.contains("hooks") || config.getList("hooks") == null) { if (!config.contains("hooks") || config.getList("hooks") == null) {
config.set("hooks", new ArrayList<>()); config.set("hooks", new ArrayList<>());
} }
if (!config.contains("windows") || config.getList("windows") == null) {
config.set("windows", new ArrayList<>());
}
if (!config.contains("chests") || config.getList("chests") == null) { if (!config.contains("chests") || config.getList("chests") == null) {
config.set("chests", new ArrayList<>()); config.set("chests", new ArrayList<>());
} }
@ -79,10 +76,6 @@ public class LocationsConfig {
return loadLocationList("hooks"); return loadLocationList("hooks");
} }
public List<Location> getWindows() {
return loadLocationList("windows");
}
public List<Location> getChests() { public List<Location> getChests() {
return loadLocationList("chests"); return loadLocationList("chests");
} }

View file

@ -115,7 +115,7 @@ public class GameSession {
if (currentPhase instanceof GameplayPhase gp) { if (currentPhase instanceof GameplayPhase gp) {
// Всегда переходим в EndgamePhase для корректного завершения игры // Всегда переходим в EndgamePhase для корректного завершения игры
// (очистка скорборда, телепорт в лобби, показ результатов) // (очистка скорборда, телепорт в лобби, показ результатов)
return new EndgamePhase(gateManager, null, null); return new EndgamePhase(gateManager);
} }
return null; return null;
} }

View file

@ -60,6 +60,7 @@ public class ExitGate {
World world = location.getWorld(); World world = location.getWorld();
if (world == null) return; if (world == null) return;
// Place all iron bars first (no physics) then force update for connections
if (hasZone) { if (hasZone) {
for (int x = zoneMinX; x <= zoneMaxX; x++) { for (int x = zoneMinX; x <= zoneMaxX; x++) {
for (int y = zoneMinY; y <= zoneMaxY; y++) { for (int y = zoneMinY; y <= zoneMaxY; y++) {
@ -68,6 +69,14 @@ public class ExitGate {
} }
} }
} }
// Force update all iron bars so they connect to neighbors
for (int x = zoneMinX; x <= zoneMaxX; x++) {
for (int y = zoneMinY; y <= zoneMaxY; y++) {
for (int z = zoneMinZ; z <= zoneMaxZ; z++) {
world.getBlockAt(x, y, z).getState().update(true, true);
}
}
}
} else { } else {
// Fallback: 3x3x3 zone around gate location // Fallback: 3x3x3 zone around gate location
int cx = location.getBlockX(), cy = location.getBlockY(), cz = location.getBlockZ(); int cx = location.getBlockX(), cy = location.getBlockY(), cz = location.getBlockZ();
@ -78,6 +87,13 @@ public class ExitGate {
} }
} }
} }
for (int x = cx - 1; x <= cx + 1; x++) {
for (int y = cy; y <= cy + 2; y++) {
for (int z = cz - 1; z <= cz + 1; z++) {
world.getBlockAt(x, y, z).getState().update(true, true);
}
}
}
} }
// Button at gate center + (1, 1, 1) // Button at gate center + (1, 1, 1)

View file

@ -1,125 +0,0 @@
package dev.loki.hatch;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
public class Hatch {
private final Location location;
private HatchState state;
private Block hatchBlock;
public enum HatchState {
HIDDEN,
CLOSED,
OPEN
}
public Hatch(Location location) {
this.location = location;
this.state = HatchState.HIDDEN;
this.hatchBlock = location.getBlock();
}
public Location getLocation() {
return location;
}
public Location getJumpTarget() {
return location.clone().add(0.5, -2, 0.5);
}
public HatchState getState() {
return state;
}
public boolean isHidden() {
return state == HatchState.HIDDEN;
}
public boolean isClosed() {
return state == HatchState.CLOSED;
}
public boolean isOpen() {
return state == HatchState.OPEN;
}
public void reveal() {
if (state == HatchState.HIDDEN) {
state = HatchState.CLOSED;
updateVisuals();
playRevealEffect();
}
}
public void open() {
if (state == HatchState.CLOSED) {
state = HatchState.OPEN;
updateVisuals();
playOpenEffect();
}
}
public void hide() {
state = HatchState.HIDDEN;
clearVisuals();
}
public void reset() {
state = HatchState.HIDDEN;
clearVisuals();
}
private void updateVisuals() {
switch (state) {
case CLOSED -> hatchBlock.setType(Material.IRON_TRAPDOOR);
case OPEN -> hatchBlock.setType(Material.AIR);
default -> hatchBlock.setType(Material.AIR);
}
}
private void clearVisuals() {
hatchBlock.setType(Material.AIR);
}
public boolean isInRange(Location playerLoc, double radius) {
return location.distance(playerLoc) <= radius;
}
public boolean canEscape(Location playerLoc) {
return isOpen() && isInRange(playerLoc, 1.5);
}
private void playRevealEffect() {
World world = location.getWorld();
if (world == null) return;
world.playSound(location, Sound.BLOCK_METAL_PLACE, 1.0f, 0.8f);
world.spawnParticle(org.bukkit.Particle.SMOKE,
location.clone().add(0.5, 0.5, 0.5),
30, 0.3, 0.3, 0.3, 0.05);
}
private void playOpenEffect() {
World world = location.getWorld();
if (world == null) return;
world.playSound(location, Sound.BLOCK_IRON_TRAPDOOR_OPEN, 1.0f, 1.0f);
world.spawnParticle(org.bukkit.Particle.END_ROD,
location.clone().add(0.5, 0.5, 0.5),
20, 0.2, 0.2, 0.2, 0.02);
}
public void playEscapeEffect() {
World world = location.getWorld();
if (world == null) return;
world.playSound(location, Sound.ENTITY_PLAYER_SPLASH, 1.0f, 1.0f);
world.spawnParticle(org.bukkit.Particle.PORTAL,
location.clone().add(0.5, 0, 0.5),
100, 0.5, 0.5, 0.5, 0.5);
}
}

View file

@ -1,76 +0,0 @@
package dev.loki.hatch;
import dev.loki.player.BasePlayer;
import dev.loki.player.PlayerState;
import java.util.Collection;
public class HatchCondition {
private final int minSurvivorsForOpen;
public HatchCondition(int minSurvivorsForOpen) {
this.minSurvivorsForOpen = minSurvivorsForOpen;
}
public boolean shouldSpawn(Collection<BasePlayer> players, int repairedGenerators) {
int aliveSurvivors = countAliveSurvivors(players);
return aliveSurvivors <= repairedGenerators;
}
public boolean shouldOpen(Hatch hatch, Collection<BasePlayer> players, int repairedGenerators) {
if (hatch.isOpen()) return false;
if (!hatch.isClosed() && !hatch.isHidden()) return false;
return shouldSpawn(players, repairedGenerators);
}
public boolean canOpen(Hatch hatch, Collection<BasePlayer> players, int repairedGenerators) {
if (!hatch.isHidden() && !hatch.isClosed()) return false;
int aliveSurvivors = countAliveSurvivors(players);
int requiredGens = Math.max(minSurvivorsForOpen, aliveSurvivors);
return repairedGenerators >= requiredGens;
}
public int countAliveSurvivors(Collection<BasePlayer> players) {
return (int) players.stream()
.filter(p -> !p.isKiller())
.filter(this::isAlive)
.count();
}
private boolean isAlive(BasePlayer player) {
PlayerState state = player.getState();
return state != PlayerState.DEAD
&& state != PlayerState.ESCAPED
&& state != PlayerState.HOOKED;
}
public int getRemainingAlive(Collection<BasePlayer> players) {
return countAliveSurvivors(players);
}
public boolean isLastSurvivor(Collection<BasePlayer> players) {
return countAliveSurvivors(players) == 1;
}
public boolean checkAndReveal(Hatch hatch, Collection<BasePlayer> players, int repairedGenerators) {
if (hatch.isHidden() && shouldSpawn(players, repairedGenerators)) {
hatch.reveal();
return true;
}
return false;
}
public boolean checkAndOpen(Hatch hatch, Collection<BasePlayer> players, int repairedGenerators) {
if (canOpen(hatch, players, repairedGenerators)) {
if (hatch.isHidden()) {
hatch.reveal();
}
hatch.open();
return true;
}
return false;
}
}

View file

@ -1,117 +0,0 @@
package dev.loki.hatch;
import dev.loki.config.MessagesConfig;
import dev.loki.mdbd;
import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class HatchEscape {
private static final double ESCAPE_RADIUS = 1.5;
private final Hatch hatch;
private final MessagesConfig messages;
public HatchEscape(Hatch hatch) {
this.hatch = hatch;
this.messages = mdbd.getInstance().getConfigManager().getMessages();
}
public boolean tryEscape(Survivor survivor) {
if (!hatch.isOpen()) {
return tryRevealAndCheck(survivor);
}
Player player = survivor.getPlayer();
if (player == null) return false;
if (!isAtHatch(player.getLocation())) {
player.sendMessage(messages.get("hatch.too-far"));
return false;
}
performEscape(survivor);
return true;
}
public boolean canEscape(Survivor survivor) {
if (!hatch.isOpen()) return false;
Player player = survivor.getPlayer();
if (player == null) return false;
return isAtHatch(player.getLocation());
}
private boolean tryRevealAndCheck(Survivor survivor) {
Player player = survivor.getPlayer();
if (player == null) return false;
if (hatch.isHidden()) {
player.sendMessage(messages.get("hatch.hidden"));
return false;
}
if (hatch.isClosed()) {
player.sendMessage(messages.get("hatch.closed"));
return false;
}
return false;
}
private boolean isAtHatch(Location location) {
return hatch.isInRange(location, ESCAPE_RADIUS);
}
private void performEscape(Survivor survivor) {
Player player = survivor.getPlayer();
if (player == null) return;
player.teleport(hatch.getJumpTarget());
hatch.playEscapeEffect();
player.getWorld().playSound(player.getLocation(),
Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.0f);
player.sendTitle(
messages.getString("hatch.escape-title"),
messages.getString("hatch.escape-subtitle"),
10, 60, 10);
survivor.setState(PlayerState.ESCAPED);
giveEscapeReward(survivor);
}
private void giveEscapeReward(Survivor survivor) {
Player player = survivor.getPlayer();
if (player == null) return;
player.sendMessage(messages.get("hatch.reward"));
}
public void forceOpenForEscape() {
if (hatch.isHidden()) {
hatch.reveal();
}
if (!hatch.isOpen()) {
hatch.open();
}
}
public void notifyNearbyPlayers() {
Location hatchLoc = hatch.getLocation();
World world = hatchLoc.getWorld();
if (world == null) return;
for (Player player : world.getPlayers()) {
if (player.getLocation().distance(hatchLoc) < 30) {
player.sendMessage(messages.get("hatch.open-notify"));
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 2.0f);
}
}
}
}

View file

@ -32,7 +32,7 @@ public class PlayerInteractListener implements Listener {
private BiConsumer<Player, Boolean> onAttack; private BiConsumer<Player, Boolean> onAttack;
private BiConsumer<Player, Boolean> onRescueAttempt; private BiConsumer<Player, Boolean> onRescueAttempt;
private BiConsumer<Player, Boolean> onChestInteract; private BiConsumer<Player, Boolean> onChestInteract;
private BiConsumer<Player, Boolean> onHatchInteract; private BiConsumer<Player, Boolean> onGateInteract;
/** Called when killer toggles sneak: (player, isSneaking) */ /** Called when killer toggles sneak: (player, isSneaking) */
private BiConsumer<Player, Boolean> onKillerSneak; private BiConsumer<Player, Boolean> onKillerSneak;
/** Called when a survivor sneaks near another injured/downed survivor: (healer, target) */ /** Called when a survivor sneaks near another injured/downed survivor: (healer, target) */
@ -56,7 +56,7 @@ public class PlayerInteractListener implements Listener {
public void setOnAttack(BiConsumer<Player, Boolean> h) { this.onAttack = h; } public void setOnAttack(BiConsumer<Player, Boolean> h) { this.onAttack = h; }
public void setOnRescueAttempt(BiConsumer<Player, Boolean> h) { this.onRescueAttempt = h; } public void setOnRescueAttempt(BiConsumer<Player, Boolean> h) { this.onRescueAttempt = h; }
public void setOnChestInteract(BiConsumer<Player, Boolean> h) { this.onChestInteract = h; } public void setOnChestInteract(BiConsumer<Player, Boolean> h) { this.onChestInteract = h; }
public void setOnHatchInteract(BiConsumer<Player, Boolean> h) { this.onHatchInteract = h; } public void setOnGateInteract(BiConsumer<Player, Boolean> h) { this.onGateInteract = h; }
public void setOnKillerSneak(BiConsumer<Player, Boolean> h) { this.onKillerSneak = h; } public void setOnKillerSneak(BiConsumer<Player, Boolean> h) { this.onKillerSneak = h; }
public void setOnHealSneak(BiConsumer<Player, Player> h) { this.onHealSneak = h; } public void setOnHealSneak(BiConsumer<Player, Player> h) { this.onHealSneak = h; }
private BiConsumer<Player, Boolean> onCarriedShift; private BiConsumer<Player, Boolean> onCarriedShift;
@ -245,12 +245,12 @@ public class PlayerInteractListener implements Listener {
} }
// Gate opening — проверяем ДО генератора, чтобы ворота можно было открыть рядом с геной // Gate opening — проверяем ДО генератора, чтобы ворота можно было открыть рядом с геной
if (!bp.isKiller() && onHatchInteract != null) { if (!bp.isKiller() && onGateInteract != null) {
var s = gameManager.getPlayerSession(player.getUniqueId()); var s = gameManager.getPlayerSession(player.getUniqueId());
if (s != null && s.getGateManager() != null) { if (s != null && s.getGateManager() != null) {
var gate = s.getGateManager().getGateAt(player.getLocation(), 3.0); var gate = s.getGateManager().getGateAt(player.getLocation(), 3.0);
if (gate != null && !gate.isOpen()) { if (gate != null && !gate.isOpen()) {
onHatchInteract.accept(player, true); onGateInteract.accept(player, true);
return; return;
} }
} }

View file

@ -95,7 +95,6 @@ public class MapConfig {
applyList("generators", locs); applyList("generators", locs);
applyList("hooks", locs); applyList("hooks", locs);
applyList("chests", locs); applyList("chests", locs);
applyList("windows", locs);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------

View file

@ -83,10 +83,6 @@ public class TemplateManager {
// Chest preset (1x1x1) // Chest preset (1x1x1)
presets.put("chest_default", new PresetMap("chest_default", presets.put("chest_default", new PresetMap("chest_default",
"chest", new Location(null, 0, 0, 0))); "chest", new Location(null, 0, 0, 0)));
// Hatch preset (2x1x2)
presets.put("hatch_default", new PresetMap("hatch_default",
"hatch", new Location(null, 1, 0, 1)));
} }
public boolean placeObject(String templateName, Location location) { public boolean placeObject(String templateName, Location location) {

View file

@ -2,12 +2,8 @@ package dev.loki.phase;
import dev.loki.core.GameSession; import dev.loki.core.GameSession;
import dev.loki.gate.GateManager; import dev.loki.gate.GateManager;
import dev.loki.hatch.Hatch;
import dev.loki.hatch.HatchCondition;
import dev.loki.hatch.HatchEscape;
import dev.loki.player.BasePlayer; import dev.loki.player.BasePlayer;
import dev.loki.player.PlayerState; import dev.loki.player.PlayerState;
import dev.loki.player.Survivor;
import dev.loki.ui.Sidebar; import dev.loki.ui.Sidebar;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -27,9 +23,6 @@ public class EndgamePhase implements Phase {
private boolean gatesActivated; private boolean gatesActivated;
private boolean killerWin; // true если маньяк убил всех — пропускаем геймплей эндгейма private boolean killerWin; // true если маньяк убил всех — пропускаем геймплей эндгейма
private GateManager gateManager; private GateManager gateManager;
private Hatch hatch;
private HatchCondition hatchCondition;
private HatchEscape hatchEscape;
private Sidebar sidebar; private Sidebar sidebar;
private int endgameTimer = -1; // секунд до конца эндгейма (-1 = не активно) private int endgameTimer = -1; // секунд до конца эндгейма (-1 = не активно)
@ -37,13 +30,9 @@ public class EndgamePhase implements Phase {
this.openTicks = 20 * 20; this.openTicks = 20 * 20;
} }
public EndgamePhase(GateManager gateManager, public EndgamePhase(GateManager gateManager) {
Hatch hatch, HatchCondition hatchCondition) {
this.openTicks = 20 * 20; this.openTicks = 20 * 20;
this.gateManager = gateManager; this.gateManager = gateManager;
this.hatch = hatch;
this.hatchCondition = hatchCondition;
this.hatchEscape = new HatchEscape(hatch);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -120,7 +109,7 @@ public class EndgamePhase implements Phase {
} }
} }
updateHatch(session); updateGates(session);
checkWinConditions(session); checkWinConditions(session);
} }
@ -137,10 +126,6 @@ public class EndgamePhase implements Phase {
sidebar = null; sidebar = null;
} }
if (hatch != null) {
hatch.reset();
}
if (gateManager != null) { if (gateManager != null) {
gateManager.resetAll(); gateManager.resetAll();
} }
@ -229,29 +214,9 @@ public class EndgamePhase implements Phase {
gateManager.activateEndgame(); gateManager.activateEndgame();
gatesActivated = true; gatesActivated = true;
} }
checkHatchConditions(session);
session.getPlugin().getLogger().info("Endgame started!"); 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 (hatchCondition.isLastSurvivor(session.getPlayers().values())) {
hatchCondition.checkAndOpen(hatch, session.getPlayers().values(), repairedGens);
if (hatch.isOpen() && hatchEscape != null) {
hatchEscape.notifyNearbyPlayers();
}
}
}
private int countRepairedGenerators(GameSession session) {
if (session.getGeneratorManager() != null) {
return session.getGeneratorManager().getCompletedCount();
}
return 0;
}
private void announceEndgameStart(GameSession session) { private void announceEndgameStart(GameSession session) {
for (BasePlayer bp : session.getPlayers().values()) { for (BasePlayer bp : session.getPlayers().values()) {
Player p = bp.getPlayer(); Player p = bp.getPlayer();
@ -271,18 +236,6 @@ public class EndgamePhase implements Phase {
gateManager.updateAllGates(1.0 / openTicks); gateManager.updateAllGates(1.0 / openTicks);
} }
private void updateHatch(GameSession session) {
if (hatch == null || !hatch.isOpen() || hatchEscape == null) return;
for (BasePlayer player : session.getPlayers().values()) {
if (player.isKiller()) continue;
PlayerState st = player.getState();
if (st != PlayerState.HEALTHY && st != PlayerState.INJURED) continue;
if (hatchEscape.canEscape((Survivor) player)) {
hatchEscape.tryEscape((Survivor) player);
}
}
}
private void checkWinConditions(GameSession session) { private void checkWinConditions(GameSession session) {
if (complete) return; if (complete) return;
int survivorsAlive = 0; int survivorsAlive = 0;

View file

@ -301,8 +301,8 @@ public class GameplayInteraction {
damageSystem.getKillerController().getCarry().onSurvivorShift(survivor.getUuid()); damageSystem.getKillerController().getCarry().onSurvivorShift(survivor.getUuid());
}); });
// Gate (uses hatch callback - triggered on PORTAL/HOPPER interaction) // Gate - triggered on HOPPER interaction
interactListener.setOnHatchInteract((player, ignored) -> { interactListener.setOnGateInteract((player, ignored) -> {
BasePlayer bp = session.getPlayer(player.getUniqueId()); BasePlayer bp = session.getPlayer(player.getUniqueId());
if (bp == null || bp.isKiller()) return; if (bp == null || bp.isKiller()) return;
Survivor survivor = (Survivor) bp; Survivor survivor = (Survivor) bp;
@ -337,7 +337,7 @@ public class GameplayInteraction {
interactListener.setOnCarriedShift(null); interactListener.setOnCarriedShift(null);
interactListener.setOnGeneratorSkillCheckSneak(null); interactListener.setOnGeneratorSkillCheckSneak(null);
interactListener.setOnGeneratorInteract(null); interactListener.setOnGeneratorInteract(null);
interactListener.setOnHatchInteract(null); interactListener.setOnGateInteract(null);
} }
} }
} }

View file

@ -176,20 +176,6 @@ bossbar:
# Расстояние полного заполнения (блоков) # Расстояние полного заполнения (блоков)
full-range: 8 full-range: 8
# Окна
window:
# Быстрый волт выжившего (секунд)
vault-survivor-fast: 1.0
# Медленный волт выжившего (секунд)
vault-survivor-slow: 1.5
# Волт киллера (секунд)
vault-killer: 1.5
# Блокировка после 3 волтов подряд (секунд)
vault-block-seconds: 15
# Эндгейм # Эндгейм
endgame: endgame:
# Время открытия ворот (секунд) # Время открытия ворот (секунд)
@ -229,14 +215,6 @@ scoreboard:
color-healing: "GREEN" color-healing: "GREEN"
color-hooked: "DARK_RED" color-hooked: "DARK_RED"
# Люк
hatch:
# Минимум живых для открытия люка
min-survivors-for-open: 1
# Условие: живых < починенных генераторов
require-more-gens-than-survivors: true
# Блоки для объектов (спавнятся на местах при старте игры) # Блоки для объектов (спавнятся на местах при старте игры)
blocks: blocks:
# Блок на месте генератора # Блок на месте генератора

View file

@ -20,9 +20,6 @@ hooks: []
# Пример: # Пример:
# - "world,120.5,65.0,180.5,0.0,0.0" # - "world,120.5,65.0,180.5,0.0,0.0"
# Окна (много)
windows: []
# Сундуки с лутом (3-4) # Сундуки с лутом (3-4)
chests: [] chests: []

View file

@ -64,7 +64,7 @@ dbdadmin:
hooks: hooks:
usage: "%admin-prefix%&c/dbd admin hooks <игрок> <0-3>" usage: "%admin-prefix%&c/dbd admin hooks <игрок> <0-3>"
sender: "%admin-prefix%&a%s hooks=%d" sender: "%admin-prefix%&a%s hooks=%d"
invalid: "%admin-prefix%&cЧисло 0–3." invalid: "%admin-prefix%&cЧисло 0-3."
kill: kill:
sender: "%admin-prefix%&c%s → DEAD" sender: "%admin-prefix%&c%s → DEAD"
resolve: resolve:
@ -152,8 +152,8 @@ lobby:
# ── Роли ─────────────────────────────────────── # ── Роли ───────────────────────────────────────
role: role:
killer: "%prefix%&4Вы — Маньяк! Поймайте всех выживших!" killer: "%prefix%&4Вы - Маньяк! Поймайте всех выживших!"
survivor: "%prefix%&bВы — Выживший! Почините генераторы и сбегите!" survivor: "%prefix%&bВы - Выживший! Почините генераторы и сбегите!"
# ── Генераторы ───────────────────────────────── # ── Генераторы ─────────────────────────────────
@ -256,17 +256,6 @@ gate:
door-interrupted: "&7Открытие прервано!" door-interrupted: "&7Открытие прервано!"
door-actionbar: "&aОткрываем ворота... (зажмите ПКМ)" door-actionbar: "&aОткрываем ворота... (зажмите ПКМ)"
# ── Люк ────────────────────────────────────────
hatch:
too-far: "&cПодойдите ближе к люку!"
hidden: "&7Люк скрыт..."
closed: "&cЛюк закрыт!"
open-notify: "&e&lЛюк открыт!"
escape-title: "&a&lПОБЕГ!"
escape-subtitle: "&7Вы сбежали через люк!"
reward: "&a+5000 Очков — Побег через люк!"
# ── Игрок вышел ──────────────────────────────── # ── Игрок вышел ────────────────────────────────
quit: quit:
@ -286,19 +275,19 @@ minigames:
usage: usage:
dbd-header: "&6=== DBD Команды ===" dbd-header: "&6=== DBD Команды ==="
dbd-join: "&7/dbd join [name] — присоединиться к игре/лобби" dbd-join: "&7/dbd join [name] - присоединиться к игре/лобби"
dbd-leave: "&7/dbd leave — покинуть игру" dbd-leave: "&7/dbd leave - покинуть игру"
dbd-lobby: "&7/dbd lobby — телепорт в лобби" dbd-lobby: "&7/dbd lobby - телепорт в лобби"
dbd-create: "&7/dbd create — создать лобби" dbd-create: "&7/dbd create - создать лобби"
dbd-list: "&7/dbd list — список лобби" dbd-list: "&7/dbd list - список лобби"
dbd-delete: "&7/dbd delete — удалить лобби" dbd-delete: "&7/dbd delete - удалить лобби"
dbd-admin: "&e/dbd admin — управление игроками в матче" dbd-admin: "&e/dbd admin - управление игроками в матче"
dbd-forcestart: "&e/dbd forcestart — форс старт" dbd-forcestart: "&e/dbd forcestart - форс старт"
dbd-stop: "&e/dbd stop — остановить игру" dbd-stop: "&e/dbd stop - остановить игру"
dbd-reload: "&e/dbd reload — перезагрузить конфиги" dbd-reload: "&e/dbd reload - перезагрузить конфиги"
dbd-setlobby: "&e/dbd setlobby — установить точку лобби" dbd-setlobby: "&e/dbd setlobby - установить точку лобби"
dbd-save: "&e/dbd save — сохранить карту" dbd-save: "&e/dbd save - сохранить карту"
dbd-load: "&e/dbd load — загрузить карту" dbd-load: "&e/dbd load - загрузить карту"
admin-header: "&6=== /dbd admin ===" admin-header: "&6=== /dbd admin ==="
admin-heal: "&6/dbd admin heal [игрок]" admin-heal: "&6/dbd admin heal [игрок]"
admin-down: "&6/dbd admin down [игрок]" admin-down: "&6/dbd admin down [игрок]"
@ -306,20 +295,20 @@ usage:
admin-state: "&6/dbd admin state <игрок> <статус>" admin-state: "&6/dbd admin state <игрок> <статус>"
admin-hooks: "&6/dbd admin hooks <игрок> <0-3>" admin-hooks: "&6/dbd admin hooks <игрок> <0-3>"
admin-kill: "&6/dbd admin kill [игрок]" admin-kill: "&6/dbd admin kill [игрок]"
admin-jump: "&6/dbd admin jump [on/off] — вкл/выкл прыжки" admin-jump: "&6/dbd admin jump [on/off] - вкл/выкл прыжки"
setup-header: "&6=== DBD Setup ===" setup-header: "&6=== DBD Setup ==="
setup-wand: "&6/dbdsetup wand — Получить ванд (ЛКМ/ПКМ для ворот)" setup-wand: "&6/dbdsetup wand - Получить ванд (ЛКМ/ПКМ для ворот)"
setup-hook: "&6/dbdsetup set hook — Установить крюк (ломай блок)" setup-hook: "&6/dbdsetup set hook - Установить крюк (ломай блок)"
setup-chest: "&6/dbdsetup set chest — Установить сундук" setup-chest: "&6/dbdsetup set chest - Установить сундук"
setup-generator: "&6/dbdsetup set generator — Установить генератор" setup-generator: "&6/dbdsetup set generator - Установить генератор"
setup-killer-spawn: "&6/dbdsetup set killer-spawn — Спавн киллера (только 1)" setup-killer-spawn: "&6/dbdsetup set killer-spawn - Спавн киллера (только 1)"
setup-survivor-spawn: "&6/dbdsetup set survivor-spawn — Спавн выжившего (до 4)" setup-survivor-spawn: "&6/dbdsetup set survivor-spawn - Спавн выжившего (до 4)"
setup-gate: "&6/dbdsetup set gate A|B — Установить ворота (из точек ванда)" setup-gate: "&6/dbdsetup set gate A|B - Установить ворота (из точек ванда)"
setup-clear: "&6/dbdsetup clear [тип] — Очистить объекты (без разрушения блоков)" setup-clear: "&6/dbdsetup clear [тип] - Очистить объекты (без разрушения блоков)"
setup-delete: "&6/dbdsetup delete <тип> <#> — Удалить конкретный объект" setup-delete: "&6/dbdsetup delete <тип> <#> - Удалить конкретный объект"
setup-clear-spawns: "&6/dbdsetup clear-spawns — Очистить все спавны" setup-clear-spawns: "&6/dbdsetup clear-spawns - Очистить все спавны"
setup-lobby: "&6/dbdsetup lobby — Установить точку лобби" setup-lobby: "&6/dbdsetup lobby - Установить точку лобби"
admin-list-header: "&6=== DBD Admin ===" admin-list-header: "&6=== DBD Admin ==="
admin-list-list: "&6/dbdadmin list — Список всех объектов" admin-list-list: "&6/dbdadmin list - Список всех объектов"
admin-list-type: "&6/dbdadmin list <тип> — Список по типу" admin-list-type: "&6/dbdadmin list <тип> - Список по типу"
admin-world: "&6/dbdadmin world <game|мир> — Телепорт в мир" admin-world: "&6/dbdadmin world <game|мир> - Телепорт в мир"