Commit Graph
19 Commits
Author SHA1 Message Date
AlexCubeandClaude Opus 5.5 027c707233 Кровавая роза: семена, куст, ступка, сок чёрной розы
- Кровавые семена (50 семян травы + кровь некроманта), три этапа роста на грядке:
  росток -> бутоны-черепа -> куст роз с черепом в сердцевине (бандл necrorose).
  Урожай - чёрные розы (3 базово, бонусы фермерства через ванильные теги).
- Ступка (верстак, 1 куб, руны на боку; бандл necromortar) - на Подмастерье.
- Сок чёрной розы: 4 розы + пустая банка на ступке; банка - копия банки крови
  с чернильно-чёрным содержимым (в бандле necroblood).
- Копии всех рецептов на крови некроманта с соком: банка сока = две банки крови
  (при одной крови - одна), из сока 3 кровавые сферы вместо 2.
- Иконки семян, ступки, сока и чёрной розы; тексты на 13 языках.
- DecorColliderTagPatch: хитбокс ступки и куста роз.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:30:02 +03:00
AlexCubeandClaude Opus 5.5 bb7a66dd8e Банки с водой: хват стеклянной банки, вода до стенки
- tinCanRiverWater/tinCanBoiledWater: HoldType 14 -> 3 (хват drinkJar*),
  питьё сразу, без фазы вскрытия консервы.
- necrocan: диск воды расширен с r 0.0389 до 0.0425 - край уходит в
  толщину двойной стенки, щели у стенки больше нет. Проверено в игре.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:00:09 +03:00
AlexCubeandClaude Opus 5.5 66a0dcf403 Чертоги разума, хваты пустой руки, одержимость, книга с оглавлением
- Чертоги разума: дух в префабе chertogi под землёй, книга памяти, нож и плакат;
  кровать префаба - мебель necroPalaceBed (иначе становилась точкой возрождения);
  охрана выбрасывает и игроков (их нет в EntityAlives).
- Хваты пустой руки по R: «отрицание» и «пиф-паф» - поза рук костями поверх аниматора,
  остальные кости заморожены, ЛКМ - заклинание, прицел краснеет на зомби.
- «Отрицание»: зомби в ужасе бежит дальше 40 м и теряет игрока как цель.
- «Пиф-паф»: одержимость зомби-гуманоидом - бег, прыжок, удар, дальняя атака,
  подрыв, крик крикуньи; тело цепенеет, зомби танкуют одержимого; область
  вокруг тела сжата; полоска здоровья; спавн и прорисовка у одержимого.
- Книга с оглавлением (окно necroTome), глава «Некроэнергия».
- Прорисовка дверей у змеи и одержимого (CheckLODs от камеры, а не от тела).
- Почтовый ящик консоли и команды necrobones/necropose/necroshot для разработки.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 00:10:05 +03:00
AlexCubeandClaude Opus 5.5 fa9c5e619d Банки с мутной и кипячёной водой: свои модели с водой внутри
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:05:36 +03:00
AlexCubeandClaude Opus 5.5 12a5559315 Пустая консервная банка: своя модель без крышки (бандл necrocan)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:02:18 +03:00
AlexCubeandClaude Opus 5.5 7f1f61fe40 Книги собаки и стервятника: свои модели, обложки из референсов, новые иконки
- Префабы necroBookDogPrefab и necroBookVulturePrefab в бандле necrobooks: модель
  книги крысы, свои текстуры - рисунки z-dog и z-bird, кожа в тон шкуре зомбопса
  (серо-бурая) и перьям зомбостервятника (красно-бурая).
- bookSummonZombieDog и bookSummonZombieGriffin переведены на них, тинт снят.
- Иконки SummonZombieDog и SummonZombieGriffin - рендер моделей, как у книги крысы.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:56:39 +03:00
AlexCubeandClaude Opus 5.5 d35b77be1b Кровавый камень - вечное топливо скакуна и оссуария; сферы чинятся пакетом крови
- Камень в любой ячейке скакуна - вечно полный бак, сферы рядом не тратятся.
- Камень в отсеке топлива гео-оссуария - работает вечно (FuelTypes + removeFuel).
- Кровавая сфера чинится пакетом крови: 250 прочности за пакет (2 пакета - полная).
- Описания сферы, камня, оссуария и скакуна дополнены (13 языков); в описании
  скакуна по-корейски и по-китайски название сферы приведено к принятому в моде.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:10:41 +03:00
AlexCubeandClaude Opus 5.5 24d6e9f675 1.7.0: скакун на сферах в ячейках, ремонт костями; правки моделей скакуна и книги крысы
- Топливо скакуна - кровавые сферы в 4 ячейках модификаций, тратятся по очереди
  (одна сфера = 120 ед., бак 480); уровень бака считается по прочности сфер,
  выработанная сфера исчезает. Заправка канистрой убрана. В ячейки - только сферы.
