Решили: у взмаха есть НОМЕР, и назначает его сим — UnitView.OnAttackStarted (событие ленты
AttackStarted, которое AutoAttackSystem шлёт на каждый вход в свинг, включая мгновенный). Всё, что
случается «раз за взмах» — снятие точки A и заказ дуги, — сверяется с этим номером. Плюс размеры форм
приведены к росту юнита: укол 1.1 → 0.3 роста, линия-всполох перестала брать длину из дистанции
выстрела и получила свою — 0.45. У дуги за клинком появилась собственная яркость
(SwingArcBrightness = 0.35 от свечения каста).
Почему: точка A сбрасывалась при ПЕРЕХОДЕ в фазу замаха. У кита, чей следующий замах начинается в тот же тик, где кончился прошлый удар, фаза не прерывается ни на кадр — сброса не происходит, и хук начала взмаха, стоящий на «точки A ещё нет», зовётся ровно один раз за бой. Дуга появлялась на первой атаке и больше никогда.
Первое решение было снято в тот же день. Оно опознавало новый взмах по ОТКАТУ скраба назад
(IsNewSwing с порогом): клип свинга всегда идёт вперёд, значит упавшее время — следующий удар. На
практике дуга пропадала и «иногда появлялась», а Макс назвал подход костылём — и справедливо: показ
угадывал по порогу событие, о котором сим сообщает прямо. Показ не имеет права выводить «начался новый
взмах» из собственного состояния: ни фаза, ни скраб не являются этим событием, они лишь его следы.
Функция и её тест удалены, флаг _hasStrikeOrigin — тоже: сравнение двух номеров не нуждается в том,
чтобы кто-то вовремя что-то сбросил.
Размеры: при росте юнита 0.694 в мире укол рисовался длиной 0.6–1.5 (полтора юнита), а всполох брал длину «вся дистанция выстрела» × 2 — с четырёх единиц полёта это восемь единиц, линия через полэкрана. «Откуда прилетело» говорит НАПРАВЛЕНИЕ A→B, а не размер, поэтому длина всполоха стала своим числом. Отвергнуто: клампить длину потолком — потолок прячет правило вместо того, чтобы его назвать.
Сказано: «Взмах (след за мечом) срабатывает но почему-то лишь на ПЕРВУЮ АТАКУ», «И сделай плз его менее ярким тоже», «И заодно “длину” разреза юнита при колющих и болте понизь. Оно должно быть максимум в ширину юнита (это просто пример, а не реальное ограничение, пример длины при обычном хорошем уроне!), а то щас слишком гигантская», и после первой попытки — «После первой атаки все еще пропадает (а потом иногда появляется?) всполох за мечом. Сделай ЧИСТО, БЕЗ КОСТЫЛЕЙ, ок?» (2026-08-04, сессия 06e45474).
Грабли: серп режущего остался 1.4 роста — вдвое выше юнита; его Макс не трогал, и трогать без
вердикта нельзя. Число названо здесь, чтобы следующий заход не считал его выверенным. Канал
(AttackPhase.Channel) получает ОДНУ дугу на вход в поток, а не по одной на тик: сим шлёт начало атаки
один раз, и это осознанно — у вращения нет отдельных взмахов.
Владелец правды: UnitView._swingSerial (номер взмаха) и UnitView.TrackStrikeWindow,
AutoAttackSystem.NotifyAttackStarted как его источник, HitFormArchetypeConfig (размеры форм).