Решили: «чем исполнен приём» — поле навыка (AbilityData.CastSource: Auto / OffHand / BothHands /
Shield / WholeBody / None), а лента боя возит СAМО определение способности payload’ом, как уже возит
EffectData. Показ переводит объявленную РОЛЬ в части конкретного тела (CastGlowMask →
IUnitPartLookup).
Почему: событие каста доезжало до показа как один casterId, поэтому телеграф светил всем
одинаково — щит-бэш зажигал клинок. Отвергнуто:
- вывести природу приёма из механики (есть урон → удар оружием, есть канал → бафф) — это та же эвристика, которую мы только что выпилили из типа предмета: приём с уроном бывает и пинком;
- везти по ленте узкий слепок (enum источника вместо определения) — дешевле на байтах, но показу
от навыка нужно не только это (школа, цвет, природа), и слепок пришлось бы расширять каждый раз;
прецедент с
EffectDataуже показал, что ссылка на неизменное определение здесь достаточна; - резолвить часть в симуляции — сим не знает и не должен знать про части тела и свечение.
Роль названа в терминах боя, а не рига (OffHand, а не «узел Grip слева»): у дуалиста это второй
кинжал, у щитовика — щит, у монаха — кулак. Один и тот же навык ложится на любую расстановку.
Грабли: запрос «источник удара ЭТОЙ рукой» падал в фолбэк «любое оружие», и у бойца с мечом
справа и щитом слева удар левой светил меч из другой руки. Тест поймал сразу; правило теперь такое:
явный адрес строгий, терпим только Auto — и он обязан быть терпимым, иначе левша (оружие лишь в
левой) остался бы без телеграфа.
Владелец правды: CastSource.cs (перечень ролей), CastGlowMask.cs (перевод роли в части),
BattleTape.RecordAbility/GetAbility (доставка), тесты CastGlowMaskTests (перевод на четырёх
расстановках) и TapeCastPayloadTests (определение доезжает до показа и не путается между кастами).