- Причина «не едет» и «-2147483648%»: Extends не наследует effect_group, у предмета
  скакуна не было ни ячеек, ни прочности. Своя группа: ModSlots 4, DegradationMax 4000;
  здоровье закреплено кодом (DegradationMax сфер в ячейках его перебивал бы).
- Ремонт - 50 костей за ход вместо ремкомплекта; подсказка при нехватке, 13 языков.
- Модель скакуна: сиденье и рама прогнуты по ванили, рога по оси руля,
  череп меньше и короче, свет фары в глазнице, крыло над передним колесом,
  зубы под черепом убраны.
- Книга крысы: повёрнута как ванильная (палец на корешке), без металлических уголков.

В игре не проверено.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:51:03 +03:00
AlexCubeandClaude Opus 5.5 11db1116b0 1.7.0: костяной скакун, книга Духа крысы, турели, расход сфер в оссуарии
- Костяной скакун (necroBoneSteed): мотоцикл из костей, сухожилий и сосудов
  с черепом-циклопом вместо фары; своя модель (бандл necrobonesteed),
  ванильная система предмета-транспорта (necroBoneSteedPlaceable, предпросмотр
  при установке); топливо - кровавая сфера, одна сфера = полный бак; теги
  коллайдеров и шейдер копируются с ванильного мотоцикла; рецепт на верстаке,
  Подмастерье
- Книга Духа крысы: своя модель (бандл necrobooks) - чёрная кожа, светящийся
  узор со скелетом крысы и семиконечной звездой, ржавые уголки, ремешок
- Турели не стреляют по существам мода (питомцы, рой, змея)
- Гео-оссуарий тратит 1/10 прочности сферы на стак вместо целой сферы

В игре не проверено.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:58:18 +03:00
AlexCubeandClaude Opus 5.5 1c2e3f2cdf Метка «Жертвы» вешается до урона: работает и при убийстве с одного удара
Метка висела на onSelfAttackedOther, которое приходит после DamageEntity; при смертельном
ударе добыча успевала разыграться без неё. Перенесена на onSelfPrimary/SecondaryActionRayHit
(до урона, как лечение ножом), с гейтом Health GT 0 - трупы больше не метятся.
Отзыв sanovskiy на Nexus. Проверено в игре на 3.3: три убийства с одного удара дали «Жертву».

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:54:07 +03:00
AlexCubeandClaude Opus 5 01aa054177 1.4.0: своя модель Ножа некроманта, иконки ножа и Свитка духа крысы, документы релиза
НОЖ ПОЛУЧИЛ СВОЮ ФОРМУ. До сих пор в бандле necroknife стояла ванильная геометрия
костяной заточки с нашей текстурой - на Nexus это заметили (Scarlettdruid: нож не похож
на свою иконку). Форма сделана в Blender поверх ванильного меша: головка и шейка бедра
срезаны, срез закрыт; лезвие выпрямлено в ампутационный нож с клиновым сечением;
костяная гарда стоит над кулаком (место выбрано по игре: девятый виток обмотки от
прежней гарды); рукоять обмотана верёвкой. Весь нож повёрнут на 180° вокруг оси -
режущая кромка смотрела не в ту сторону, "получается, что я обухом режу". Поворот, а
не зеркало: так руны на клинке не отражаются.

Текстура осталась от ножа некроманта. Верёвка нарисована в свободном углу её же атласа
(второй материал импорт в Unity отбрасывает), старые руны заменены светящимися
рублеными знаками, одинаковыми на обеих сторонах клинка. Меш 2823 вершины / 4360
треугольников. Сама цепочка сборки (скрипты Blender и сборки текстур) - в _private,
в репозиторий не входит.

ИКОНКИ нарисованы пользователем: NecromancersKnife.png - под новую модель, RatBook.png -
первая своя у Свитка духа крысы. У свитка снят CustomIconTint: он множится на иконку
и гасил бы нарисованные цвета, он был нужен только перекрашенной волчьей иконке.

ДОКУМЕНТЫ. README (обе половины), SITE_DESCRIPTION.html, NEXUS_DESCRIPTION.bbcode:
версия 1.4.0, новый вид ножа, добыча Жертвы в самом трупе (краснеет, лежит час, при
обыске оставляет мешок - проверено в игре), подбор кроватей-точек возрождения (в игре
НЕ проверено, так и написано). В "Статусе" - абзац 1.4.0 и напоминание о шкале 1.3.0:
на Nexus 21.09 игрок принял уровень "1 из 250" за застывший счётчик и решил, что
прогресс сбросился - уровень растёт раз в 20 убийств, а с 1.0.1 он пересчитывается и
становится в 20 раз меньше.

