Решили: CombatEvent.UnitDied рассылается всем живым юнитам (труп в рассылке остаётся), а проверка
«мой ли это скелет и близко ли он упал» живёт в пассивке НОСИТЕЛЯ —
BoneCollectorComponent на Некроманте.
Почему: пассивка реагирует на событие, в котором её носитель не участвует, а прежняя доставка отдавала смерть только трупу. Из трёх вариантов выбран третий:
- Ловить смерть любого юнита — так была написана карточка. Отвергнуто вердиктом Макса: кости за чужие смерти кормят некроманта чужой работой, и пассивка перестаёт читаться как его собственная.
- Повесить компонент на самого скелета — событие тогда приходит трупу штатно, ядро не меняется. Я сделала так и получила замечание: это костыль. Способность хозяина превращалась в свойство призыва, кит скелета начинал знать про механику Некроманта, а его будущие улучшения («Лавина костей», «Костяная защита») не смогли бы её менять — они висят на хозяине, а поведение уехало в тело.
- Рассылать событие и фильтровать у носителя. Дороже на N диспатчей за смерть, зато способность остаётся там, где ей место, и условия («мой призыв», «от этой активки», «в радиусе») читаются в одном месте — в её собственном компоненте.
Существующий потребитель события (перенос «Метки охотника») от рассылки не страдает: он сверяет, что умер именно его носитель, и на чужие смерти выходит сразу.
Грабли: «мёртвым зрителям смерть не интересна» — фильтр в рассылке обязателен, иначе труп с пассивкой собирал бы кости с чужих смертей уже будучи мёртвым. Второе: разгон числа призывов заведён ОТДЕЛЬНЫМ полем от разгона залпа, хотя арифметика одна — призыв применяется вне цикла нагрузки, и общее поле означало бы, что «залп из трёх стрел» множит и скелетов.
Владелец правды: CombatSimulation.DrainEventQueue, BoneCollectorComponent.cs,
AbilityData.ResolveSummonCount, карточка gdd/relics/the-bonewright.