Решили: точка 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.