Тексты для Nexus в принятых сайтом форматах: NEXUS_FILE_SUMMARY_1.4.0.txt (254 знака
из 255) и NEXUS_CHANGELOG_1.4.0.txt (20 строк = 20 пунктов, без номера версии в начале).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 23:57:18 +03:00
AlexCubeandClaude Opus 5 d97f83e972 ИИ питомцев переписан, добавлен Дух крысы, пороги разнесены по шкале
Работа по указаниям 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>
2026-09-18 20:51:42 +03:00
AlexCubeandClaude Opus 5 896501dcd8 Откат крови и Кровавая сфера вместо неё
Чинит поломку сейвов, внесённую предыдущим коммитом e362c62, и заменяет её
механику на безопасную.

ЧТО БЫЛО СЛОМАНО. e362c62 перенёс resourceNecromancerBlood из items.xml в
item_modifiers.xml, чтобы кровь вставлялась в Пространственный браслет. Класс
предмета определяет БАЙТОВУЮ РАСКЛАДКУ каждого его стака в сейве:

    ItemValue.Read  строка 1094:  if ((version > 4 || HasQuality) && !(itemClass is ItemClassModifier))
    ItemValue.Write строка 1228:  if (!(ItemClass is ItemClassModifier))

Обычный предмет пишет байт числа модификаций и байт числа косметических слотов;
ItemClassModifier не пишет ни того, ни другого. Сейв, записанный до переноса,
после переноса читается со сдвигом - поток съезжает на первом же стаке крови, и
PlayerDataFile.Load падает. Бэкап .ttp.bak умирает вместе с основным файлом: он
того же формата. В тестовом мире персонаж потерян вместе с бэкапом, игра
откатилась на Respawning: NewGame.

В коммите e362c62 написано "сейв цел" со ссылкой на assignIdsFromMapping. Айди
действительно берутся из сохранённого name->id мэппинга - но ломается не айди, а
раскладка байтов, и к мэппингу это отношения не имеет. Была проверена не та вещь.

ОТКАТ. Кровь вернулась в items.xml обычным <item>. Набор её свойств сверен с
7172681 и совпадает посимвольно: убраны и Stacknumber=1, и прочность
(ShowQuality + DegradationBreaksAfter + effect_group DegradationMax). Обе правки
были безвредны для сейва, но существовали ради отменённой механики - по указанию
пользователя откат доведён до "как было", а не до "как было плюс безвредное".
Стак снова 15, наследуется от medicalBloodBag.

В комментарии у предмета оставлено предупреждение с номерами строк Read/Write -
единственное, что вынесено из аварии, и единственное, ради чего стоит читать этот
комментарий целиком.

КРОВАВАЯ СФЕРА. Расходник браслета теперь отдельный предмет, и это ровно то, что
делает правку безопасной: resourceBloodSphere - НОВОЕ имя, в старых сейвах его
нет, значит нет и ни одного стака, который читался бы по другой раскладке. Общее
правило, выведенное из аварии: предмет, который уже мог попасть в чужой
инвентарь, нельзя переводить между ItemClass и ItemClassModifier ни в какую
сторону - нужна модификация, заводи новый предмет.

Продиктовано: доступна на первом грейде, без станка, 1 кровь некроманта + 5 праха
зомби дают две сферы, прочность 500. В руке - камень с алым тинтом.

  - item_modifiers.xml: installable_tags="necroBracelet", свой modifier_tags,
    type="attachment", DegradationMax 500 в tiered="false" группе.
    Extends=modGeneralMaster, а НЕ resourceRockSmall: вместе с камнем приезжали бы
    Action0 ThrowAway и ThrowableDecoy, то есть сферу можно было бы метать.
    Меш берётся строкой Meshfile, наследовать ради него весь предмет не нужно.
  - Вид в руке: HoldType 40 и все три меша (Meshfile/HandMeshfile/DropMeshfile) на
    rock_smallPrefab плюс TintColor "220, 30, 45". Путь проверенный - на этом же
    меше с таким же тинтом в моде живут Камень духов и оба портальных камня.
  - recipes.xml: count=2, без craft_area и без тега разблокировки (группа 1
    открыта с уровня 1, рецепт без тега доступен всегда - как у Камня духов).
  - progression.xml: сфера в unlock_entry группы 1, unlock_tier="1".
  - SpatialVaultPickupPatch: SpendBlood -> SpendCharge, имя из новой константы
    ChargeItemName. Гейт пустого слота в Begin снова включён - после отката он был
    временно закомментирован, потому что вставлять было нечего.

