ИИ питомцев переписан, добавлен Дух крысы, пороги разнесены по шкале
Работа по указаниям 2026-09-18. В релиз пока не выходит. НОВЫЙ ПИТОМЕЦ "Дух крысы" (necroRatSpirit), Некромантия 3 (60 убийств): модель зомбоволка в масштабе 0.28, урон 5, кроличьи звуки. Сам не нападает никогда, держится справа-сзади в двух блоках, упёршись в препятствие проходит СКВОЗЬ него и блоков не ломает. Укус замедляет, оставляет метку духа (видна на компасе, +25% получаемого урона) и рвёт жилу. Обгрызая труп, лечится. СВОЯ ЗАДАЧА ИИ. Задачи "иди за сущностью" в игре нет вовсе - проверены все 32 типа EAI*. Написана NecroFollowOwnerTask по образцу EAIApproachSpot: сектор "3-6 часов" от хозяина, FindPath с canBreak:false, проход сквозь препятствие через Entity.IsStuck. Вешается в рантайме, минуя Type.GetType. ПРИКАЗ АТАКОВАТЬ. Повторное применение свитка при живом питомце натравливает его на цель под прицелом: EntityPlayerLocal.HitInfo + ItemActionAttack. GetEntityFromHit. Торговцы и игроки отсеяны. Нет цели - "Нет цели для атаки". ЗОМБОЖИВОТНЫЕ ПРИВЕДЕНЫ К ТОМУ ЖЕ ОБРАЗЦУ. Сняты BreakBlock, Territorial, ApproachSpot, Wander, BlockingTargetTask и поедание трупов; цель они больше не выбирают сами. Лестница урона 20/35/45/60 плюс расчленение у Пса, Медведя и Волка. Кровотечение всем, метка и ослабление - только у крысы. УБИЙСТВА ПИТОМЦЕМ ЗАСЧИТЫВАЮТСЯ ВЛАДЕЛЬЦУ, включая добивание кровотечением. Префикс на AwardKillXPServer подменяет убийцу владельцем; для смерти от баффа заведена память укусов, потому что в DamageSource от баффа нет того, кто его наложил. Зомби под Камнем духов это не задело - решение от 17.09 в силе. ГРИФ откачен на летающую ветку EntityVulture и переименован в Могильного стервятника: модель наконец соответствует имени. Держится у игрока сам, через собственный механизм "дома" (setHomeArea), на время погони дом отвязывается. Попытка натянуть птичий префаб на наземный класс провалилась и записана - так делать нельзя. ПРОЧЕЕ: призрачный вид распространён с торговцев на питомцев (у Пса, Медведя и Волка выключен по указанию), у Пса светятся фиолетовые глаза, белая иконка книги снята со всех свитков призыва, "Жуки Властелина" переименованы в "Рой фараона" на всех 13 языках. ПОРОГИ: крыса 60, стервятник 500, пёс 1300, медведь 2000, волк 4000. ИСПРАВЛЕНО ПО ХОДУ ИГРОВЫХ ПРОВЕРОК: питомцы не призывались обычным кликом (AnimWait требовал удержания), отзыв срабатывал не с первого раза (автомат состояний ItemActionSpawnEntity), крыса проваливалась сквозь мир (IsStuck отключает и пол), питомец подбрасывал хозяина (коллайдеры разводились до появления модели). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
15c59dd37a
commit
d97f83e972
+161
-48
@@ -58,9 +58,41 @@
|
||||
originally had before its own rework - see necroMeleeHandZombieDog in items.xml. -->
|
||||
<property name="HandItem" value="necroMeleeHandZombieDog"/>
|
||||
|
||||
<property name="AITask-3" value="ApproachAndAttackTarget" data="class=EntityZombie,20"/>
|
||||
<property name="AITarget-1" value="SetAsTargetIfHurt" data="class=EntityZombie"/>
|
||||
<property name="AITarget-4" value="SetNearestEntityAsTarget" data="class=EntityZombie,22,20"/>
|
||||
<!-- ИИ ПЕРЕПИСАН 2026-09-18 ПОД ОБРАЗЕЦ ДУХА КРЫСЫ, прямое указание: "поведение
|
||||
других призванных животных зомби тоже подгони под крысу. По сути это те же
|
||||
крысы, но размер модели оригинальный, урон нарастает от зомбособаки до
|
||||
зомбоволка". Правка стоит здесь, у necroZombieDog, и этого достаточно:
|
||||
Зомбомедведь, Зомбоволк и Зомбогриф расширяют именно его и унаследуют всё.
|
||||
|
||||
БЫЛО (и разобрано в BACKLOG.md 18.09 как "питомцы унаследовали ИИ враждебной
|
||||
твари"): AITask-3 переопределял только погоню, а от animalZombieDog оставались
|
||||
BreakBlock (грыз базу игрока), Territorial (держался точки призыва, а не
|
||||
хозяина), ApproachSpot и Wander (бродил сам по себе), BlockingTargetTask и
|
||||
SetNearestCorpseAsTarget (бросал хозяина ради ближайшего трупа), а
|
||||
SetNearestEntityAsTarget заставлял его самому лезть в драку в 22 метрах.
|
||||
|
||||
СТАЛО, ровно как у крысы:
|
||||
- AITask-3 пустой обрывает перебор, поэтому BreakBlock/Territorial/ApproachSpot/
|
||||
Wander не грузятся вовсе (CopyPropertiesFromEntityClass идёт по индексам и
|
||||
встаёт на первом пустом);
|
||||
- AITarget-2 пустой так же убирает BlockingTargetTask и поедание трупов;
|
||||
- цель НЕ ВЫБИРАЕТСЯ самостоятельно никогда: SetNearestEntityAsTarget больше
|
||||
нет. Цель приходит только приказом игрока (PetCommandPatch.cs);
|
||||
- AITarget-1 остаётся только как ответ на удар, и список классов без
|
||||
EntityPlayer: питомец огрызается на зомби и враждебных зверей, но никогда на
|
||||
хозяина;
|
||||
- class=EntityAlive в AITask-1 - это разрешение задаче подхватить ту цель,
|
||||
которую ей ДАЛИ, а не "бей всё живое" (EAIApproachAndAttackTarget.CanExecute
|
||||
сверяет тип цели со списком и без совпадения не запускается). Кого можно
|
||||
назначать, решает PetCommandPatch.cs, и торговец там отсеян.
|
||||
|
||||
Задача следования (NecroFollowOwnerTask) вешается в рантайме из SummonPatch.cs -
|
||||
всем, у кого UsesFollowTask, то есть теперь и этим четверым. -->
|
||||
<property name="AITask-1" value="ApproachAndAttackTarget" data="class=EntityAlive,0"/>
|
||||
<property name="AITask-2" value="Look"/>
|
||||
<property name="AITask-3" value=""/>
|
||||
<property name="AITarget-1" value="SetAsTargetIfHurt" data="class=EntityZombie,EntityEnemyAnimal"/>
|
||||
<property name="AITarget-2" value=""/>
|
||||
</entity_class>
|
||||
</append>
|
||||
|
||||
@@ -156,6 +188,9 @@
|
||||
<property name="PrefabCombined" value="true"/>
|
||||
<property name="PhysicsBody" value="bear"/>
|
||||
<property name="Mass" value="600"/>
|
||||
<!-- 80% от ванильного, указание 2026-09-18. У animalZombieBear своего SizeScale нет,
|
||||
то есть ванильный размер - единица, отсюда 0.8. -->
|
||||
<property name="SizeScale" value="0.8"/>
|
||||
<property name="Tags" value="entity,animal,bear"/>
|
||||
<!-- FIXED 2026-08-30 (user report: "зомбомедведь лает" - swapping the Prefab only
|
||||
changes the visible model, sound properties are a totally separate set of
|
||||
@@ -173,7 +208,7 @@
|
||||
<property name="SoundStepType" value="animalhvystep"/>
|
||||
<!-- Real vanilla hand item (claw damage 60, vs. the Dog's own bite at 8) - reused
|
||||
as-is, not customized further (no slow debuff etc. - not asked for). -->
|
||||
<property name="HandItem" value="meleeHandAnimalZombieBear"/>
|
||||
<property name="HandItem" value="necroMeleeHandZombieBear"/>
|
||||
<effect_group name="Base Effects">
|
||||
<!-- 1500 is a guess between the Dog's 200 and real animalZombieBear's own 4000 -
|
||||
a tough pet, not necessarily boss-tier tanky. Say if it should be higher/lower. -->
|
||||
@@ -189,7 +224,8 @@
|
||||
<property name="PrefabCombined" value="true"/>
|
||||
<property name="PhysicsBody" value="AWolf"/>
|
||||
<property name="Mass" value="180"/>
|
||||
<property name="SizeScale" value="1.4"/>
|
||||
<!-- 1.12 = 80% от ванильных 1.4 у animalDireWolf, указание 2026-09-18. -->
|
||||
<property name="SizeScale" value="1.12"/>
|
||||
<property name="Tags" value="entity,animal,wolf"/>
|
||||
<!-- FIXED 2026-08-30, same oversight as the Bear above (see its comment) - real
|
||||
animalDireWolf's own sound set. -->
|
||||
@@ -202,7 +238,7 @@
|
||||
<property name="SoundGiveUp" value="wolfdiregiveup"/>
|
||||
<property name="SoundStepType" value="animalpawstep"/>
|
||||
<!-- Real vanilla hand item (bite damage 60, vs. the Dog's own 8). -->
|
||||
<property name="HandItem" value="meleeHandAnimalDireWolf"/>
|
||||
<property name="HandItem" value="necroMeleeHandZombieWolf"/>
|
||||
<effect_group name="Base Effects">
|
||||
<!-- 1200 is a guess between the Dog's 200 and real animalDireWolf's own 3000 -
|
||||
slightly below the Bear, faster/leaner theme. Say if it should be different. -->
|
||||
@@ -211,56 +247,133 @@
|
||||
</entity_class>
|
||||
</append>
|
||||
|
||||
<!-- Griffin CONVERTED 2026-08-29 to the same Dog-reskin trick as Bear/Wolf, after the user
|
||||
confirmed live in-game that the animalZombieVulture+Harmony-redirect approach genuinely
|
||||
doesn't work ("летает где-то в небе, и зомби его вообще не интересуют" - flies around
|
||||
doing EntityVulture's own default Wander behavior, never engaging anything). Not worth
|
||||
debugging the Harmony redirect further without another live test cycle - switched
|
||||
straight to the proven-reliable pattern instead, same as Wolf (confirmed working) and
|
||||
Bear (not yet confirmed, same trick).
|
||||
<!-- "Зомбогриф" ОТКАЧЕН 2026-09-18 К ЛЕТАЮЩЕЙ ВЕТКЕ.
|
||||
|
||||
No real griffin exists in this game and a bird's skeleton/rig was flagged as a real risk
|
||||
for reusing necroZombieDog's own quadruped rig (see the removed comment this replaces) -
|
||||
picked animalMountainLion as the substitute model instead of a bird: it EXTENDS
|
||||
animalWolf (Data/Config/entityclasses.xml, confirmed by reading it directly) - the SAME
|
||||
immediate parent animalZombieDog itself extends - almost certainly sharing the exact same
|
||||
quadruped skeleton/rig family the Dog's own model already uses, the lowest-risk pick
|
||||
available (lower risk than the Bear, which comes from a totally different
|
||||
animalBear->animalTemplateHostile lineage). Not a literal griffin visually any more (a
|
||||
mountain lion, not a bird/lion-eagle hybrid) - say if a different substitute or the name
|
||||
itself should change; kept "Зомбогриф"/"Summon Zombie Griffin" as-is for now since
|
||||
renaming would touch items.xml/recipes.xml/Localization.csv too and wasn't asked for. -->
|
||||
История у него длинная, и важно не потерять её конец. До 29.08 он расширял
|
||||
animalZombieVulture и просто бестолково летал ("летает где-то в небе, и зомби его вообще
|
||||
не интересуют") - тогда его перевели на necroZombieDog, то есть сделали наземным со
|
||||
сменённой моделью. 18.09 пользователь заметил результат прямо: "зомбогриф у тебя это серая
|
||||
пума". Попробовали натянуть на тот же наземный класс префаб стервятника - вышло хуже
|
||||
всего: "выглядит жутко, прозрачное только туловище и голова, по земле он ползёт на
|
||||
крыльях". Это и был ответ на висевший с 29.08 вопрос, можно ли подменить ОДИН префаб:
|
||||
нельзя, птичья модель на аниматоре наземного квадрупа не работает.
|
||||
|
||||
Указание: "зомбогрифа откати, пусть ведёт себя как раньше и не делай его прозрачным.
|
||||
Пусть пока бестолково летает как раньше, но с возможностью нацелить его на противника...
|
||||
Потом сделаем грифа как надо. Но потом."
|
||||
|
||||
Поэтому здесь снова ванильная ЛЕТАЮЩАЯ ветка со всем, что к ней прилагается, и это
|
||||
сознательный шаг назад до отдельной работы над ним (замысел разведдрона - BACKLOG.md).
|
||||
|
||||
ЧТО ПРИШЛОСЬ СНЯТЬ И ПОЧЕМУ:
|
||||
- EntityFlags и EntityType уходят с "animal,zombie"/"Zombie" на чистое "animal"/"Animal".
|
||||
Иначе EntityAlive.DamageEntity не даст ему бить зомби вовсе: там жёсткое правило, что
|
||||
две сущности с флагом Zombie не могут повредить друг другу. Тот же приём и по той же
|
||||
причине применён к Рою жуков выше.
|
||||
- Tags теряют zombie/hostile, IsEnemyEntity=false, Faction=none - форма "свой игроку",
|
||||
как у всех остальных питомцев.
|
||||
- AITask/AITarget НЕ ЗАДАЮТСЯ ВОВСЕ, и это не упущение: Class="EntityVulture" не
|
||||
использует систему AITask ни в каком виде, у него собственный захардкоженный поиск
|
||||
целей на C# (см. HarmonySrc/SwarmTargetPatch.cs, там это разобрано целиком). Писать
|
||||
сюда задачи - ровно та ошибка, которую уже совершали 28.08 с Роем.
|
||||
|
||||
ЧТОБЫ НЕ АТАКОВАЛ ХОЗЯИНА, он добавлен в SwarmTargetPatch.SpeciesByName: префикс на
|
||||
EntityAlive.SetAttackTarget подменяет игрока ближайшим зомби. Это единственная точка, через
|
||||
которую проходят все цели EntityVulture.
|
||||
|
||||
ПРИКАЗ АТАКОВАТЬ у него остаётся (CommandsAttack в SummonPatch.cs), но с оговоркой:
|
||||
EntityVulture перебирает цели сам, своим циклом, и может сбросить наш приказ. Задачу
|
||||
следования ему НЕ вешаем - она наземная и с полётом только подерётся. -->
|
||||
<append xpath="/entity_classes">
|
||||
<entity_class name="necroZombieGriffin" extends="necroZombieDog">
|
||||
<!-- Real vanilla animalMountainLion's own Prefab/PhysicsBody/Mass/SizeScale. -->
|
||||
<property name="Prefab" value="@:Entities/Animals/Cat/animalMountainLion.prefab"/>
|
||||
<property name="PrefabCombined" value="true"/>
|
||||
<property name="PhysicsBody" value="MountainLion"/>
|
||||
<property name="Mass" value="125"/>
|
||||
<property name="SizeScale" value="1"/>
|
||||
<property name="Tags" value="entity,animal,cat"/>
|
||||
<!-- FIXED 2026-08-30, same oversight as the Bear above (see its comment) - real
|
||||
animalMountainLion's own sound set. -->
|
||||
<property name="SoundRandom" value="mlionroam"/>
|
||||
<property name="SoundAlert" value="mlionalert"/>
|
||||
<property name="SoundHurt" value="mlionpain"/>
|
||||
<property name="SoundDeath" value="mliondeath"/>
|
||||
<property name="SoundAttack" value="mlionattack"/>
|
||||
<property name="SoundSense" value="mlionsense"/>
|
||||
<property name="SoundGiveUp" value="mliongiveup"/>
|
||||
<property name="SoundStepType" value="animalpawstep"/>
|
||||
<!-- Real vanilla hand item (claw damage 22 - lighter than the Bear/Wolf's 60, a
|
||||
faster/leaner theme fitting a big cat rather than a heavyweight brawler). -->
|
||||
<property name="HandItem" value="meleeHandAnimalMountainLion"/>
|
||||
<entity_class name="necroZombieGriffin" extends="animalZombieVulture">
|
||||
<property name="EntityFlags" value="animal"/>
|
||||
<property name="EntityType" value="Animal"/>
|
||||
<property name="Tags" value="entity,animal,vulture"/>
|
||||
<property name="IsEnemyEntity" value="false"/>
|
||||
<property name="Faction" value="none"/>
|
||||
<property name="HandItem" value="necroMeleeHandZombieGriffin"/>
|
||||
<effect_group name="Base Effects">
|
||||
<!-- Real vanilla animalMountainLion's own HealthMax (750) - used as-is, not
|
||||
scaled further, since this pet is meant to be the "fast/agile" one, not the
|
||||
tankiest of the three. -->
|
||||
<!-- У ванильного зомбостервятника 30 HP - для питомца, которого не отозвать до
|
||||
следующего призыва, это ничто. 750 оставлено с прежней, наземной версии. -->
|
||||
<passive_effect name="HealthMax" operation="base_set" value="750"/>
|
||||
</effect_group>
|
||||
</entity_class>
|
||||
</append>
|
||||
|
||||
<!-- "Дух крысы" (Rat Spirit) - питомец начального уровня, указание 2026-09-18. Первый
|
||||
питомец, у которого поведение задано НАМЕРЕННО, а не унаследовано: на нём и отлаживается
|
||||
ИИ питомцев вообще (см. разбор в BACKLOG.md от 2026-09-18).
|
||||
|
||||
МОДЕЛЬ. Extends necroZombieWolf, то есть тот же самый ванильный префаб лютоволка, только
|
||||
SizeScale с 1.4 на 0.28 - "уменьшить в 5 раз". Хитбокс отдельно задавать НЕ НАДО и брать
|
||||
кроличий НЕЛЬЗЯ: коллайдеры в physicsbodies.xml привязаны к костям по имени пути, а риг
|
||||
кролика с волчьим не совпадает (у кролика корпус Hips/LowerBack/Spine1 и голова под
|
||||
Spine2/Neck/Head, у волка Hips/LowerBack/Spine/Spine1/Spine2 и голова под Neck/Neck1/Head)
|
||||
- кроличье тело нашло бы на волчьей модели только таз и ноги, а корпус и голова остались
|
||||
бы вообще без хитбокса. Унаследованный PhysicsBody="AWolf" при этом ужимается сам:
|
||||
Entity.SetScale ставит ModelTransform.localScale, а костяные коллайдеры лежат внутри него.
|
||||
|
||||
ЗВУКИ - кроличьи ("он тоже грызун"). На АТАКУ поставлен rabbitpain: это буквально вопль
|
||||
кролика от боли, и он же остаётся на SoundHurt - крыса вопит и когда кусает, и когда бьют
|
||||
её. Остальные звуки ГЛУШАТСЯ ПУСТЫМИ НАМЕРЕННО: у animalRabbit нет ни roam, ни alert, ни
|
||||
sense, ни giveup, и если их не погасить, крыса унаследует волчьи от necroZombieWolf -
|
||||
ровно те грабли, что дали "зомбомедведь лает" (см. necroZombieBear выше). Дух рыщет молча.
|
||||
|
||||
ИИ. Здесь снято ВСЁ, что питомцы до сих пор тащили от враждебного зомбопса:
|
||||
- нет BreakBlock и BlockingTargetTask - крыса физически не может грызть блоки, и это же
|
||||
продублировано в коде (EAINecroFollowOwner зовёт FindPath с canBreak:false). Упёршись
|
||||
в препятствие, дух проходит СКВОЗЬ него - см. Entity.IsStuck в PetFollowTask.cs;
|
||||
- нет Territorial, ApproachSpot и Wander - крыса не бродит сама, она ходит за хозяином
|
||||
(задача следования добавляется в рантайме из SummonPatch.cs, отдельным классом, потому
|
||||
что задачи "иди за сущностью" в игре нет вовсе - все 32 типа EAI* проверены);
|
||||
- нет SetNearestCorpseAsTarget - она не бросает хозяина ради ближайшего трупа;
|
||||
- AITarget-1 оставлен ТОЛЬКО как ответ на удар, и список классов без EntityPlayer:
|
||||
крыса огрызается на зомби и враждебных зверей, но никогда на хозяина, даже если он
|
||||
заденет её в свалке (прямое указание 2026-09-18).
|
||||
Сама она цель не ВЫБИРАЕТ никогда: SetNearestEntityAsTarget здесь нет, а AITarget-2
|
||||
пустой обрывает перебор (CopyPropertiesFromEntityClass идёт по индексам и встаёт на первом
|
||||
пустом - тем же приёмом ваниль глушит задачи у animalInsectSwarm). Цель приходит снаружи:
|
||||
по команде игрока из PetCommandPatch.cs.
|
||||
|
||||
class=EntityAlive в AITask-1 - это НЕ "бей всё живое" само по себе, а разрешение задаче
|
||||
подхватить ту цель, которую ей дали (EAIApproachAndAttackTarget.CanExecute сверяет тип
|
||||
цели с этим списком и без совпадения просто не запускается). Кого можно назначить целью,
|
||||
решает PetCommandPatch.cs, и торговец там отсеян. -->
|
||||
<append xpath="/entity_classes">
|
||||
<entity_class name="necroRatSpirit" extends="necroZombieWolf">
|
||||
<property name="SizeScale" value="0.28"/>
|
||||
<property name="Mass" value="33"/>
|
||||
<property name="Weight" value="11"/>
|
||||
<property name="Tags" value="entity,animal,rat"/>
|
||||
<property name="HandItem" value="necroMeleeHandRatSpirit"/>
|
||||
|
||||
<property name="SoundRandom" value=""/>
|
||||
<property name="SoundAlert" value=""/>
|
||||
<property name="SoundSense" value=""/>
|
||||
<property name="SoundGiveUp" value=""/>
|
||||
<property name="SoundHurt" value="rabbitpain"/>
|
||||
<property name="SoundDeath" value="rabbitdeath"/>
|
||||
<property name="SoundAttack" value="rabbitpain"/>
|
||||
<property name="SoundStepType" value="animallightstep"/>
|
||||
|
||||
<!-- Жёлтая метка на карте и компасе - указание 2026-09-18. Класс метки наш,
|
||||
Config/nav_objects.xml; ванильные animaltracking_* не подошли, они завязаны
|
||||
на перк следопыта, а не на прямое назначение. -->
|
||||
<property name="NavObject" value="necroRatSpiritPet"/>
|
||||
|
||||
<property name="AITask-1" value="ApproachAndAttackTarget" data="class=EntityAlive,0"/>
|
||||
<property name="AITask-2" value="Look"/>
|
||||
<property name="AITask-3" value=""/>
|
||||
<property name="AITarget-1" value="SetAsTargetIfHurt" data="class=EntityZombie,EntityEnemyAnimal"/>
|
||||
<property name="AITarget-2" value=""/>
|
||||
|
||||
<effect_group name="Base Effects">
|
||||
<!-- Дух-разведчик, а не танк: меньше собаки (200). Урон у неё и так 5. -->
|
||||
<passive_effect name="HealthMax" operation="base_set" value="120"/>
|
||||
</effect_group>
|
||||
</entity_class>
|
||||
</append>
|
||||
|
||||
<!-- "Жертва" loot bag - BACKLOG.md item 5, Necromancer's Knife. Same shape as vanilla's own
|
||||
EntityLootContainerStrong ("BLUE")/EntityLootContainerBoss ("RED") right above these in
|
||||
Data/Config/entityclasses.xml - only the Mesh and LootList differ.
|
||||
|
||||
Reference in New Issue
Block a user