Решили: точка A удара (кончик оружия, от которого строится форма) снимается не только скрабом
свинга, но и лениво — по запросу, если под текущий взмах снимка ещё нет. Один владелец на оба
входа: UnitView.CaptureStrikeOrigin().
Почему: консоль ругалась hit-form-origin:relic.assassin — «форма удара строится от КОРПУСА
бьющего, а не от оружия». Причина не в контенте: клип атаки размечен StrikeStart/StrikeEnd,
оружие в хвате есть, кончик у него есть. Причина в том, что у Убийцы удар из тени идёт вне
очереди (EmpowerNextAttackComponent._recastImmediately): замах ускорен вдвое и садится на
телеграф-пол, а урон приходит тем же тиком, что и старт свинга. Между OnAttackStarted
(где растёт _swingSerial) и событием урона не проходит ни одного кадра показа — скрабу нечего
листать, и снимать точку A было негде. Номер взмаха уже новый, снимка под него нет,
TryGetStrikeOrigin отвечает «нет» — и форма честно деградирует на корпус.
Поза на момент запроса для такого удара честна: весь свинг уложился в кадр, клинок ещё там, где ударил. Для обычного кита ленивая ветка не срабатывает вовсе — там снимок сделан на замахе.
Грабли: первый диагноз был неверен и стоил лишнего захода. _windupShare: 0 в данных кита
прочиталось как «нулевой замах», хотя это ветка «долю не задавали, считай по клипу»
(AttackTiming.WindupTicksFor), и она всё равно клампится снизу в SimConstants.MinWindupTicks.
Нулевого замаха у кита не бывает. Правку по этой посылке (снимать точку A в else-ветке
OnAttackStarted) откатили: она лечила бы состояние, которого нет.
Отвергнута и вторая альтернатива — снимать точку A безусловно на OnAttackStarted. Там поза ещё
прошлого кадра (конец прошлой атаки или стойка), то есть у нормального кита точка уехала бы назад
во времени ради случая, который его не касается. Ленивый снимок трогает ровно тех, кому не хватило
кадров.
Дефекты strike-body / strike-source / strike-tip остались на месте: «нечем ударить» и
«не успели посмотреть» — разные болезни, и первая обязана кричать по-прежнему.
Владелец правды: поведение — <remarks> у UnitView.TryGetStrikeOrigin и
UnitView.CaptureStrikeOrigin; последствие для формы — комментарий ветки деградации в
CombatPresenter.SpawnHitForm; тайминг замаха — AttackTiming.WindupTicksFor.