ИКОНКИ. Свои, от пользователя: BloodSphere.png и BloodStone.png, 160x160 RGBA, в
ItemIconAtlas и ItemIconAtlasGreyscale. Серая копия обязательна - без неё у
заблокированной записи в скиллах не будет картинки вообще. Способ её получения
подобран сверкой с существующими файлами и совпал ПОБИТОВО: convert('L') на RGB
без альфы, альфа приклеивается обратно отдельным каналом. Записано в BACKLOG.md,
раньше это нигде не было зафиксировано. Иконка камня положена заранее - самого
предмета ещё нет, он запланирован.

ПРОВЕРЕНО, ЧТО НИЧЕГО БОЛЬШЕ НЕ ЕДЕТ. Сверка с 7172681: набор <item> в items.xml
не изменился, в item_modifiers.xml единственное добавление - resourceBloodSphere,
и ни у одного существующего предмета не менялись Tags, ShowQuality и Stacknumber.
То есть ни один предмет не сменил класс и не сменил раскладку.

В игре: мир грузится без ошибок, сфера крафтится и тратится - в логе
"sphere in slot 0 now 12/500 used" за 12-секундный канал.

---

Revert the blood, and a Blood Sphere in its place

Fixes the save corruption introduced by e362c62 and replaces the mechanic behind
it with a safe one.

WHAT WAS BROKEN. e362c62 moved resourceNecromancerBlood from items.xml into
item_modifiers.xml so it could be installed in the Spatial Bracelet. An item's
CLASS decides the BYTE LAYOUT of every stack of it in a save:

    ItemValue.Read  line 1094:  if ((version > 4 || HasQuality) && !(itemClass is ItemClassModifier))
    ItemValue.Write line 1228:  if (!(ItemClass is ItemClassModifier))

A plain item writes a modifications count and a cosmetic-slot count; an
ItemClassModifier writes neither. A save written before the move reads out of
step after it - the stream slips on the first blood stack and PlayerDataFile.Load
throws. The .ttp.bak backup dies with the main file, being the same format. In the
test world the character was lost along with its backup and the game fell back to
Respawning: NewGame.

e362c62's message claimed "saves are safe", citing assignIdsFromMapping. Item ids
really do come from the stored name->id mapping - but what breaks is not the id,
it is the byte layout, and the mapping has nothing to do with it. The wrong thing
was verified.

THE REVERT. The blood is a plain <item> in items.xml again. Its property set was
diffed against 7172681 and matches character for character: both Stacknumber=1 and
the durability (ShowQuality + DegradationBreaksAfter + the DegradationMax
effect_group) are gone. Both were harmless to the save format, but both existed
only to serve the cancelled mechanic - on the user's instruction the revert goes
back to "as it was", not "as it was plus whatever I judged harmless". The stack is
15 again, inherited from medicalBloodBag.

A warning carrying the Read/Write line numbers stays in the item's comment - the
one thing worth keeping out of this accident.

THE BLOOD SPHERE. The bracelet's charge is its own item now, and that is precisely
what makes this safe: resourceBloodSphere is a NEW name, absent from every
existing save, so no stack of it can be read under the wrong layout. The general
rule the accident produced: an item that may already sit in someone's inventory
must never be moved between ItemClass and ItemClassModifier in either direction -
if a modifier is wanted, make a new item.

Dictated: available at the first grade, no workstation, 1 Necromancer's Blood +
5 zombie ash makes two spheres, durability 500. Held, it is a stone with a
scarlet tint.

  - item_modifiers.xml: installable_tags="necroBracelet", its own modifier_tags,
    type="attachment", DegradationMax 500 in a tiered="false" group.
    Extends=modGeneralMaster, NOT resourceRockSmall: the rock would have brought
    Action0 ThrowAway and ThrowableDecoy with it, making the sphere throwable.
    The mesh comes from the Meshfile line; inheriting a whole item for it is not
    needed.
  - Held look: HoldType 40 and all three meshes (Meshfile/HandMeshfile/
    DropMeshfile) on rock_smallPrefab, plus TintColor "220, 30, 45". A proven
    path - the Spirit Stone and both portal stones already live on that mesh with
    that same kind of tint.
  - recipes.xml: count=2, no craft_area and no unlock tag (group 1 opens at level
    1, and a recipe with no tag is simply always available, as with the Spirit
    Stone).
  - progression.xml: the sphere joins group 1's unlock_entry at unlock_tier="1".
  - SpatialVaultPickupPatch: SpendBlood -> SpendCharge, the name coming from a new
    ChargeItemName constant. The empty-slot gate in Begin is switched back on - it
    was commented out during the revert because nothing could be installed.

