ИИ питомцев переписан, добавлен Дух крысы, пороги разнесены по шкале
Работа по указаниям 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
@@ -200,5 +200,128 @@
|
||||
</effect_group>
|
||||
</buff>
|
||||
|
||||
<!-- "Путы духа крысы" - укус Духа крысы, 2026-09-18.
|
||||
|
||||
БЫЛО НОКДАУНОМ, СТАЛО ЗАМЕДЛЕНИЕМ (в тот же день, по игровой проверке: "ронять зомби
|
||||
при каждом ударе смотрится скорее смешно"). Первая версия ставила из кода
|
||||
bodyDamage.CurrentStun = Prone на 5 секунд - механизм рабочий, но зомби валился на
|
||||
землю от каждого укуса мелкого духа, и выглядело это комично.
|
||||
|
||||
ПОЧЕМУ ТЕПЕРЬ ХВАТАЕТ ЧИСТОГО XML, А РАНЬШЕ НЕ ХВАТАЛО. Открытым был ровно один вопрос:
|
||||
доходят ли RunSpeed/WalkSpeed до ИИ, или это чисто игроцкие величины. Ответ нашёлся в
|
||||
EntityAlive:
|
||||
|
||||
public virtual float GetMoveSpeedAggro() {
|
||||
if (IsBloodMoon || world.IsDark())
|
||||
return EffectManager.GetValue(PassiveEffects.RunSpeed, null, moveSpeedAggroMax, this);
|
||||
return EffectManager.GetValue(PassiveEffects.WalkSpeed, null, moveSpeedAggro, this);
|
||||
}
|
||||
|
||||
Скорость зомби берётся через EffectManager, а EntityMoveHelper.SetMoveTo читает её
|
||||
оттуда же. Значит обычный пассивный эффект работает, и весь Harmony-код (RatGripPatch.cs)
|
||||
оказался не нужен - удалён.
|
||||
|
||||
ОБЕ ВЕЛИЧИНЫ ОБЯЗАТЕЛЬНЫ. Ветка в GetMoveSpeedAggro выбирается по времени суток: ночью и
|
||||
в кровавую луну читается RunSpeed, днём - WalkSpeed. Прописать одну - значит получить
|
||||
замедление, которое молча отваливается на полсуток. CrouchSpeed добавлен за компанию,
|
||||
для крадущихся спящих.
|
||||
|
||||
ЗАТУХАНИЕ, А НЕ РОВНАЯ ПОЛКА: value="0.7,.1" с duration="0,5" - это -70% в момент укуса,
|
||||
плавно сходящие к -10% за 5 секунд, тем же приёмом, что у ванильного buffInjurySlow.
|
||||
stack_type replace: каждый следующий укус начинает отсчёт заново, поэтому пока крыса
|
||||
грызёт, зомби так и держится возле -70%, а стоит ей отвлечься - он разгоняется обратно.
|
||||
Кулдаун, который был нужен нокдауну (иначе один питомец держал бы зомби лежачим вечно),
|
||||
здесь не нужен и удалён вместе с ним: замедление, обновляемое укусами, - это ровно то
|
||||
поведение, которое и требовалось. -->
|
||||
<buff name="buffNecroRatGrip" name_key="buffNecroRatGripName" description_key="buffNecroRatGripDesc" icon="ui_game_symbol_twitch_slow" icon_color="140,200,255">
|
||||
<stack_type value="replace"/>
|
||||
<duration value="5"/>
|
||||
<effect_group>
|
||||
<passive_effect name="RunSpeed" operation="perc_subtract" value="0.7,.1" duration="0,5"/>
|
||||
<passive_effect name="WalkSpeed" operation="perc_subtract" value="0.7,.1" duration="0,5"/>
|
||||
<passive_effect name="CrouchSpeed" operation="perc_subtract" value="0.7,.1" duration="0,5"/>
|
||||
</effect_group>
|
||||
</buff>
|
||||
|
||||
<!-- "Метка духа" - вторая половина укуса Духа крысы, 2026-09-18 (указания "предложи дебаф
|
||||
поинтереснее" -> выбраны варианты 2 и 3, метка и гниль, вместе).
|
||||
|
||||
ДВА ЭФФЕКТА, ОДИН БАФФ, И ЖИВЁТ ОН ДОЛЬШЕ ЗАМЕДЛЕНИЯ. Замедление (buffNecroRatGrip
|
||||
выше) осмысленно только пока крыса грызёт, поэтому оно короткое и обновляется каждым
|
||||
укусом. Метка - наоборот: её ценность в том, что она ПЕРЕЖИВАЕТ драку. Тридцать секунд
|
||||
достаточно, чтобы добежать до помеченного и добить его, и мало, чтобы карта превратилась
|
||||
в ёлку.
|
||||
|
||||
1. ВИДНО. SetNavObject на самого носителя - тот же механизм, которым сделано Тёмное
|
||||
чутьё (necroModKnifeDarkSense ниже), только там selfAOE по площади, а здесь
|
||||
target="self": метится ровно тот, кого укусили. Класс метки свой и зелёный, не
|
||||
красный ванильный, - иначе добыча крысы была бы неотличима от зомби, подсвеченных
|
||||
чутьём (см. комментарий в nav_objects.xml).
|
||||
Снимается тремя триггерами, а не одним: по истечении баффа, по смерти носителя и на
|
||||
всякий случай - тем же способом, что RemoveParticleEffectFromEntity у девиации выше.
|
||||
Метка на трупе - это метка, которая не уйдёт уже никогда.
|
||||
|
||||
2. ГНИЁТ. GeneralDamageResist в МИНУС - помеченный получает на четверть больше урона от
|
||||
всего подряд. Это не выдумка и не побочный эффект: сопротивление читается со стороны
|
||||
ЖЕРТВЫ, в EntityAlive.DamageEntity:
|
||||
|
||||
float num = Utils.FastMin(1f, EffectManager.GetValue(PassiveEffects.GeneralDamageResist, null, 0f, this));
|
||||
float num2 = (float)_strength * num + accumulatedDamageResisted;
|
||||
int num3 = Utils.FastMin(_strength, (int)num2);
|
||||
_strength -= num3;
|
||||
|
||||
при отрицательном сопротивлении num3 отрицателен, и вычитание его УВЕЛИЧИВАЕТ урон.
|
||||
Ограничение FastMin(1f, ...) режет только верх (100% сопротивления), низ открыт.
|
||||
|
||||
Вместе это и есть роль Духа крысы: он не убивает сам (урон 5), он находит добычу и
|
||||
делает её уязвимой для хозяина. -->
|
||||
<buff name="buffNecroRatMark" name_key="buffNecroRatMarkName" description_key="buffNecroRatMarkDesc" icon="ui_game_symbol_skull" icon_color="150,220,70">
|
||||
<stack_type value="replace"/>
|
||||
<duration value="30"/>
|
||||
<effect_group>
|
||||
<passive_effect name="GeneralDamageResist" operation="base_subtract" value="0.25"/>
|
||||
<triggered_effect trigger="onSelfBuffStart" action="SetNavObject" target="self" nav_object="necroRatSpiritMark" add="true"/>
|
||||
<triggered_effect trigger="onSelfBuffRemove" action="SetNavObject" target="self" nav_object="necroRatSpiritMark" add="false"/>
|
||||
<triggered_effect trigger="onSelfDied" action="SetNavObject" target="self" nav_object="necroRatSpiritMark" add="false"/>
|
||||
</effect_group>
|
||||
</buff>
|
||||
|
||||
<!-- "Кровоточащая рана" - кровотечение от укуса Духа крысы, 2026-09-18.
|
||||
|
||||
ВАНИЛЬНОЕ buffInjuryBleeding НА ЗОМБИ НЕ РАБОТАЕТ ВООБЩЕ, и стояло оно тут ошибочно.
|
||||
Замечено пользователем по игре ("при такой слабой атаке байкера она била минут 5"),
|
||||
подтверждено чтением Data/Config/buffs.xml. Урон там берётся не из самого баффа, а из
|
||||
переменной игрока:
|
||||
|
||||
<triggered_effect trigger="onSelfBuffStart" action="ModifyCVar" cvar="$bleedAmount"
|
||||
operation="set" value="@bleedCounter"/>
|
||||
<passive_effect name="HealthChangeOT" operation="base_subtract" value="@$bleedAmount"/>
|
||||
<triggered_effect trigger="onSelfBuffUpdate" action="RemoveBuff" buff="buffInjuryBleeding">
|
||||
<requirement name="CVarCompare" cvar="bleedCounter" operation="Equals" value="0"/>
|
||||
</triggered_effect>
|
||||
|
||||
bleedCounter накручивают ДРУГИЕ баффы-обёртки (buffInjuryBleedingOne/Two,
|
||||
buffInjuryBleedingBarbedWire), и это часть игроцкой системы травм. Повесить
|
||||
buffInjuryBleeding напрямую на зомби - значит получить счётчик 0: урон ноль, и бафф
|
||||
снимает сам себя на первом же обновлении. Ровно ноль эффекта, молча.
|
||||
|
||||
Поэтому здесь своё, без единой внешней переменной: сколько написано, столько и капает.
|
||||
|
||||
ЧИСЛА. 5 в секунду на 15 секунд. Укус крысы даёт 5 урона и проходит примерно раз в
|
||||
секунду, то есть кровотечение РОВНО УДВАИВАЕТ её вклад, а stack_type replace означает,
|
||||
что пока она грызёт, рана не заживает. Отвлеклась - зомби живёт ещё 15 секунд и
|
||||
перестаёт течь. Если в игре окажется мало или много, править надо эти две цифры и
|
||||
больше ничего. -->
|
||||
<buff name="buffNecroRatBleed" name_key="buffNecroRatBleedName" description_key="buffNecroRatBleedDesc" icon="ui_game_symbol_critical" icon_color="200,40,40" icon_blink="true">
|
||||
<damage_type value="bloodloss"/>
|
||||
<damage_source value="Internal"/>
|
||||
<stack_type value="replace"/>
|
||||
<duration value="15"/>
|
||||
<update_rate value="1"/>
|
||||
<effect_group>
|
||||
<passive_effect name="HealthChangeOT" operation="base_subtract" value="5"/>
|
||||
</effect_group>
|
||||
</buff>
|
||||
|
||||
</append>
|
||||
</config>
|
||||
|
||||
Reference in New Issue
Block a user