Решили: вспышка защиты играет на ЛЮБОЕ поглощение щитом (shieldAbsorbed = ShieldDamage > 0), а
не только на полный блок (HpDamage <= 0). Это обычная вспышка тела через _FlashAmount, той же
яркости, что и у попадания, — просто перекрашенная в золото --gm-color-combat-block-flash (#FFCC33).
UI защиты (полоса, цифра поглощённого) остаётся синим.
Почему: пользователь трижды сказал «визуал не работает ДО активки», и это подтвердилось живой
трассой боя bone-vs-bone на реальных ассетах. Каждый удар до активки — ЧАСТИЧНЫЙ блок: щит Оплота 50
гасит 50, но ~14 всё равно проходит в HP (авто-атака 109 → ~64 после брони 70). Значит
HpDamage <= 0 ложно на каждом ударе, и завязанная на него вспышка молчала. Только активка
«Решительный удар» ослабляет цель на 30%, входящий падает ниже щита, удар гасится целиком
(hp=0) — и вспышка впервые срабатывала. Отсюда «работает только после активки». Баг жил ещё с
исходного синего варианта: та же завязка на полный блок.
Грабли — три моих промаха на этой задаче, все про НЕ ТУДА:
- Взяла шире просьбы: перекрасила роль защиты целиком, утащив в золото полосу и цифру (просили только «на юните»).
- Изобрела два механизма подряд — HDR-флар (пересвет, отвергнут), потом затемнение тела с отдельным
тинтом части-щита. Оба — сложная надстройка вместо простого: взять исходную вспышку и перекрасить.
Всё снято, шов
IUnitBodyVisualвернулся к одному тинту. - Диагностировала «по ощущению» вместо замера, хотя пользователь прямо указал, где искать. Причина
нашлась за один прогон трассы:
SimEnvironment+OnDamageDealt, логShieldDamage/HpDamageпо каждому удару. Надо было начать с этого.
Владелец правды: CombatPresenter.HandleDamageDealt (условие shieldAbsorbed),
CombatColorPalette.BlockFlash, UI/Theme/tokens.semantic.uss (роли защиты и вспышки),
трасса воспроизводится через SimEnvironment в headless-прогоне.