ICONS. The user's own art: BloodSphere.png and BloodStone.png, 160x160 RGBA, in
both ItemIconAtlas and ItemIconAtlasGreyscale. The greyscale copy is mandatory -
without it a locked skill entry has no picture at all. How those copies are made
was worked out by diffing against the existing files and matched BIT FOR BIT:
convert('L') over RGB without the alpha, with the alpha merged back as its own
channel. Written up in BACKLOG.md; it had never been recorded anywhere. The
stone's icon is filed ahead of the item, which is still only planned.

VERIFIED THAT NOTHING ELSE SHIFTS. Diffed against 7172681: the set of <item>
entries in items.xml is unchanged, the only addition to item_modifiers.xml is
resourceBloodSphere, and no existing item had its Tags, ShowQuality or Stacknumber
changed. No item changed class, and no item changed layout.

In game: the world loads clean, and the sphere crafts and drains - the log shows
"sphere in slot 0 now 12/500 used" for a 12-second channel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MnwP2Dt1vk8bUPJ452EoVL
2026-09-15 23:50:37 +03:00
AlexCubeandClaude Opus 5 e362c627e7 Кровь некроманта - топливо Пространственного браслета
Шесть указаний одного захода, которые сложились в одну механику: поглощение блока
больше не бесплатно. Браслет требует модификацию в слоте, кровь ею стала, и она
на это тратится.

СТАК ПО ОДНОЙ БАНКЕ. Наследуемый medicalBloodBag даёт Stacknumber 15, и это надо
перебивать явно - Extends копирует свойство целиком, а не "если не задано иначе".
Дорого и так задумано: Чёрный портал просит десять банок, то есть десять ячеек.

ПРОЧНОСТЬ 1000. Свойства с именем вроде Durability в игре нет; ручек две, и обе
обязательны. Число - пассивный эффект DegradationMax
(ItemValue.MaxUseTimesBase -> EffectManager.GetValue), полоска - отдельное
свойство ShowQuality (XUiC_ItemStack.ShowDurability -> ItemClass.ShowQualityBar).
Без первой прочность равна нулю, а полоска при MaxUseTimes == 0 рисуется ПОЛНОЙ,
то есть забытый эффект выглядит как "всё работает". tiered="false" обязателен:
ItemClass.HasQuality читается как Effects.IsOwnerTiered(), и тированная группа
превратила бы банку в предмет с качеством, с тирами и рамкой.

КРОВЬ ПЕРЕЕХАЛА В item_modifiers.xml. Это не настройка, а смена класса предмета:
XUiC_ItemPartStack.CanSwap открывается строкой
`if (!(stack.itemValue.ItemClass is ItemClassModifier ...)) return false;` - слот
модификации не смотрит ни на теги, ни на свойства, пока предмет не
ItemClassModifier, а этот класс создаётся только из <item_modifier>. Свойства
вида CanBeInstalled не существует; остаться ресурсом в items.xml и вставляться в
браслет физически нельзя. На старом месте оставлен комментарий-указатель.

Что при этом проверено, а не понадеялось: рецепты резолвятся (ItemClassModifier
наследует ItemClass, имена лежат в общем ItemClass.nameToItem, Recipe ищет через
GetItemClass по тому же словарю); сейв цел (ItemClass.assignIdsFromMapping берёт
айди из сохранённого name->id мэппинга, перестановка в конфигах предмет не
подменит); Harmony-патч и ключи локализации ходят по имени, имя не менялось.

ЛОВУШКА ПЕРЕЕЗДА: у модификации effect_group применяется к предмету, В КОТОРЫЙ её
вставили - прочность 1000 начала бы выдаваться БРАСЛЕТУ. Пассивка гейтована
tags="necroBloodFlask", тег добавлен в Tags флакона: MaxUseTimesBase зовёт
GetValue с ItemTags того предмета, для которого считает.

СЛОТОВ У БРАСЛЕТА 1, было 4. Слот из набора улучшений стал выбором.

ПУСТОЙ СЛОТ ОТКАЗЫВАЕТ. Проверка стоит первой строкой Begin, впереди всех
остальных отказов: прочие про ЦЕЛЬ (нет блока, не тот блок, хранилище полно), эта
про ИНСТРУМЕНТ, и сказать "здесь нет блока", когда пуст браслет, значит отправить
игрока искать не там. Тест - ItemValue.HasMods(), игровой собственный: обходит
только Modifications, пропуская null и IsEmpty, и не считает CosmeticMods, иначе
краска читалась бы как "браслет заряжен". Звук отказа достался бесплатно -
Deny() в этом файле уже играет ванильный ui_denied.

РАСХОД. Цена пула считается ОДИН раз, при старте, и едет в PickupJob.ChannelSeconds
вместе с самим браслетом. Не потому, что так короче: ChannelSecondsFor меряет луч
игрока, а за десять секунд игрок успевает отвернуться - второй вызов насчитал бы
цену за другой блок, а не за тот, который забрали. Браслет хранится экземпляром по
той же причине: моды живут на ItemValue, а колесо прокручивается.

