Счёт убийств Некромантии переехал из XML в код
Чинит баг: скилл не засчитывал часть убийств зомби. Причин было две, и обе
закрываются одним ходом.
ПРИЧИНА 1: ОДИН КЛАСС - НЕ ВСЕ ЗОМБИ. Счёт висел append-ом на zombieTemplateMale.
Человекоподобные покрыты (effect_group у entity_class наследуется через extends, и
все шаблоны зомби сходятся к Male), но пять зомби-ЗВЕРЕЙ наследуют животную ветку
и до него не доходят вовсе:
animalZombieBear extends animalBear
animalZombieBoar extends animalBoar
animalZombieDog extends animalWolf
animalZombieVulture extends animalTemplateHostile
animalZombieVultureRadiated extends animalZombieVulture
Убийство зомбопса, зомбомедведя, зомбокабана и зомбоворона не считалось никак.
Вороны попадаются постоянно - это и была бОльшая часть "не всегда засчитывает".
ПРИЧИНА 2: target="other" - БУКВАЛЬНЫЙ УБИЙЦА. Триггер onOtherKilledSelf с
требованием EntityTagCompare tags="player" начислял только за убийство своей
рукой. Робомолот, кровотечение и питомцы требование не проходят, хотя опыт игрок
за них получает: ваниль определяет получателя не по убийце, а по DamageSource - в
EntityAlive.AwardKillXPServer, где для этого есть обращение к BuffClass (DoT) и
отдельный флаг bTrapKillXP (ловушки).
Требование было ОДНО на оба эффекта, поэтому недосчитывался и
necroZombieKillsCVar, а это урон Ножа некроманта (items.xml: Damage = CVar / 10).
Баг тихо занижал ещё и нож.
РЕШЕНИЕ: Postfix на EntityPlayer.AddKillXP. Этот метод вызывается ровно из одного
места во всей сборке - из AwardKillXPServer, то есть уже ПОСЛЕ того, как ваниль
разобрала DamageSource и решила, чей это фраг (проверено сканированием IL).
Мы не повторяем её логику и не угадываем владельца турели или автора
кровотечения - забираем готовый ответ. Наш счёт совпадает с опытом на экране по
построению, включая случаи, о которых мы не подумали.
ФИЛЬТР ПО ТЕГУ zombie, А НЕ ПО КЛАССУ. Проверено по данным: zombieBiker,
zombieArlene, zombieBoe, zombieSpider несут "entity,zombie,...", зомби-звери -
"entity,animal,zombie,zombieAnimal,...". Тег есть у всех. Работает это благодаря
тому, что Tags у entity_class НЕ наследуется через extends: каждый реально
спавнящийся зомби выписывает теги сам, а безтеговые шаблоны не спавнятся. Тег
переживёт и новых зомби из патчей игры, и чужие моды.
Повышение уровня воспроизводит MinEventActionAddProgressionLevel.Execute шаг в
шаг по его IL: GetProgressionValue, Level+1, кламп по MaxLevel, для крафтового
скилла AddCraftingSkillNotification и HandleCheckCrafting, затем
bProgressionStatsChanged и bPlayerStatsChanged под !isEntityRemote.
HandleCheckCrafting легко выбросить и дорого потерять - без него рецепты рискуют
не заметить, что открылись. Уведомление с _bAddOnlyIfNotExisting=true, чтобы в
орду не всплывал тост на каждый труп.
Config/entityclasses.xml: append снят ЦЕЛИКОМ, на его месте комментарий, почему
возвращать нельзя - XML-триггер рядом с патчем засчитает убийство своей рукой
ДВАЖДЫ. Это единственная ловушка переезда.
Сборка: 0 ошибок (4 прежних MSB3277). Проверено рефлексией по собранной DLL:
атрибут нацелен верно, перегрузка AddKillXP ровно одна, имя параметра killedEntity
совпадает с ванильным (Harmony инжектит по имени - опечатка дала бы молчаливо
неработающий патч), PatchAll подхватывает файл сам.
НЕ ПРОВЕРЕНО В ИГРЕ. Отдельно: питомцы НЕ гарантированы - патч следует решению
ванили, а не принимает его. Если ваниль не зачисляет владельцу убийство
питомцем, не зачислит и он; это отдельная работа, а не ошибка здесь.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e890999391
commit
229b436420
+25
-13
@@ -1,17 +1,29 @@
|
||||
<config>
|
||||
<!-- Step 1: lifetime zombie kill counter.
|
||||
zombieTemplateMale is the root template every zombie entity_class extends
|
||||
(directly, or indirectly via zombieTemplateShort), so patching it here covers
|
||||
every zombie variant in the game without listing them individually. -->
|
||||
<append xpath="/entity_classes/entity_class[@name='zombieTemplateMale']">
|
||||
<effect_group>
|
||||
<requirement name="EntityTagCompare" target="other" tags="player"/>
|
||||
<triggered_effect trigger="onOtherKilledSelf" action="ModifyCVar" target="other" cvar="necroZombieKillsCVar" operation="add" value="1"/>
|
||||
<!-- "Некромантия" skill: +1 level per zombie kill, capped by its own max_level.
|
||||
See progression.xml for why this drives the skill instead of reading books. -->
|
||||
<triggered_effect trigger="onOtherKilledSelf" action="AddProgressionLevel" target="other" progression_name="craftingNecroNecromancy" level="1"/>
|
||||
</effect_group>
|
||||
</append>
|
||||
<!-- СЧЁТ УБИЙСТВ ПЕРЕЕХАЛ В КОД 2026-09-16. Здесь СОЗНАТЕЛЬНО ничего нет, и вернуть это
|
||||
обратно нельзя - см. HarmonySrc/NecromancyKillCreditPatch.cs.
|
||||
|
||||
Тут стоял append на zombieTemplateMale с двумя onOtherKilledSelf-эффектами
|
||||
(ModifyCVar necroZombieKillsCVar и AddProgressionLevel craftingNecroNecromancy) под общим
|
||||
требованием EntityTagCompare target="other" tags="player". Он был сломан дважды:
|
||||
|
||||
1. Один класс - не все зомби. Пять зомби-ЗВЕРЕЙ наследуют животную ветку и до
|
||||
zombieTemplateMale не доходят вовсе (animalZombieBear extends animalBear,
|
||||
animalZombieBoar extends animalBoar, animalZombieDog extends animalWolf,
|
||||
animalZombieVulture extends animalTemplateHostile, animalZombieVultureRadiated).
|
||||
Убийство зомбопса, зомбомедведя, зомбокабана и зомбоворона не считалось никак.
|
||||
2. target="other" - это БУКВАЛЬНЫЙ убийца, а не тот, кому ваниль зачла убийство.
|
||||
Робомолот, кровотечение и питомцы требование tags="player" не проходят, хотя опыт
|
||||
игрок за них получает: ваниль определяет получателя по DamageSource, в
|
||||
EntityAlive.AwardKillXPServer.
|
||||
|
||||
Требование было одно на оба эффекта, поэтому вместе со скиллом недосчитывался и
|
||||
necroZombieKillsCVar - то есть занижался урон Ножа некроманта (items.xml: Damage =
|
||||
necroZombieKillsCVar / 10).
|
||||
|
||||
ОБА эффекта теперь делает Postfix на EntityPlayer.AddKillXP - единственной точке, где
|
||||
ваниль уже решила, чей это фраг. ЕСЛИ ВЕРНУТЬ ЭТОТ append НА МЕСТО, убийство своей рукой
|
||||
будет засчитано ДВАЖДЫ: и здесь, и в патче. Ровно это и проверять, если уровень вдруг
|
||||
начнёт расти по два за труп. -->
|
||||
|
||||
<!-- "Зомбособака" (Zombie Dog pet): BACKLOG.md item 3. Extends the vanilla hostile
|
||||
animalZombieDog (same prefab/physics/sounds - a real zombie dog model, not a reskinned
|
||||
|
||||
Reference in New Issue
Block a user