Прямое указание пользователя. Единица здесь - градусы сдвига уличной температуры к комфортным 70, а не проценты, и в PlayerEntityStats стоит min/max-ограничение: с 50 любая температура в пределах 50 градусов от 70 подтягивается к 70 целиком. То есть примерно от 20 до 120 по шкале игры это полный иммунитет, а не "сильная защита". Прежние 5 были уровнем одной детали брони с T3-подкладкой. Описание в Localization.csv править не потребовалось: там "strong protection from both freezing and heat" без конкретных цифр. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEXvXg1FSAQJHrvYbeAKqq
328 lines
27 KiB
XML
328 lines
27 KiB
XML
<config>
|
||
<!-- Модификации Ножа некроманта. Продиктовано 2026-09-07: "добавь в нож слоты для
|
||
модификаций. Но модификации там будут особые, именно для ножа некроманта, а не для
|
||
обычного ножа."
|
||
|
||
HOW THE EXCLUSIVITY WORKS (both halves verified against the decompiled assembly, not
|
||
guessed - see the long comment on the knife's Tags in items.xml for the full audit):
|
||
|
||
- installable_tags="necroKnife" is the positive half. The install UI checks
|
||
"InstallableTags.IsEmpty || itemClass.HasAnyTags(InstallableTags)"
|
||
(XUiC_ItemPartStack.CanSwap / XUiC_ItemStack / XUiM_AssembleItem all agree), matched
|
||
against the TARGET ITEM's Tags. necroWpnBladeNecroKnife is the only item anywhere -
|
||
vanilla or this mod - that carries "necroKnife", so these three fit it and nothing
|
||
else. Note the IsEmpty short-circuit above: a modifier with no installable_tags at all
|
||
goes into ANY item, so leaving it off would be the opposite of what was asked.
|
||
- The knife's own "noMods" tag is the negative half, blocking all 87 vanilla modifiers
|
||
from going the other way. That lives on the knife, not here.
|
||
|
||
WHY EACH ONE HAS ITS OWN modifier_tags: mods whose modifier_tags overlap are counted
|
||
against ItemClass.MaxModsAllowed, which defaults to 1 (ItemClass.cs line 376), and
|
||
CanSwap refuses once the count is reached. Giving all three a shared tag like
|
||
"necroKnifeMod" would therefore have let the player install exactly ONE of them at a time
|
||
- the four slots would be unusable. Distinct tags per mod is also what vanilla does
|
||
(damageBleed / barrelAttachment / droneArmor ...).
|
||
|
||
type="attachment" (not "mod") so they can be pulled back out and moved to another knife -
|
||
a type="mod" is permanent once installed.
|
||
|
||
ICONS UPDATED 2026-09-07: real generated art for all six, drawn by the user and dropped in
|
||
via c:\Exchange\exch. Each mod now points CustomIcon at its own sprite in
|
||
UIAtlases/ItemIconAtlas (TearsOfTheDead / ScavengersFeast / DeadMansGrip / GravesRepose /
|
||
DeadStorm / DarkSense, all 160x160 RGBA like the other 21). This replaced the old
|
||
reused-vanilla-sprite placeholders (drinkJarBoiledWater, foodShamSandwich,
|
||
modMeleeGraveDigger, modArmorInsulatedLinerT2, modMeleeStunBatonRepulsor,
|
||
modGunScopeSmall) - the same progression the Knife and Victim's Skin went through on
|
||
2026-08-29. CustomIconTint dropped from all six along with them: it existed only to stop
|
||
the borrowed vanilla sprites reading as the items they came from, and on purpose-drawn art
|
||
it would just darken the picture.
|
||
|
||
If a tint is ever needed again here, note the format trap that cost a round the first
|
||
time: CustomIconTint is HEX ("785AB4"), NOT the "R, G, B" triplet that TintColor takes on
|
||
the knife itself. They look interchangeable and are not - decompiled, ItemClass parses this
|
||
one with StringParsers.ParseHexColor while TintColor goes through the Color32 comma path,
|
||
and every vanilla CustomIconTint value is hex (FF00FF, 6441A5, C68C53...). -->
|
||
<append xpath="/item_modifiers">
|
||
|
||
<!-- "Слёзы мертвеца" - вода. Продиктовано 2026-09-07: "Если он вставлен в нож, то каждый
|
||
убитый зомби даёт 2 единицы воды."
|
||
|
||
IMPORTANT - this deliberately does NOT just add to $waterAmountAdd and stop there.
|
||
That CVar is only a QUEUE; on its own it hydrates nobody. Every vanilla drink
|
||
(drinkJarRiverWater, Data/Config/items.xml ~21744) pairs the add with
|
||
"AddBuff buffProcessConsumables", and it is buffProcessConsumables that adds
|
||
buffHealWaterMax (Data/Config/buffs.xml ~8527: AddBuff buffHealWaterMax requires
|
||
$waterAmountAdd GT 0), whose own onSelfBuffUpdate is what finally moves the number
|
||
into the water stat - .1 per .1s tick, so the 2 units land over about two seconds.
|
||
Missing that second line is exactly the bug that made the knife's lifesteal do
|
||
nothing at all for over a week (see items.xml), so it is spelled out here on purpose.
|
||
|
||
onSelfKilledOther is fired by ItemActionAttack (decompiled, lines ~798 and ~846) as
|
||
"entityAlive.FireEvent(MinEventTypes.onSelfKilledOther, flag4)", guarded by
|
||
"!wasAlreadyDead && entity.IsDead()" so it means a real kill, not a hit on a corpse.
|
||
flag4 is "the damaging item IS the held item", which is true for a melee swing - and
|
||
that same flag4 is what routes the event through Inventory -> ItemValue -> installed
|
||
Modifications. It is the identical argument the knife's already-working
|
||
onSelfAttackedOther effects ride on, so if those fire, this fires. (No vanilla
|
||
item_modifier happens to use onSelfKilledOther, but it is in item_modifiers.xml's own
|
||
documented TRIGGER LIST and the dispatch path above is unconditional.)
|
||
|
||
Gated to zombies via EntityTagCompare on "other" - killing a bear or a bird gives
|
||
nothing, matching how every other on-hit effect in this mod is gated. -->
|
||
<item_modifier name="necroModKnifeTearsOfTheDead" installable_tags="necroKnife" modifier_tags="necroKnifeWater" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="TearsOfTheDead"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<requirement name="EntityTagCompare" target="other" tags="zombie"/>
|
||
<triggered_effect trigger="onSelfKilledOther" action="ModifyCVar" cvar="$waterAmountAdd" operation="add" value="2"/>
|
||
<triggered_effect trigger="onSelfKilledOther" action="AddBuff" buff="buffProcessConsumables"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
<!-- "Пир падальщика" - еда. Продиктовано 2026-09-07: "Следующий мод, на еду. Принцип тот
|
||
же." - same 2 units, same per-kill trigger, same zombie gate.
|
||
|
||
Food rides the mirror-image path of the water mod above: $foodAmountAdd is the queue,
|
||
buffProcessConsumables is what notices it (Data/Config/buffs.xml ~8525: AddBuff
|
||
buffHealFood requires $foodAmountAdd GT 0), buffHealFood is what actually feeds you.
|
||
One AddBuff covers both mods if they are installed together - buffProcessConsumables
|
||
checks water and food independently and hands out whichever buffs apply, so stacking
|
||
the two mods costs nothing extra and neither one cancels the other. -->
|
||
<item_modifier name="necroModKnifeScavengersFeast" installable_tags="necroKnife" modifier_tags="necroKnifeFood" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="ScavengersFeast"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<requirement name="EntityTagCompare" target="other" tags="zombie"/>
|
||
<triggered_effect trigger="onSelfKilledOther" action="ModifyCVar" cvar="$foodAmountAdd" operation="add" value="2"/>
|
||
<triggered_effect trigger="onSelfKilledOther" action="AddBuff" buff="buffProcessConsumables"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
<!-- "Хватка мертвеца" - замедление. Chosen by the user from the proposed list 2026-09-07.
|
||
|
||
Reuses buffInjurySlow, the same vanilla debuff the mod's own Зомбособака already
|
||
applies on its bite (necroMeleeHandZombieDog in items.xml) - proven working in this
|
||
mod rather than a fresh guess, and the same EntityTagCompare zombie gate.
|
||
|
||
onSelfAttackedOther, not onSelfKilledOther: the point is to slow a zombie that is
|
||
still coming at you, so it has to land on the hit, not on the kill. -->
|
||
<item_modifier name="necroModKnifeDeadMansGrip" installable_tags="necroKnife" modifier_tags="necroKnifeSlow" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="DeadMansGrip"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<requirement name="EntityTagCompare" target="other" tags="zombie"/>
|
||
<triggered_effect trigger="onSelfAttackedOther" action="AddBuff" target="other" buff="buffInjurySlow"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
<!-- "Могильный покой" - защита от переохлаждения и перегрева. Продиктовано 2026-09-07:
|
||
"Пусть защищает от переохлаждения и перегрева... Есть параметр устойчивости к холоду и
|
||
жаре. Он бывает на предметах одежды и на некоторых модах на одежду."
|
||
|
||
Найденные параметры - HypothermalResist (холод) и HyperthermalResist (жара). Живой
|
||
ванильный образец: modArmorInsulatedLinerT1/T2/T3 (Data/Config/item_modifiers.xml
|
||
~1873), они ставят ровно эту пару. Величина у них по тирам: T1 1->2.5, T2 2.8->4.3,
|
||
T3 4.6->6 на ОДИН элемент брони, а элементов четыре.
|
||
|
||
ЗНАЧЕНИЕ 5 -> 50, 2026-09-13, прямое указание пользователя ("по факту она поднимает
|
||
сопротивление всего на 5, а надо на 50"). Изначально стояло 5 - примерно уровень одной
|
||
детали брони с T3-подкладкой, и ровно то число, которым ваниль пользуется во
|
||
вкомментированных modArmorInsulatedLiner/modArmorCoolingMesh. Это было осознанно
|
||
скромно; пользователь хочет иначе, и его решение тут главнее моей балансной оценки.
|
||
|
||
ЧТО 50 ОЗНАЧАЕТ НА САМОМ ДЕЛЕ, раз единица - градусы, а не проценты (формула ниже):
|
||
любая уличная температура в пределах 50 градусов от комфортных 70 подтягивается К 70
|
||
ЦЕЛИКОМ, потому что там стоит min/max-ограничение. То есть от 20 до 120 по шкале игры
|
||
это не "сильная защита", а полный иммунитет: и снежная вершина, и пустынный полдень
|
||
перестают быть угрозой. Это примерно в 10 раз больше, чем даёт набор брони с
|
||
T3-подкладками на всех четырёх деталях. Записано не в укор, а чтобы через месяц не
|
||
пришлось гадать, почему термометр перестал что-либо значить.
|
||
|
||
ЕДИНИЦА ИЗМЕРЕНИЯ - градусы, на которые сдвигается уличная температура в сторону
|
||
комфортной, а не проценты (PlayerEntityStats, декомпиляция):
|
||
if (outsideTemperature < 70) { v = GetValue(HypothermalResist);
|
||
outsideTemperature = min(70, outsideTemperature + v); }
|
||
else { v = GetValue(HyperthermalResist);
|
||
outsideTemperature = max(70, outsideTemperature - v); }
|
||
|
||
ВАЖНО - РАБОТАЕТ ТОЛЬКО ПОКА НОЖ В РУКАХ. Это не оплошность, а то, как движок вообще
|
||
умеет учитывать не-броню, и проверено по всей цепочке, потому что термостойкость - это
|
||
обычно броневой стат, а нож не броня:
|
||
1. PlayerEntityStats зовёт EffectManager.GetValue(HypothermalResist, null, 0f, entity)
|
||
со всеми параметрами по умолчанию, а в сигнатуре GetValue значения по умолчанию -
|
||
calcHoldingItem: true и useMods: true. То есть предмет в руках и его моды учитываются.
|
||
2. Внутри GetValue ветка "else if (calcHoldingItem && ...)" зовёт Inventory.ModifyValue.
|
||
3. Inventory.ModifyValue пропускает предмет, если его теги попадают в
|
||
ignoreWhenHeld = FastTags.Parse("clothing,armor"). У ножа ни того, ни другого нет,
|
||
так что он проходит - а вот на реальной броне в руках это бы не сработало.
|
||
4. ItemValue.ModifyValue в конце обходит Modifications[j].ModifyValue под флагом
|
||
_useMods. Заметь: здесь, в отличие от FireEvent, НЕТ отсечки "if (!HasQuality)
|
||
return;" - пассивки модов считаются независимо от качества. Но нож всё равно уже
|
||
починен по tiered (см. items.xml), так что вопрос снят в обе стороны.
|
||
Убрал нож в рюкзак - защита пропала. Так и задумано, и так это описано в Localization.csv.
|
||
|
||
Пассивка, а не triggered_effect, поэтому ни onSelfKilledOther, ни гейта на зомби здесь
|
||
нет - эффект просто висит, пока нож в руке.
|
||
|
||
Иконка - спрайт настоящего ванильного мода-подкладки (у item_modifier без своего
|
||
CustomIcon спрайт называется как он сам), то есть по смыслу ровно та картинка. Тинт
|
||
тот же фиолетовый, что у остальных трёх, до появления собственной графики. -->
|
||
<item_modifier name="necroModKnifeGravesRepose" installable_tags="necroKnife" modifier_tags="necroKnifeThermal" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="GravesRepose"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<passive_effect name="HypothermalResist" operation="base_add" value="50"/>
|
||
<passive_effect name="HyperthermalResist" operation="base_add" value="50"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
<!-- "Мёртвая буря" - переделывает силовую атаку. Продиктовано 2026-09-07: "-5 HP повышаем
|
||
до -10 HP. Эффект делаем AOE в радиусе 20 блоков (если это много, то скажи). Расход
|
||
стамины на силовую атаку увеличиваем вдвое. Добавляем дебаф кровотечения и искрения."
|
||
|
||
ФОРМА И РАЗМЕР ОБЛАСТИ. Пользователь потом уточнил: "Нужна именно сфера. Иначе птиц не
|
||
заденет." Сфера не нужна и недоступна - движок умеет ровно одну форму, и она уже
|
||
объёмная. MinEventActionTargetedBase, ветка otherAOE:
|
||
entsInRange = World.GetLivingEntitiesInBounds(_params.Self,
|
||
new Bounds(_params.Other.position, Vector3.one * (maxRange * 2f)));
|
||
Unity-шный Bounds(center, SIZE) берёт РАЗМЕР, а не extents, здесь size = range*2 по
|
||
каждой оси - то есть это КУБ, расходящийся на range блоков во все шесть сторон,
|
||
ВКЛЮЧАЯ вверх и вниз. Дальше World.GetLivingEntitiesInBounds обходит чанки по X/Z и
|
||
сверяет коробки; никакого доп. фильтра по дистанции после выборки нет (см. цикл сразу
|
||
за вызовом - только isValidTarget и singleTargetCheck, оба про теги, не про радиус).
|
||
Поэтому вертикаль покрыта уже сейчас, и куб для летящей цели даже ЛУЧШЕ сферы: сфера
|
||
радиуса R целиком помещается внутрь куба с полу-размером R.
|
||
|
||
Заодно из этого следует, что 20 - это очень много: куб 40x40x40 вокруг цели, сквозь
|
||
стены и перекрытия (проверки линии взгляда тут нет вовсе). Весь ванильный диапазон
|
||
AOE для сравнения: 1.1, 1.3, 1.4, 2.7, 3, 6 и ровно один случай 10
|
||
(buffRingOfFireEffect). Поставлено 6 - это куб 12x12x12, то есть 6 блоков вверх, чего
|
||
хватает на пикирующего стервятника, и при этом не выкашивает соседний этаж POI. Если
|
||
нужно доставать высоко кружащих птиц - поднимать; помнить, что то же число уходит и
|
||
в горизонталь. Менять - четыре атрибута range ниже.
|
||
|
||
ЧТО ЭТОТ МОД ДОБАВЛЯЕТ К БАЗОВОЙ СИЛОВОЙ. Мод умеет только ДОБАВЛЯТЬ эффекты, снять
|
||
собственные эффекты предмета он не может, поэтому "-5 HP -> -10 HP" сделано вторым
|
||
списанием на 5, а не переписыванием первого. Порядок детерминирован: в
|
||
ItemValue.FireEvent собственные эффекты предмета (itemClass.FireEvent) идут ДО цикла
|
||
по Modifications, так что сперва снимается базовая пятёрка, затем эта. Оба списания
|
||
несут свой порог "Health GT 5", поэтому убить себя силовой атакой по-прежнему нельзя;
|
||
следствие - при здоровье между 5 и 10 спишется только часть.
|
||
|
||
ПРО СТАМИНУ. База берётся в ItemActionDynamicMelee.cs:384:
|
||
_actionData.StaminaUsage = EffectManager.GetValue(PassiveEffects.StaminaLoss,
|
||
itemValue, 2f, holdingEntity, null, _actionData.ActionTags) * StaminaUsageMultiplier;
|
||
- значение по умолчанию 2 (своего StaminaLoss у этого ножа нет), и читается оно с
|
||
ActionTags, то есть "secondary" для силовой. GetValue возвращает
|
||
_originalValue * _perc_value, где _perc_value стартует с 1, а perc_add к нему
|
||
прибавляет - поэтому value="1" это ровно "вдвое", а не "+1".
|
||
|
||
ПРО КРОВОТЕЧЕНИЕ - две строки, а не одна, и это не перестраховка. buffInjuryBleeding
|
||
снимает сам себя, если у цели bleedCounter == 0:
|
||
<triggered_effect trigger="onSelfBuffUpdate" action="RemoveBuff" buff="buffInjuryBleeding">
|
||
<requirement name="CVarCompare" cvar="bleedCounter" operation="Equals" value="0"/>
|
||
а урон берёт как HealthChangeOT base_subtract @$bleedAmount, где $bleedAmount
|
||
выставляется из bleedCounter на старте баффа. Просто повесить бафф - он мгновенно
|
||
снимется, не сделав ничего. Поэтому сначала счётчик, потом бафф - как и у ванильного
|
||
modMeleeSerratedBlade. Счётчик задан через "set 2", а не "add 1", чтобы не зависеть от
|
||
$maxBleedCounter (его выставляют перки игрока, buffs.xml ~530) и чтобы эффект не
|
||
накапливался бесконечно от серии ударов. 2 -> 2 HP/сек в течение 20 секунд.
|
||
|
||
ПРО ИСКРЕНИЕ - это ванильный buffShocked, тот самый, что вешают электродубинка и
|
||
электрозабор. Своя частица p_electric_shock и звук electric_fence_impact уже внутри
|
||
баффа, подключать отдельно нечего. По умолчанию 4 секунды и -5 HP/сек через
|
||
HealthChangeOT. Его замедление лежит в ОТДЕЛЬНЫХ effect_group, гейтованных на
|
||
$shockDurationMax >= 4 - это важно для птиц, см. ниже.
|
||
|
||
СРАБОТАЕТ ЛИ НА ПТИЦ (прямой вопрос пользователя) - да, в той части, которая наносит
|
||
урон:
|
||
+ Стервятник попадает в выборку: коробка трёхмерная, вертикаль включена.
|
||
+ Тег есть: animalZombieVulture несёт "entity,animal,zombie,zombieAnimal,hostile,
|
||
vulture,special", а target_tags="zombie" гейтит именно по нему.
|
||
+ Кровотечение работает: HealthChangeOT применяется в EntityStats.cs:142, это общий
|
||
путь для любого EntityAlive, полёт ему безразличен.
|
||
+ Урон от искрения работает по той же причине.
|
||
- Замедление от buffShocked по птице НЕ отработает: оно давит на RunSpeed/WalkSpeed,
|
||
а EntityVulture.cs (~563/567) умножает на сырые поля moveSpeed/moveSpeedAggro и
|
||
геттеры GetMoveSpeed()/GetMoveSpeedAggro() - единственные, кто эти пассивки
|
||
применяет - не зовёт вовсе.
|
||
? Ragdoll по летящей цели - НЕ ПРОВЕРЕНО. Ни в EntityVulture, ни в EntityFlying нет
|
||
ни строчки про ragdoll, полёт-специфичной поддержки точно нет. Проверять в игре.
|
||
Итого по птице: сбить с ног скорее всего не выйдет, но кровотечение и разряд догрызут.
|
||
|
||
Иконка-заглушка - спрайт ванильного мода-репульсора электродубинки, тематически
|
||
ближайшее, что есть готового. -->
|
||
<item_modifier name="necroModKnifeDeadStorm" installable_tags="necroKnife" modifier_tags="necroKnifePower" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="DeadStorm"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<!-- Вдвое дороже по стамине, только силовая. -->
|
||
<passive_effect name="StaminaLoss" operation="perc_add" value="1" tags="secondary"/>
|
||
|
||
<!-- Вторая половина платы: базовые 5 + эти 5 = 10 HP. -->
|
||
<triggered_effect trigger="onSelfSecondaryActionRayHit" action="ModifyStats" stat="Health" operation="subtract" value="5">
|
||
<requirement name="EntityTagCompare" target="other" tags="zombie"/>
|
||
<!-- "Health GT 0" на цели - тот же гейт на трупы, что у самого ножа, чтобы
|
||
силовой удар по трупу не брал 5 HP впустую; подробный разбор в items.xml
|
||
у лечения. AOE-строкам ниже он не нужен: GetLivingEntitiesInBounds сама
|
||
отсеивает мёртвых. -->
|
||
<requirement name="StatCompareCurrent" target="other" stat="Health" operation="GT" value="0"/>
|
||
<requirement name="StatCompareCurrent" stat="Health" operation="GT" value="5"/>
|
||
</triggered_effect>
|
||
|
||
<!-- AOE вокруг задетой цели. Базовое сбивание с ног у ножа одиночное, это его
|
||
расширяет; двойное попадание по самой цели безвредно - Ragdoll это действие,
|
||
а не стакающийся бафф. -->
|
||
<triggered_effect trigger="onSelfSecondaryActionRayHit" action="Ragdoll" target="otherAOE" range="6" target_tags="zombie" duration="1.5" force="150"/>
|
||
|
||
<!-- Кровотечение: сначала счётчик, затем бафф - см. большой комментарий выше. -->
|
||
<triggered_effect trigger="onSelfSecondaryActionRayHit" action="ModifyCVar" target="otherAOE" range="6" target_tags="zombie" cvar="bleedCounter" operation="set" value="2"/>
|
||
<triggered_effect trigger="onSelfSecondaryActionRayHit" action="AddBuff" target="otherAOE" range="6" target_tags="zombie" buff="buffInjuryBleeding"/>
|
||
|
||
<!-- Искрение. -->
|
||
<triggered_effect trigger="onSelfSecondaryActionRayHit" action="AddBuff" target="otherAOE" range="6" target_tags="zombie" buff="buffShocked"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
<!-- "Тёмное чутьё" - радар зомби, пока нож в руке. Вся механика и разбор, почему это
|
||
вообще выполнимо на XML, лежат в комментарии к buffNecroDarkSense в Config/buffs.xml -
|
||
здесь только выключатель.
|
||
|
||
onSelfEquipStart / onSelfEquipStop - ванильный паттерн для "работает, только пока
|
||
предмет в руках" (так сделаны эффекты кирок, Data/Config/items.xml ~158 и ~175).
|
||
Оба события шлёт Inventory на ItemValue держимого предмета (строки ~1226 и ~1245), а
|
||
ItemValue.FireEvent прокидывает их в установленные Modifications - при условии, что у
|
||
предмета есть качество, что у этого ножа теперь так (см. правку tiered в items.xml).
|
||
|
||
Бафф снимается и при смерти игрока: remove_on_death у него не выставлен, а по
|
||
умолчанию это true - то есть залипнуть после респавна он не может. -->
|
||
<item_modifier name="necroModKnifeDarkSense" installable_tags="necroKnife" modifier_tags="necroKnifeSense" type="attachment">
|
||
<property name="Extends" value="modGeneralMaster" param1="CustomIcon"/>
|
||
<property name="CustomIcon" value="DarkSense"/>
|
||
<property name="EconomicValue" value="0"/>
|
||
<property name="SellableToTrader" value="false"/>
|
||
|
||
<effect_group tiered="false">
|
||
<triggered_effect trigger="onSelfEquipStart" action="AddBuff" buff="buffNecroDarkSense"/>
|
||
<triggered_effect trigger="onSelfEquipStop" action="RemoveBuff" buff="buffNecroDarkSense"/>
|
||
</effect_group>
|
||
</item_modifier>
|
||
|
||
</append>
|
||
</config>
|