Списывается в SpendBlood, ПОСЛЕ SetBlockRPC и после того, как предмет лёг в
хранилище: все отказы выходят раньше через return, так что кровь за отменённое
поглощение невозможна по построению. Имя предмета берётся из
NecromancerBloodPatch.BloodItemName, а не вторым литералом, чтобы не разъехались.
Мод, который не кровь, не платит ничего и поглощению не мешает - слот задуман под
другие вещи.

КОНЧИЛАСЬ - РАЗБИВАЕТСЯ. Правило именно "прочность 0 или меньше", а не "не хватило
на пул", и разница не косметическая: по второй формулировке флакон, которому
хватило впритык, остался бы в слоте с нулём, HasMods() видел бы "что-то вставлено",
и браслет работал бы бесплатно до конца света. Поэтому зажим по MaxUseTimes убран,
а слот обнуляется через ItemValue.None - это type 0, ровно то, что проверяет
IsEmpty(). Последнее поглощение проходит всегда, флакон его просто не переживает.
Звук - ванильный itembreak, тот же, что играет ItemAction.HandleItemBreak.

Защита: если MaxUseTimes окажется 0 (снесли passive_effect или тег), флакон НЕ
удаляется, а в лог идёт предупреждение с указанием, где чинить. Без этой ветки
ошибка в XML съедала бы игроку предмет на первом же поглощении, и выглядело бы это
багом механики.

Локализация: новый ключ braceletSpatialVaultNoMod в 13 языках, плюс описания
флакона и браслета - механика стала условной и платной, и оба текста без этого
стали бы враньём.

Известное и намеренное: кровавого камня, который обещает сообщение о пустом слоте,
ещё нет - он запланирован, разбор в BACKLOG.md. В игре ничего из этого не
проверено.

---

Necromancer's Blood is the Spatial Bracelet's fuel

Six instructions from one session that add up to one mechanic: pulling a block
into the vault is no longer free. The bracelet needs a mod in its slot, the blood
became that mod, and it is spent doing the work.

ONE JAR PER STACK. The inherited medicalBloodBag sets Stacknumber 15 and it has to
be overridden explicitly - Extends copies a property wholesale, not "unless set".
Expensive on purpose: the Black Portal asks for ten jars, so ten slots.

DURABILITY 1000. There is no property called anything like Durability; there are
two knobs and both are required. The number is a DegradationMax passive effect
(ItemValue.MaxUseTimesBase -> EffectManager.GetValue); the bar is a separate
ShowQuality property (XUiC_ItemStack.ShowDurability -> ItemClass.ShowQualityBar).
Without the first, durability is zero - and the bar at MaxUseTimes == 0 draws
FULL, so a forgotten effect looks exactly like success. tiered="false" is
mandatory: ItemClass.HasQuality is Effects.IsOwnerTiered(), and a tiered group
would have turned the jar into a quality item with tiers and a frame.

THE BLOOD MOVED TO item_modifiers.xml. Not a setting but a change of item class:
XUiC_ItemPartStack.CanSwap opens with
`if (!(stack.itemValue.ItemClass is ItemClassModifier ...)) return false;` - a mod
slot looks at neither tags nor properties until the item is an ItemClassModifier,
and that class is only created from <item_modifier>. No CanBeInstalled property
exists; staying a resource in items.xml and going into the bracelet is impossible.
A pointer comment was left where it used to live.

Checked rather than hoped: recipes still resolve (ItemClassModifier extends
ItemClass, names live in the shared ItemClass.nameToItem, Recipe looks them up
through GetItemClass); saves are safe (ItemClass.assignIdsFromMapping takes ids
from the stored name->id mapping, so shuffling configs cannot swap the item); the
Harmony patch and the localization keys go by name, and the name did not change.

THE TRAP IN MOVING IT: a modifier's effect_group applies to the item it is
INSTALLED IN - the 1000 durability would have been granted to the BRACELET. The
passive is gated with tags="necroBloodFlask" and the tag added to the flask's own
Tags: MaxUseTimesBase calls GetValue with the ItemTags of whatever it is
computing for.

THE BRACELET HAS 1 MOD SLOT, down from 4. The slot stopped being a set of
upgrades and became a choice.

AN EMPTY SLOT REFUSES. The check is the first line of Begin, ahead of every other
refusal: the others are about the TARGET (no block, wrong block, vault full), this
one is about the TOOL, and saying "no block there" when the real problem is an
empty bracelet sends the player looking in the wrong place. The test is
ItemValue.HasMods(), the game's own: it walks Modifications only, skipping nulls
and IsEmpty, and does not count CosmeticMods - a dye would otherwise have read as
"loaded". The refusal sound came free: Deny() in this file already plays vanilla's
ui_denied.

