From 1999ccb3d809fef0a508186f057b7dee728a9cdc Mon Sep 17 00:00:00 2001 From: MpakobecEx Date: Sat, 31 Oct 2026 20:49:17 +0500 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BB=D0=B0=D0=BD=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8=20DeckBuilder=20(TAS?= =?UTF-8?q?K-2026-023)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Решения: один экран с панелями «Мои колоды»/«Колода»; превью — только иллюстрация карты; фильтры — модальный оверлей с мультивыбором клана, грейда и триггера; сортировка колоды грейд → имя, группировка по nameId. - Чек-лист C1-C11: обрезка иллюстрации, один экран, корректный список колод и карт, live-валидация, тесты и проверки. --- docs/Development/IMPLEMENTATION_PLAN.md | 228 ++++++++++++++++++++++++ docs/SESSION-STATE.md | 4 +- 2 files changed, 231 insertions(+), 1 deletion(-) diff --git a/docs/Development/IMPLEMENTATION_PLAN.md b/docs/Development/IMPLEMENTATION_PLAN.md index 2087ec1..52f22da 100644 --- a/docs/Development/IMPLEMENTATION_PLAN.md +++ b/docs/Development/IMPLEMENTATION_PLAN.md @@ -43,6 +43,7 @@ | TASK-2026-020 | `[x]` | Парсер карт и артов с официального сайта | DeepSeek: анализ и реализация | идемпотентность 0 diff; `validate` не запускался | | TASK-2026-021 | `[!]` | Login по референсу: 2D-арт и неоновый UI | DeepSeek: C1–C9, Tab/Enter/Esc; ждёт приёмки | EditMode 60/60; `SCENE_SMOKE success=True`; standalone собран; ручная — пользователь | | TASK-2026-022 | `[!]` | Lobby по референсу: дашборд, заглушки, сцена Community | DeepSeek: C1–C11 реализованы; ждёт ручной приёмки | EditMode 62/62; `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone; ручная — пользователь | +| TASK-2026-023 | `[ ]` | DeckBuilder: один экран, мультифильтры и список колоды | DeepSeek: анализ и план готовы; реализация ожидает | не выполнена | Новые задачи добавляются в конец файла отдельными разделами. Не используй один раздел для нескольких независимых задач. @@ -2343,6 +2344,233 @@ HUD с номером хода и фазовой шкалой, компактн - **Skill обновлён:** не требуется; правила и архитектура не менялись. - **Git:** не коммитилось. +--- + +### TASK-2026-023 — DeckBuilder: один экран, мультифильтры и список колоды + +- **Статус:** `[ ]` +- **Создано:** 2026-10-31 +- **Анализ:** DeepSeek выполнен +- **Реализация:** не начата +- **Проверка:** не выполнена +- **Затронутые системы:** `Runtime/UI/DeckBuilderView.cs`, + `Runtime/UI/CardImageService.cs`, `Localization.cs`, EditMode-тесты. + Сервер, правила, протокол и YAML не меняются. + +#### A. Цель и требования + +Переделать декбилдер по решениям пользователя от 2026-10-31: + +1. **Один экран** вместо двух: слева коллекция, справа панель, которая + переключается между «Мои колоды» и «Колода» при входе в редактор. +2. **Мультивыбор фильтров** по клану, грейду и триггеру в модальном + оверлее; выбранные значения подсвечены, есть «Применить» и «Сбросить». +3. **Корректный список колод** справа: имя, `50/50`, `T 16/16`, формат, + распределение по грейдам, бейдж валидности, подсветка открытой колоды. +4. **В редакторе** справа вместо списка колод — карты этой колоды: превью + **только иллюстрации** карты (без рамки и текста, без искажений), имя, + количество; сортировка **грейд → имя**; группировка по `nameId`. +5. Live-валидация 50/16/4; «Сохранить» и «В бой» активны только для + валидной сохранённой колоды. +6. Поведение сохранения, создания, удаления, крафта и разбора не меняется. +7. Геймплей и визуальную приёмку проверяет пользователь. + +Критерии готовности: + +- переключение «список колод ⇄ колода» не пересоздаёт сцену и не теряет + выбранные фильтры; +- мультивыбор клана/грейда/триггера реально фильтрует коллекцию и + отображается в сводке; +- в списке колоды одна строка на карту (`nameId`), превью — иллюстрация + без растяжения, порядок грейд → имя; +- список колод показывает валидность и счётчики, открытая колода + подсвечена; +- существующие EditMode-тесты и смоуки проходят. + +#### B. Текущее состояние + +- `DeckBuilderView` (1435 строк) строит два полноэкранных режима + (`DeckList` и `DeckEditor`) с отдельными топбарами и двумя гридами + коллекции; переключение — `ShowEditor`/`BackToList`. +- Правая колонка фиксирована на 300 px: в списке — ряды 76 px + (`имя`, `N/50 · classic`), в редакторе — ряды 64 px + (превью 36×50, `G`, имя, `×N · триггер`). +- Колода хранится как список `printingId`; в редакторе группируется по + `printingId` и сортируется по нему же. Одна карта в разных принтах даёт + две строки, хотя лимит 4 копии считается по `nameId`. +- Фильтры — модальный оверлей: одиночные значения (клан, грейд, триггер), + выбранное состояние не подсвечивается, сводка показывает по одному + значению. +- `CardImageService.Apply` ставит `preserveAspect = false`: арты 350×511 + растягиваются в область 174×112 (сетка) и 36×50 (список). +- Валидация выполняется только при сохранении; кнопки активны всегда. +- Тестов на фильтрацию/сортировку нет; `ClientSmokeTests` только создаёт + `DeckBuilderView`. + +Что сохранить: + +- загрузку коллекции/каталога/колод и контракты `MetaService`; +- лимиты 50/16/4 и правила добавления/удаления; +- оверлей карты (ПКМ), крафт/разбор; +- сцена `DeckBuilder` и переходы `SceneFlow`; +- 3D-окружение сцены не трогать в этой задаче. + +#### C. Чек-лист изменений + +- [ ] **C1. `MODIFY` `Runtime/UI/CardImageService.cs`** — превью + иллюстрации. + - `ApplyIllustration(Image, imageKey, fallback)`: спрайт из верхней части + карты — `Rect(0, h * 0.41, w, h * 0.59)` для 350×511 (иллюстрация до + полосы флейвора), с кешем по `imageKey`. + - `preserveAspect = true`; выравнивание — центральное; при отсутствии + арта — процедурный fallback без обрезки. + - Полный арт (`Apply`) не меняется: он нужен карточке и 3D-картам. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: нет. + +- [ ] **C2. `MODIFY` `Runtime/UI/DeckBuilderView.cs`** — один экран. + - Убрать `_listView`/`_editorView` и `BackToList`; оставить один корень + `DeckBuilderScreen`: топбар (назад в Lobby, заголовок, фильтры, + сброс, статус) и тело (коллекция + правая панель). + - Правая панель: `DeckListPanel` и `DeckPanel` (карты колоды), видимость + переключается; при открытии колоды — `DeckPanel`, кнопка «К списку + колод» возвращает `DeckListPanel`. + - Ширина правой панели 380 px; содержимое — без пересоздания сцены. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C1, C3, C4. + +- [ ] **C3. `MODIFY` список колод.** + - Строка: имя, `N/50`, `T N/16`, формат (`Classic`, локализовано), + распределение `G0…G3`, бейдж «Готова / Не готова». + - Валидность считать локально (50 карт, 16 триггеров, ≤4 по `nameId`). + - Подсветка открытой колоды; кнопка «Создать колоду» — над списком. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C2. + +- [ ] **C4. `MODIFY` список карт колоды.** + - Группировать по `nameId`, счётчик — сумма принтов; превью — первая + карта группы. + - Строка 84 px: иллюстрация 64×54 (пропорция 1.18), имя (2 строки), + бейдж `G`, `×N`, триггер. + - Сортировка: `Grade` → `Loc.CardName` (`StringComparer.Ordinal`). + - Клик по строке — убрать одну копию; ПКМ — карточка. Счётчики и + валидация обновляются сразу. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C1, C2. + +- [ ] **C5. `MODIFY` фильтры — мультивыбор.** + - Хранить `HashSet Clans`, `HashSet Grades`, + `HashSet Triggers`; пустой набор = «все». + - Оверлей: группы чипов с подсветкой выбранного, «Все»/«Сбросить», + «Применить» (применяет черновик) и «Отмена» (откатывает). + - Сводка в топбаре: `Клан: RP, Kagero · Ранг: 0, 1 · Триггер: Heal`. + - `MatchesFilter` проверяет вхождение во все активные наборы. + - После применения — пересборка коллекции; счётчики в ячейках + обновляются без полного пересоздания (если возможно). + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C2, C6. + +- [ ] **C6. `MODIFY` фильтрация и сортировка — чистый класс.** + - Вынести в `Runtime/UI/DeckListFilter.cs` (или статический helper): + `Matches(meta, filter)`, `SortDeck(cards, catalog)`, `GroupDeck(...)`. + - Фильтр: наборы клана/грейда/триггера; сортировка колоды: грейд → имя; + группировка по `nameId`. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C4, C5. + +- [ ] **C7. `MODIFY` ячейки коллекции.** + - Иллюстрация через `ApplyIllustration`, область арта с правильной + пропорцией (например, 174×147), без растяжения. + - Показывать `×в колоде` по `nameId`; при достижении лимита 4 или 16 + триггеров — приглушать и не добавлять. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C1, C5. + +- [ ] **C8. `MODIFY` live-валидация.** + - `UpdateStats` дополнить статусом валидности и цветом счётчиков; + «Сохранить», «В бой», «С ботом» — `interactable` только при валидной + сохранённой колоде. + - Ошибки лимитов — в статусе редактора, без модальных окон. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C3, C4. + +- [ ] **C9. `MODIFY` `Runtime/UI/Localization.cs`** — новые ключи. + - «Мои колоды», «К списку колод», «Готова», «Не готова», «Клан: », + «Ранг: », «Триггер: », «Применить», «Отмена», «Все кланы», + «Все ранги», «Все триггеры», «Иллюстрация» и подписи счётчиков. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C2–C5. + +- [ ] **C10. `TEST` EditMode.** + - `DeckListFilter`: мультивыбор клана/грейда/триггера, пустой набор = + все; сортировка грейд → имя; группировка по `nameId` суммирует принты. + - `CardImageService`: обрезка иллюстрации возвращает неполный rect + (проверка по спрайту/текстуре без реального файла — на fallback). + - UI: один экран, переключение панелей, сводка фильтров, бейдж + валидности. + - Существующий `Client_Views_Build` — без изменений ожиданий. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C1–C9. + +- [ ] **C11. `VERIFY` EditMode, smoke, standalone.** + - Копия без `Library`; EditMode; `SCENE_SMOKE`; standalone. + - Ручная проверка: фильтры, список колод, редактор, добавление/удаление, + сохранение, «В бой»/«С ботом», ПКМ-карточка. + - Реализация: не выполнена. Проверка: не выполнена. + - Зависит: C10. + +#### D. Последовательность выполнения + +1. C1 + C6: обрезка иллюстрации и чистые функции фильтра/сортировки/групп. +2. C2: один экран и переключение правой панели. +3. C3–C4: список колод и список карт колоды. +4. C5 + C7: мультифильтры и ячейки коллекции. +5. C8–C9: валидация и локализация. +6. C10–C11: тесты, smoke, standalone, ручная приёмка. + +#### E. Проверки + +- EditMode в копии без `Library`. +- `SceneSmoke.Run`, `RunPlaymat`, standalone-сборка. +- `git diff --check`; нет изменений в `server/`, `content/`, `Vanguard.Rules`. +- Ручная проверка — пользователь. + +#### F. Решения и риски + +**Зафиксировано пользователем (2026-10-31):** + +1. Один экран с двумя панелями. +2. Превью — только иллюстрация карты (без рамки и текста). +3. Фильтры — модальный оверлей с мультивыбором. +4. Триггерный фильтр — тоже мультивыбор. +5. Сортировка карт колоды — грейд → имя; группировка по названию. + +**Риски:** + +- **Границы иллюстрации:** доля 0.59 снята с BT01/TD01 (350×511); если + встретится другой макет карты, полоса флейвора может попасть в кадр. + Константы вынести в одно место и проверить на нескольких сетах. +- **Группировка по `nameId`:** при смешанных принтах в строке показывается + иллюстрация первого; удаление уменьшает суммарный счётчик. +- **Один экран:** легко потерять состояние (открытая колода, черновик + фильтров). Хранить явно и сбрасывать только по действию пользователя. +- **Пересборка грида:** при смене фильтра она неизбежна; не пересобирать + на каждый клик добавления — обновлять счётчики точечно. +- **Валидность:** локальная проверка должна совпадать с серверной + (`DeckValidator`), иначе «Сохранить» включится, а сервер откажет. +- **3D-фон DeckBuilder** остаётся; если позже переведём на 2D, это + отдельная задача. + +**Открытых вопросов, блокирующих старт, нет.** + +#### G. Результат + +- **Реализовано:** — +- **Проверки:** — +- **Не завершено/заблокировано:** — +- **Skill обновлён:** — +- **Git:** — + diff --git a/docs/SESSION-STATE.md b/docs/SESSION-STATE.md index f393879..92d0d8b 100644 --- a/docs/SESSION-STATE.md +++ b/docs/SESSION-STATE.md @@ -375,7 +375,9 @@ client/Assets/Plugins/Vanguard.Shared + MessagePack (C10). EditMode 60/60, `SCENE_SMOKE success=True`, standalone собран. **TASK-2026-022 — Lobby по референсу: реализован C1–C11, ждёт ручной приёмки.** EditMode 62/62, `SCENE_SMOKE`, `PLAYMAT_SMOKE`, standalone - собраны и запущены. После приёмки — **TASK-2026-019** (загрузочная + собраны и запущены. **TASK-2026-023 — DeckBuilder (один экран, + мультифильтры, список колоды): анализ и план готовы**, реализация — + следующим проходом. После приёмки — **TASK-2026-019** (загрузочная сцена, fade, кадр без покадровых аллокаций). 2. **TASK-2026-001 — ручная проверка пользователем** (C10): draw, call, ride, move/swap, guard, trigger, drive/damage, retire, search, открытие скрытого