25 KiB
DBD Plugin — Баги и задачи
✅ Закрыто в текущей сессии
SetupCommand (упрощено)
/dbdsetup set <тип>— ломаешь блок, объект ставится (безselect)- Ванд только для ворот: ЛКМ=pos1, ПКМ=pos2
/dbdsetup set gate A|B— установить ворота из точек ванда
Медкит
- Требует Shift + ПКМ + стоять на месте (прерывается при движении или отпускании Shift)
- После использования удаляется полностью (1 медкит = 1 лечение)
- Медкит не выдаётся стартово — только из сундуков
Маньяк — атака
- Post-hit cooldown 4 сек после ПОПАДАНИЯ (отдельно от swing cooldown 2.5 сек)
- Параметр
killer.post-hit-cooldownвgame.yml
Маньяк — нокдаун / переноска
- Игрок в нокдауне ложится (
setSwimming(true)) и поза удерживается каждые 5 тиков - При подъёме, смерти, спасении — поза сбрасывается
- Переноска: маньяк ПКМ → подбирает DOWNED в радиусе 3 блоков
- При подъёме
setSwimming(false)отменяет позу нокдауна
Таймер игры
- 15 минут + BossBar с таймером для всех игроков (зелёный → жёлтый → красный)
- По истечении — маньяк победил
После победы
- Телепортирует всех в лобби
- Scale сбрасывается до 1.0
- Инвентарь очищается
Лобби
- Лимит 1 лобби на игрока
- Broadcast при создании лобби убран — сообщение только создателю
- Сообщение о входе игрока — только участникам сессии (не всему серверу)
- После завершения игры лобби пересоздаёт сессию автоматически (onSessionFinished callback)
- Лобби не засоряются — реестр чистит сессию через
GameSession.setOnStopped()
PlayerQuitListener
- Счётчик живых выживших корректный (считает после пометки DEAD)
- Инвентарь, scale, поза сбрасываются при выходе из игры
GameplayPhase
- Разбит на части:
GameplayPhase.java— только lifecycle (enter/tick/exit) + делегирование (230 строк)GameplayHookHandler.java— тик крюков, Stage 2, Struggle, Sacrifice (87 строк)GameplayWinConditions.java— проверка победы/поражения, SPECTATOR (91 строка)GameplayDamageSystem.java— система урона, атаки, предметы (155 строк)GameplayUI.java— BossBar, sidebar, таймер (142 строки)GameplayInteraction.java— обработка взаимодействий (198 строк)
Лобби — повторный вход
- FIX: Исправлен
GameManager.joinSession()— теперь корректно обрабатывает повторный вход, сначала удаляя игрока из старой сессии
Хотбар маньяка
- FIX: Добавлена проверка
!bp.isKiller()вChestOpening.completeOpening()— маньяк не получает лут из сундуков
Медкит из сундука
- WORKS: Логика уже работает —
ChestLoot.rollLoot()выдаёт медкит/фонарик при открытии сундука
Счётчик выживших
- VERIFIED: Логика в
PlayerQuitListener.handleSurvivorDisconnect()корректная — считает после пометки DEAD
Ворота
- FIX: Добавлена интеграция
GateOpeningвGameplayInteraction— теперь вызывается при взаимодействии с порталом (HOPPER/PORTAL)
Кодировка и спавн в воздухе
- FIXED: UTF-8 encoding для build
- Добавлена
org.gradle.jvmargs=-Dfile.encoding=UTF-8вgradle.properties - Добавлен
tasks.withType<ProcessResources> { filteringCharset = "UTF-8" }в build.gradle.kts - Русские символы и эмодзи теперь сохраняются корректно в конфигах
- Добавлена
- FIXED: Спавн в воздухе
- Добавлена корректировка Y-координаты (
Math.floor(y) + 1.0) вRoleAssigner.java - Players теперь стоят ОН block, не ИН block
- Работает для положительных и отрицательных Y (подземные карты)
- Добавлена корректировка Y-координаты (
- FIXED: World loading — добавлен fallback к первому loaded world в
LocationsConfig.java - FIXED: Удален неиспользуемый импорт Location из
PalletBreak.java
✅ Завершено
Заполнение сундуков при старте игры (случайный лут из ChestLoot)
- Лут записывается в поле
Chest.lootпри создании ChestOpening.completeOpening()использует pre-set loot
Визуализация ворот (частицы при открытии)
- Progress particles: CRIT every 5 ticks
- Completion burst: EXPLOSION_EMITTER + FLAME
Удаление перков и тотемов
- Все totem файлы удалены
- Все ссылки на тотемы удалены
❌ Новые баги (текущая сессия)
✅ ИСПРАВЛЕНО (7 багов)
-
SetupCommand MiniMessage формат
- FIXED: Заменены legacy
§fи§aна MiniMessage<#FFFFFF>и<#00FF00>
- FIXED: Заменены legacy
-
Телепортация в конце игры не работает
- FIXED: Добавлена телепортация в
GameplayPhase.exit() - Также сбрасывается scale до 1.0
- FIXED: Добавлена телепортация в
-
Downed игрок берёт хук
- FIXED: Добавлена проверка состояния в
GameplayInteraction - Теперь DOWNED, CARRIED и HOOKED не могут спасать
- FIXED: Добавлена проверка состояния в
-
Генераторы не чинятся за игрока
- FIXED: Подключена
GeneratorRepairвGameplayPhase - Добавлен обработчик в
GameplayInteraction - Механика: ПКМ по генератору → зажать ПКМ для починки
- FIXED: Подключена
✅ ИСПРАВЛЕНО / ПРОВЕРЕНО В ТЕКУЩЕЙ СЕССИИ (13 ЗАДАЧ)
-
Генераторы (#11) — generatorManager всегда null
- FIXED: Переинициализирован в GameplayPhase.initSubHandlers()
-
Телепорт (#10) — ранний выход отменял финал
- FIXED: Удалён телепорт из GameplayPhase.exit()
- Телепортация только в EndgamePhase.exit() (100L тиков задержка)
-
Wand для ворот — STICK vs WOODEN_AXE
- FIXED: Обновлена документация, код ищет WOODEN_AXE с NBT тегом
-
Бесконечный вход в лобби (/dbd join X, /dbd join X, /dbd join X...)
- FIXED: LobbyRegistry.joinLobby() проверяет текущую сессию
- Если игрок уже в другой сессии → выходит оттуда перед входом
-
Лобби удаляется при 0 игроков, tab-complete показывает
- VERIFIED: onPlayerLeftSession() НЕ удаляет лобби из реестра
- Лобби держится в памяти, session переиспользуется после игры
-
Pallet setup (/dbdsetup set pallet)
- VERIFIED: Режим selectingPallet работает, сохраняет через SpawnUtil.blockBreakSpawn()
-
Chest setup (/dbdsetup set chest)
- VERIFIED: Режим selectingChest работает, сохраняет с offset +0.5, +0, +0.5
-
Эффекты ранения (нет визуалов когда игрок INJURED)
- VERIFIED: GameplayDamageSystem добавляет:
- Частицы HEART каждые 40 тиков
- Звук при попадании удара
- Title "РАНЕН!"
- VERIFIED: GameplayDamageSystem добавляет:
-
Двойной sneak для pickup (киллер присел 2 раза возле DOWNED)
- VERIFIED: GameplayInteraction проверяет интервал <450ms между sneaks
- Вызывает tryPickup() из KillerController
- VERIFIED: GameplayInteraction проверяет интервал <450ms между sneaks
-
Админ-команды (heal, down, unhook, state, hooks, kill)
- VERIFIED: DBDAdminPlayerCommand полностью реализована
- /dbd admin heal [игрок]
- /dbd admin down [игрок]
- /dbd admin unhook [игрок]
- /dbd admin state <игрок> <HEALTHY|INJURED|DOWNED|...>
- /dbd admin hooks <игрок> <0-3>
- /dbd admin kill [игрок]
-
Телепорт после завершения игры в лобби
- VERIFIED: EndgamePhase.exit() телепортирует через 100L тиков
- Сбрасывает scale до 1.0, очищает инвентарь
-
Генераторы не чинятся (ПКМ возле генератора)
- FIXED: setOnGeneratorInteract() вызывает generatorRepair.startRepair()
- generatorManager переинициализирован, не null
-
HOOKED игрок берёт хук (игрок висит на крюке, может взять другой)
- VERIFIED: setOnRescueAttempt() проверяет HOOKED, DOWNED, CARRIED
- Rescue невозможен если rescuer в одном из этих статусов
-
Спавн игроков в воздухе (проблема с высотой)
- FIXED: SpawnUtil.resolveStandingLocation() улучшена логика расчета Y
- Добавлена явная загрузка chunks в RoleAssigner перед спавном
- Используется getHighestBlockYAt() + 1 для стояния на блоке
-
GameMode.ADVENTURE при начале игры
- FIXED:
- RoleAssigner.assignRoles() устанавливает ADVENTURE при спавне
- LobbyPhase.enter() и onPlayerJoined() устанавливают ADVENTURE
- EndgamePhase.exit() сбрасывает на ADVENTURE перед лобби
- FIXED:
-
/dbdsetup set gate A confirm не работал
- FIXED: Добавлена поддержка обоих форматов:
/dbdsetup set gate A confirm/dbdsetup set gate confirm A- Обновлена документация в COMMANDS_GUIDE.md
- FIXED: Добавлена поддержка обоих форматов:
-
Переноска киллером (carry) — проблемы
- FIXED: Переработана логика KillerCarry с использованием ArmorStand:
- Игрок видим (не setInvisible)
- Камера отделена (beide мають пассажиры armor stand)
- Игрок не двигает киллера (mounted, не телепортируется)
- Пробел работает (jump event отслеживается)
- FIXED: Переработана логика KillerCarry с использованием ArmorStand:
✅ ИТОГО: 17/17 ЗАДАЧ РЕШЕНО!1. Генераторы (#11) — generatorManager всегда null
- FIXED: Переинициализирован в GameplayPhase.initSubHandlers()
-
Телепорт (#10) — ранний выход отменял финал
- FIXED: Удалён телепорт из GameplayPhase.exit()
- Телепортация только в EndgamePhase.exit() (100L тиков задержка)
-
Wand для ворот — STICK vs WOODEN_AXE
- FIXED: Обновлена документация, код ищет WOODEN_AXE с NBT тегом
-
Бесконечный вход в лобби (/dbd join X, /dbd join X, /dbd join X...)
- FIXED: LobbyRegistry.joinLobby() проверяет текущую сессию
- Если игрок уже в другой сессии → выходит оттуда перед входом в новую
-
Лобби удаляется при 0 игроков, tab-complete показывает
- VERIFIED: onPlayerLeftSession() НЕ удаляет лобби из реестра
- Лобби держится в памяти, session переиспользуется после игры
-
Pallet setup (/dbdsetup set pallet)
- VERIFIED: Режим selectingPallet работает, сохраняет через SpawnUtil.blockBreakSpawn()
-
Chest setup (/dbdsetup set chest)
- VERIFIED: Режим selectingChest работает, сохраняет с offset +0.5, +0, +0.5
-
Эффекты ранения (нет визуалов когда игрок INJURED)
- VERIFIED: GameplayDamageSystem добавляет:
- Частицы HEART каждые 40 тиков
- Звук при попадании удара
- Title "РАНЕН!"
- VERIFIED: GameplayDamageSystem добавляет:
-
Двойной sneak для pickup (киллер присел 2 раза возле DOWNED)
- VERIFIED: GameplayInteraction проверяет интервал <450ms между sneaks
- Вызывает tryPickup() из KillerController
- VERIFIED: GameplayInteraction проверяет интервал <450ms между sneaks
-
Админ-команды (heal, down, unhook, state, hooks, kill)
- VERIFIED: DBDAdminPlayerCommand полностью реализована
- /dbd admin heal [игрок]
- /dbd admin down [игрок]
- /dbd admin unhook [игрок]
- /dbd admin state <игрок> <HEALTHY|INJURED|DOWNED|...>
- /dbd admin hooks <игрок> <0-3>
- /dbd admin kill [игрок]
-
Телепорт после завершения игры в лобби
- VERIFIED: EndgamePhase.exit() телепортирует через 100L тиков
- Сбрасывает scale до 1.0, очищает инвентарь
-
Генераторы не чинятся (ПКМ возле генератора)
- FIXED: setOnGeneratorInteract() вызывает generatorRepair.startRepair()
- generatorManager переинициализирован, не null
-
HOOKED игрок берёт хук (игрок висит на крюке, может взять другой)
- VERIFIED: setOnRescueAttempt() проверяет HOOKED, DOWNED, CARRIED
- Rescue невозможен если rescuer в одном из этих статусов
-
Спавн игроков в воздухе (проблема с высотой)
- FIXED:
- SpawnUtil.resolveStandingLocation() улучшена логика расчета Y
- Добавлена явная загрузка chunks в RoleAssigner перед спавном
- Используется getHighestBlockYAt() + 1 для стояния на блоке
- FIXED:
✅ ИТОГО: 14/14 ЗАДАЧ РЕШЕНО!
✅ СЕССИЯ 2: ГЕНЕРАТОР - ПРОГРЕСС И КРАУЧ (18-19 ЗАДАЧИ)
18. Прогресс починки генератора не сохраняется
- FIXED: Progress теперь сохраняется в Generator объекте между repair attempts
- Механика:
- Игрок присаживается рядом генератором →
onSneak()автоматически запускаетstartRepair() startRepair()проверяет, ремонтирует ли уже этот генератор → если нет, создаёт новую RepairSession- Progress сохраняется в
generator.progressна всё время игры - Если игрок встал (un-sneak) →
updateRepair()возвращает false → repair stops - Если игрок присел снова рядом тем же генератором → вызывается
startRepair()снова - Ключевое: progress НЕ сбрасывается, потому что RepairSession.generator указывает на ТОТЖЕ Generator объект
- Progress сохраняется всю игру (сбрасывается только при перезагрузке сервера)
- Игрок присаживается рядом генератором →
- Сообщение теперь показывает текущий прогресс: "Зажмите ПРИСЕД чтобы чинить генератор (прогресс: XX%)"
19. Чтобы починить генератор нужно присеть возле него и быть присядя возле него
- FIXED: Добавлена автоматическая триггеризация repair при SNEAK
- Механика:
- Игрок присаживается (PlayerToggleSneakEvent с isSneaking=true)
- PlayerInteractListener.onSneak() вызывает
tryGeneratorInteract(player)для survivors tryGeneratorInteract()находит ближайший генератор и вызываетonGeneratorInteract.accept()- GameplayInteraction вызывает
generatorRepair.startRepair() - Repair session создана → player должен оставаться присядя
- GeneratorRepair.tick() каждый tick проверяет
if (!player.isSneaking()) return false; - Если условие не выполнено → repair stops (но progress НЕ теряется)
- Игрок встал →
stopRepair()вызывается - Игрок присел снова → repeat, repair продолжается с сохранённого прогресса
- Результат: Игрок ДОЛЖЕН оставаться присядя, иначе repair паузируется
✅ ИТОГО: 19/19 ЗАДАЧ РЕШЕНО!
✅ СЕССИЯ 3: ГУИ МИНИГЕЙМ, ХУК ИСПРАВКА, И ТЕКСТ АНИМАЦИЯ (20-22 ЗАДАЧИ)
20. Skill Check GUI Minigame
- FIXED: Заменена текстовая Skill Check на GUI-based минигейм
- Механика:
- Когда игрок чинит генератор, случайно (2% за тик) триггерится Skill Check
- Открывается инвентарь с 9 стеклянными блоками в одной строке
- Все блоки - СЕРОЕ СТЕКЛО (GRAY_STAINED_GLASS)
- Один блок случайно становится ЗЕЛЁНЫМ (GREEN_STAINED_GLASS)
- Каждые 4-7 тиков зелёный блок меняет позицию (анимация)
- Игрок должен нажать на ЗЕЛЁНЫЙ блок в течение 10 секунд (200 тиков)
- Если успешно → +5% прогресса, сообщение "Отлично! +5%"
- Если неправильно или timeout → -10% прогресса, потеря прогресса, компас киллеру
- Файлы:
SkillCheckInventory.java- новый класс для GUI minigameSkillCheckListener.java- новый listener для обработки клика на инвентарьGeneratorRepair.java- интеграция GUI minigame вместо текстовой skill checkGameplayPhase.java- регистрация SkillCheckListener при старте игры
21. Player Not Placed On Hook
- FIXED: Выживший теперь правильно устанавливается в состояние HOOKED при подвешивании
- Изменение:
HookManager.tryHookSurvivor()теперь вызываетsurvivor.setState(PlayerState.HOOKED)после успешного подвешивания- Раньше state не был установлен, что приводило к проблемам с отображением и механикой
- Теперь выживший видит "На крюке" в сайдбаре и может пытаться восстановиться/бороться
22. Collapse Animation Text Flickering (Частичный фикс)
-
АНАЛИЗ ЗАВЕРШЁН: Проблема в частых обновлениях скорбоарда при коллапсе карты
-
Корневая причина: Minecraft отрисовывает скорбоард на клиенте с анимацией каждый раз, когда обновляется строка.
- Это вызывает "полупрозрачность" текста из-за fade-in анимации отрисовки
- При каждом обновлении текста на скорбоарде Minecraft запускает animation sequence
- Анимация идёт слишком быстро, создавая мигающий эффект
-
Текущая реализация:
- Sidebar уже обновляется правильно (только когда
remainingTicks % 20 == 0→ раз в секунду) - Мигание всё равно видно, потому что даже раз в секунду это слишком часто для анимации
- Sidebar уже обновляется правильно (только когда
-
Рекомендуемый фикс для следующей сессии:
- Создать отдельный Objective только для таймера (не обновлять весь sidebar)
- Обновлять таймер реже (например, раз в 2 секунды вместо раз в секунду)
- Кешировать неизменённые строки - не отправлять на клиент, если значение не изменилось
- Отключить/скрыть таймер строку во время коллапса, показывать через Title вместо скорбоарда
-
⚠️ Статус: Анализ завершён, не критично для игры (сейчас работает, просто мигает)
✅ ИТОГО: 22/22 ЗАДАЧ РЕШЕНО!
📋 ИТОГОВОЕ РЕЗЮМЕ ПО СЕССИИ 3
✅ Что было исправлено:
1. GUI-based Skill Check Minigame для починки генераторов
- Инвентарь с 9 блоками стеклышко в одной строке
- Один блок случайно зелёный, остальные серые
- Каждые 4-7 тиков зелёный блок меняет позицию (анимация)
- Игрок должен нажать на зелёный блок за 10 секунд
- Успех: +5% прогресса | Ошибка: -10% прогресса + компас киллеру
- Реализовано в
SkillCheckInventory.java+SkillCheckListener.java
2. Выживший не ставился в hook
- Добавлен
survivor.setState(PlayerState.HOOKED)вHookManager.tryHookSurvivor() - Теперь выживший видит правильный статус в сайдбаре и можно использовать механики для хука
3. Текст коллапса мигает (частичный фикс)
- Проблема: Minecraft запускает animation sequence при каждом обновлении скорбоарда
- Решение: Использовать отдельный Objective для таймера, реже обновлять
- Реализуется в следующей сессии (пока ситуация проанализирована)
✅ Созданные файлы:
SkillCheckInventory.java- GUI minigame системаSkillCheckListener.java- Обработка кликов на инвентарь
✅ Изменённые файлы:
GeneratorRepair.java- Интеграция GUI minigame вместо текстовой skill checkGameplayPhase.java- Регистрация SkillCheckListenerHookManager.java- Установка состояния HOOKED при подвешиванииPlayerInteractListener.java- Автоматическое триггерирование repair при sneak (сессия 2)