THE COST. The price of a pull is computed ONCE, at the start, and carried in
PickupJob.ChannelSeconds along with the bracelet itself. Not for brevity:
ChannelSecondsFor measures the player's ray, and ten seconds is long enough to
turn away - a second call would charge for a different block than the one taken.
The bracelet is kept as an instance for the same reason: mods live on the
ItemValue and the hotbar scrolls.

It is charged in SpendBlood, AFTER SetBlockRPC and after the item is in the vault:
every refusal returns earlier, so blood charged for a cancelled pull is impossible
by construction. The item name comes from NecromancerBloodPatch.BloodItemName
rather than a second literal, so the two cannot drift. A mod that is not blood
pays nothing and does not block the pull - the slot is meant for other things.

RUNS OUT, SHATTERS. The rule is "durability 0 or less", not "could not cover the
pull", and the difference is not cosmetic: under the second wording a flask with
exactly enough left would sit in the slot at zero, HasMods() would see "something
installed", and the bracelet would work for free forever. So the MaxUseTimes clamp
is gone and the slot is cleared with ItemValue.None - type 0, exactly what
IsEmpty() tests. The last pull always completes; the flask simply does not survive
it. The sound is vanilla's itembreak, the same cue ItemAction.HandleItemBreak
plays.

A guard: if MaxUseTimes comes out 0 (the passive effect or the tag removed), the
flask is NOT deleted and a warning naming the fix goes to the log. Without that
branch a config error would eat the player's item on the first pull and look like
a bug in the mechanic.

Localization: a new braceletSpatialVaultNoMod key in 13 languages, plus the flask
and bracelet descriptions - the mechanic became conditional and paid, and both
texts would have been lies without it.

Known and deliberate: the Blood Stone the empty-slot message promises does not
exist yet - it is planned, written up in BACKLOG.md. None of this is tested in
game.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MnwP2Dt1vk8bUPJ452EoVL
2026-09-15 22:32:59 +03:00
AlexCubeandClaude Opus 5 a5f8592903 Пространственный браслет: 4 слота под модификации
Сами моды будут позже. Схема списана с Ножа некроманта: тег noMods
отсекает все ванильные моды, тег necroBracelet зарезервирован под будущие
свои. canHaveCosmetic намеренно не добавлен - именно он создаёт слот под
краски.

У effect_group НЕТ tiered="false", и это главное: ItemClass.HasQuality -
это Effects.IsOwnerTiered(), а ItemValue.FireEvent выходит по
if (!HasQuality) return; ДО обхода Modifications[]. На нетированном
предмете слоты появились бы, моды вставлялись бы, и ни один
triggered_effect внутри них не сработал бы. Качество при этом не
показывается: ShowQuality по умолчанию false и намеренно не задан.

Старый браслет из сейва слотов не получит - размер Modifications[]
фиксируется при создании предмета.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEXvXg1FSAQJHrvYbeAKqq
2026-09-13 19:54:22 +03:00
AlexCubeandClaude Opus 5 a645c53ff3 Пространственный браслет: в руке пусто, блочный хват
Свёрток-«коробочка на бечёвке» (parcelGenericPrefab + HoldType=31,
унаследованные от Петли вора) для браслета выглядел нелепо. Теперь в
руке не видно ничего, только кулак, повёрнутый вниз.

Связка списана с ванильного vehicleMinibikePlaceable (items.xml:13385),
где те же две строки стоят подряд: HoldType="7" + HoldingItemHidden="true".

Найдено декомпиляцией Assembly-CSharp 3.2.0 через Mono.Cecil, который
лежит прямо в игре (Mods/0_TFP_Harmony/Mono.Cecil.dll):

- HoldType=7 - это и есть блочный хват: его ставит ItemClassBlock..ctor,
  а в blocks.xml свойство HoldType не встречается ни разу, то есть каждый
  блок в игре держится именно этим значением. Костет - это 70, запасной
  вариант не понадобился.
- HoldingItemHidden - штатное свойство ItemClass (PropHoldingItemHidden в
  .cctor, ParseBool в Init), а Inventory.setHoldingItemTransform в конце
  делает SetActive(!HoldingItemHidden). Гаснет только модель в руке -
  иконка инвентаря и предмет на земле не трогаются.
- Пустой меш поставить нельзя: ItemClass.CloneModel подставляет заглушку
  leather.fbx, если ассет не загрузился. Поэтому Meshfile оставлен
  затычкой, а DropMeshfile - ванильный мешок, как у минибайка.
- Действия предмета не задеты: ItemActionEat читает HoldType только ради
  AnimationDelay[HoldType].RayCast, который равен 0f и у 31, и у 7;
  ExecuteAction, за которую держится SpatialVaultPatch, его не читает.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEXvXg1FSAQJHrvYbeAKqq
2026-09-13 17:21:20 +03:00
AlexCubeandClaude Opus 5 ab1b3eadaf Версия 2.0: свои модели ножа и крови, своя краска блоков через патч атласа
Нож некроманта и Кровь некроманта получили собственные модели, а Пирамида
духов - собственную поверхность. Три разных способа, каждый выбран по тому,
как устроен сам предмет.

НОЖ И КРОВЬ - свои префабы в бандлах мода.
Форма записи "#@modfolder(...)?prefab" подтверждена живым примером; геометрия
у обоих ванильная, меняются материал и текстура. Текстуры генерируются
скриптами (см. _private/tools), а не рисуются: правка вида сводится к правке
констант и одному запуску.

Нож: состаренная кость, почти чёрная обмотка, пурпур во впадинах, плюс слой
под ручную роспись рун - он подмешивается в альбедо и в эмиссию, поэтому руны
светятся. Слой пользовательский, генератор его никогда не перезаписывает.
Положение росписи посчитано по геометрии: развёртка выгружена из меша, и
подобрано смещение, при котором вся роспись ложится на одну плоскую грань.
Раньше она перегибалась через кромку, обращённую к игроку.

Кровь: банка вместо мешка. Заодно чинится расхождение, жившее с самого начала -
описание предмета говорило "Банка, наполненная кровью", а наследуемый
medicalBloodBag показывал sackPrefab, обычный мешок. Жидкость перерисована по
маскам мешей, а не перекрашена тинтом: тинт предмета на этот меш не действует
вовсе, у шейдера Game_EntityTintMaskSSS выигрывает _Color материала.

ПИРАМИДА - своя краска в атласе блоков через собственный Harmony-патч.
Ваниль своих текстур блоков не умеет: Texture у блока это индекс в готовом
атласе, а запись краски несёт только TextureId/PaintCost/Group/SortIndex и
никогда путь к картинке. Поэтому CustomBlockPaintPatch дописывает наш слой в
массивы атласа на лету.

Путь через свою модель (Shape="ModelEntity") пробовался и отложен: там
остались нерешёнными столкновения и маджента на дальних экземплярах. Краска
лучше тем, что блок остаётся обычным Shape="New" - со всеми работающими
столкновениями, наведением по E и правильной посадкой, - а поверхность у него
своя. Побочно краска доступна кисточкой под именем "Некротический прах".

Параметры атласа не угаданы, а замерены в игре (BlockAtlasProbePatch): 512x512,
DXT1 для альбедо и DXT5 для нормалей со specular, 10 мип-уровней, массивы
нечитаемые - отсюда GPU-копирование и явные настройки импорта текстур.
Зонд оставлен намеренно: номер краски в blocks.xml (608) это длина ванильного
uvMapping, и после обновления игры он может сдвинуться - зонд печатает
фактические числа при каждом запуске.

Патчи обёрнуты целиком: они работают внутри загрузки игры, где вылетевшее
исключение срывает шаг загрузки.

Resources/necropyramid в коммит не идёт - на него никто не ссылается.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5F3AVwsusZHMqPBcSQcVJ
2026-09-10 16:28:59 +03:00
AlexCubeandClaude Opus 5 026e006c9c Убран мёртвый код проигрывания видео; заготовка своей модели ножа
PlayBlackPortalVideoLegacy и BlackPortalVideoPath ниоткуда не вызывались
с 2026-09-09, когда концовку заменили слайдами. Разборы Pause/PlayVideo и
синтаксиса @modfolder перенесены в NoteFlashbackPatch - единственное место,
где эти API ещё вызываются. Перекрёстные ссылки в FinalSlides поправлены,
устаревшее упоминание StayVideoPath/ReturnVideoPath убрано.

В items.xml у necroWpnBladeNecroKnife добавлена закомментированная строка
Meshfile под будущий бандл Resources/necroknife - включать вместе с самим
бандлом, не раньше. Там же снято старое сомнение про TintColor: ваниль сама
тинтит тот же boneShivPrefab, значит механизм на оружии работает.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y3pwyLpTrwz41qBjyjzNSA
2026-09-10 02:07:31 +03:00
Alex CubeandClaude Opus 5 e8f064f5ec Книга некроманта 1.0 — первая публичная версия
Мод для 7 Days to Die 3.2: навык «Некромантия», растущий от счётчика убитых
зомби, тёмное оружие с шестью собственными модами, призывная нежить, пирамида
духов и сюжетный финал через Чёрный портал. Локализация на 13 языках.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MaNro5hAGTzcQ7rJNN2tCX
2026-09-09 21:13:03 +03:00