Files
necromants-tome-7d2d-3-2/Config/blocks.xml
T
AlexCubeandClaude Opus 5.5 c9b3e078c3 Вкладка крафта «Некромантия» (#73); пыль из целого хранилища - 10 (#24)
- ui_display.xml: вкладка Necromancy (значок черепа) в рюкзаке, на
  верстаке, в кузне и на химстоле.
- Group всех крафтящихся вещей мода + Necromancy (прежние группы
  оставлены). Моды ножа, сферы и урны раньше не попадали ни в одну
  вкладку рюкзака (умолчание игры - «Mods»/«Decor»).
- windows.xml: 10 вкладок в строку - шаг значков 43 -> 39, значки
  прежнего размера.
- Ступка: целое хранилище магии - 10 пыли (было 30), повреждённое - 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:42:45 +03:00

668 lines
53 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<config>
<!-- "Пирамида Ереси" (Pyramid of Heresy) - user request 2026-08-31: a placeable ward that
periodically applies the existing Deviator charm (see HarmonySrc/PyramidWardPatch.cs,
reusing HarmonySrc/CharmPatch.cs's buffNecroDeviatorCharm wholesale - no new charm logic
was written, this just triggers the same buff on a timer) to any un-charmed zombie that
wanders into its radius, turning it against other zombies instead of the player/base - a
"barrier" in effect, not in physics: it never pushes or physically blocks anything, it
flips allegiance.
SHAPE: Shape="New" + Model="@:Shapes/pyramid.fbx" - the same standalone pyramid mesh
vanilla itself ships and uses for imposterPyramid's own LOD model (Data/Config/blocks.xml,
"*** blockNextGen imposters" section) - a real, solid, always-loaded asset, not invented
for this mod. Checked the "tentBiohazardRoofXxx" tent-roof pieces first (they're the
nearest thing to a "block with a pyramid top" already in vanilla) but rejected them - all
of them are 3x1x1/3x2x3 multi-blocks meant as building-sized tent roofs, wrong shape/scale
for a single placeable ward. Red per the user's request via TintColor="8A4142" - the exact
hex vanilla's own tentBiohazardRoofRed/tentBiohazardRoofCenterRed use for their red tint,
reused here rather than inventing a new one.
FIXED 2026-08-31 (user report: placed fine but genuinely invisible - "нету префаба"):
missing `Texture` property. EVERY vanilla block using this exact Shape="New" + a custom
standalone Model="@:Shapes/....fbx" (imposterPyramid itself, imposterQuarter,
imposterCTREighth, poiFillerBlock - checked all of them directly) always pairs it with an
explicit `Texture="N"` atlas index; ours never had one, which is the real, simple root
cause. Also switched Material from plain "Msteel" to "Msteel_shapes" + Texture="356" -
the exact Material/Texture pair vanilla's own `steelShapes` block (the real "shapes=All"
steel building family) uses for this same "New" shape renderer - plain "Msteel" is meant
for non-shape steel blocks (doors, hatches) and was never a matched pair with Shape="New"
to begin with. TintColor="8A4142" still multiplies on top as before.
User specifically asked to reuse the "Пирамида 1 м" ("Pyramid 1m") shape/prefab -
genuinely tried, but that specific shape turned out to be a NAMED VARIANT of the engine's
procedural multi-shape building system (`shapes="All"` blocks like `steelShapes`/
`concreteShapes` - see those in vanilla blocks.xml), not a standalone asset with its own
file path at all: decompiled `BlockShapeNew` (the C# class behind every Shape="New" block)
directly and it contains NO "Pyramid" string anywhere - the mapping from a shape's display
name to its actual geometry lives in compiled/binary shape-node data this decompile
couldn't reach, not in anything grep-able or copyable as a `Model=` path. Reproducing that
exact shape would mean reverse-engineering that binary shape data, real extra work with an
uncertain payoff - what shipped instead is the closest already-proven-working equivalent:
the same "New"-shape pyramid mesh `imposterPyramid` itself uses, now actually configured
correctly (see the fix above) so it renders for real. If the proportions look wrong next to
the in-game "Pyramid 1m" (e.g. too tall/full-block instead of a short 1m cap), that's a
scale tweak once it's visible, not a rendering bug - say so and it can be resized.
REWRITTEN 2026-09-01, Class changed from none to Class="CompositeTileEntity" +
CompositeFeatures/TEFeaturePyramidWard - two direct user findings drove this:
1. "Навожу прицел, но подсказка про E не появляется" - the original plain-Block +
Harmony-patches-on-Block approach never showed the E-prompt at all, because a
SEPARATE gate method (Block.HasBlockActivationCommands) was never patched and always
said "nothing to activate" for a plain decorative block.
2. "Сделай TileEntity" - direct request for the effect/zone toggle state to actually
survive a save/reload, which the old static-Dictionary-in-Harmony-patch version could
not do at all (documented as a known caveat before, now actually fixed).
Same syntax vanilla's own keystoneBlock (Land Claim) already uses for this exact
Class="CompositeTileEntity" + CompositeFeatures pattern - see HarmonySrc/
PyramidWardPatch.cs's own class doc comment on TEFeaturePyramidWard for the full decompiled
reasoning (why this is the sanctioned extension point, not a hardcoded-switch hack; the
E-menu/persistence/per-tick mechanics all live there now, not in this XML file). -->
<append xpath="/blocks">
<block name="necroHeresyPyramid">
<property name="CreativeMode" value="Player" />
<property name="DescriptionKey" value="necroHeresyPyramidDesc" />
<property name="Class" value="CompositeTileEntity" />
<property class="CompositeFeatures">
<property class="TEFeaturePyramidWard" />
</property>
<property name="Material" value="Msteel_shapes" />
<!-- ВЕРНУТО НА Shape="New" 2026-09-10 по решению пользователя: «пока верни пирамиду,
которая была у нас изначально».
Своя модель со своей текстурой требует Shape="ModelEntity", и на этом пути осталось
два невылеченных дефекта - разбор и все замеры в BACKLOG.md, раздел про пирамиду:
- нет столкновений: при "New" их считает воксельная система блока, а "ModelEntity"
берёт от модели, и одного BoxCollider на корне в слое 16 не хватило;
- дальние экземпляры рисуются фиолетовым (маджента = не найден шейдер), ближние
при этом верны; добавленный LODGroup положения не исправил.
Всё, что сделано для того пути, сохранено и работает: генератор текстуры
_private/tools/make_pyramid_textures.py, сборка _private/Extracted/ShapesUnityProject,
бандл Resources/necropyramid. Чтобы вернуться к нему, достаточно заменить Shape на
ModelEntity и раскомментировать строку Model ниже. -->
<!-- СВОЯ КОСТЯНАЯ МОДЕЛЬ, 01.10.2026 («пирамида отрицания»): ступени из костей, черепа с
тлеющими глазницами, ось насквозь, наверху цветок из рваной плоти на шипастом стебле
из жил, в нём кристалл. Путь тот же, что у гео-оссуария (там он отлажен): ModelEntity,
префаб - копия оссуария (бандл necroward), шейдер и теги коллайдера ставит
GeoOssuaryPatch по ванильному коллектору росы. Свой коллайдер-коробка 0.95x0.5x0.95. -->
<property name="Shape" value="ModelEntity" />
<!-- Своя модель отключена вместе с возвратом на Shape="New" (см. комментарий выше).
Строка сохранена: она рабочая, ею подключается наш бандл. -->
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroward?necroWardPrefab.prefab" />
<!-- <property name="Model" value="#@modfolder(NecromancerTome):Resources/necropyramid?necroPyramidPrefab.prefab" /> -->
<!-- ModelOffset - ПОЛОЖЕНИЕ МОДЕЛИ, и задавать его надо именно здесь.
Меш формы из shapes-бандла сделан под воксельную систему: его границы лежат не вокруг
начала координат, а в углу (центр -0.50, 0.13, -0.50 при размере 0.51 x 0.26 x 0.50).
Как ModelEntity такая модель вылезает из своего куба - что и наблюдалось: «поднялась,
вершиной упирается в верхний угол».
Сначала это лечили сдвигом детей ВНУТРИ префаба. Модель встала верно, но по блоку
по-прежнему нельзя было попасть и не работало наведение по E: о сдвиге знал только
префаб, а игра держала свой объём для попаданий там, где модель была бы без сдвига.
Игрок целился в одно, а попадал мимо.
Ваниль двигает модель именно этим свойством (у верстака стоит "0,.5,0"), и его игра
учитывает целиком - и в отрисовке, и в попаданиях. Значение посчитано скриптом сборки
по фактическим границам меша: по X и Z в центр куба, по Y основанием на нижнюю грань.
Если меш заменят, скрипт напечатает новое значение в лог. -->
<!-- ModelOffset нужен только при ModelEntity; при "New" положение задаёт сама форма.
Значение верное, посчитано скриптом сборки - сохранено для возврата.
<property name="ModelOffset" value="0.5,-0.495,0.5" /> -->
<!-- ПОКРАСКА ВМЕСТО СВОЕЙ ТЕКСТУРЫ, 2026-09-10. Мысль пользователя: «в игре есть
кисточка, позволяющая перекрашивать блоки, можем ли мы наложить текстуру через
покраску, только заранее?» Можем - именно это свойство Texture и делает.
Data/Config/painting.xml сопоставляет краски из кисточки с номерами текстур атласа
(поле TextureId), а Texture у блока задаёт краску заранее. Доступно 156 красок;
выписаны с названиями в _private/Extracted/paints.txt.
Было 356 (txName_Steel_wall, «оцинкованная стальная стена») - выбор достался от
steelShapes вместе с парой Material/Texture и к праху отношения не имел.
Пробовали 11 (txName_Gravel, «гравий») - в игре прочиталось как земля.
Сейчас 552 (txName_GraniteBlack, «гранит чёрный»): тёмный камень ближе к
спрессованному праху, чем крупная осыпь гравия.
СВОЮ текстуру сюда подставить НЕЛЬЗЯ, проверено по коду игры: у записи краски есть
только TextureId, PaintCost, Group, SortIndex - поля с путём к своей картинке нет.
TextureId это индекс в уже собранном атласе, а сам атлас лежит в
blocktextureatlases_assets_all.bundle среди Addressables игры (рядом с
TerrainTextures), и крючка для подмены его модом не нашлось. Своя текстура
возможна только через путь ModelEntity со своим бандлом - см. BACKLOG.md.
Подбирать краску удобнее всего кисточкой прямо в игре: доступны все 156, перезапуск
не нужен. Найденный номер прописывается сюда.
СЕЙЧАС ЭТИ ДВА СВОЙСТВА НЕ РАБОТАЮТ. Блок снова на Shape="ModelEntity" со своей
моделью (2026-09-10, после того как префаб довели до вида ванильного): при
ModelEntity поверхность даёт материал префаба, а не атлас, и Texture с TintColor
не участвуют. Оставлены нетронутыми, чтобы возврат к покраске был ровно двумя
правками - Shape на "New" и переключить строку Model ниже.
TintColor - множитель поверх краски. Взят пепельно-серый с уходом в фиолет, в тон
остальному мод-набору. Прежний 8A4142 давал ржаво-красный.
Texture принимает и ШЕСТЬ значений через запятую - по одному на грань (в ванили есть
например value="195,570,570,570,570,570"). Если захочется основание отличать от
скатов - делается здесь же, без всякого бандла.
Хорошие запасные варианты из того же списка: 606 concrete_broken (потрескавшийся
бетон), 552 GraniteBlack (чёрный гранит), 443 Rust_black (чёрная ржавчина),
385 Green_rusty_metal (зелёная ржавчина, в тон вкраплениям). -->
<!-- СВОЯ КРАСКА, 2026-09-10. Это уже НЕ ванильная краска из атласа: текстуру пирамиды
добавляет в атлас наш собственный Harmony-патч, HarmonySrc/CustomBlockPaintPatch.cs.
Блок при этом остаётся обычным Shape="New" - со всеми работающими столкновениями,
наведением по E и правильной посадкой, - а поверхность у него своя.
608 - это НОМЕР ЗАПИСИ В uvMapping, а не номер краски. Патч печатает его в лог при
каждом запуске: «uvMapping entry 608 points at slice 407». Краска дополнительно
регистрируется под именем txName_NecroAsh («Некротический прах») и занимает слот 13,
но блоку нужен именно номер записи.
ХРУПКОЕ МЕСТО: 608 - это длина uvMapping ванильной игры, то есть наша запись просто
дописывается в конец. Число верно, пока атлас игры не изменился; после обновления игры
оно может сдвинуться. Патч печатает фактический номер в лог, поэтому расхождение видно
сразу - сверяться при обновлениях.
TintColor убран намеренно: цвет несёт сама текстура, а тинт - множитель, он бы её
исказил. Тот же вывод, что уже сделан по ножу и по банке крови.
<property name="TintColor" value="C8BCD2" /> -->
<property name="Texture" value="608" />
<!-- Real generated art (exch/pyramidOfSpirit.png, copied to
UIAtlases/ItemIconAtlas/) added 2026-09-02, per direct instruction - no
CustomIconTint alongside it (same lesson as every other real icon in this mod,
e.g. resourceZombieAsh: a real drawn icon already has its own correct color, tinting
it on top would recolor it unintentionally). TintColor above is unaffected - that's
the 3D block MESH's tint, a completely separate thing from the 2D inventory icon. -->
<property name="CustomIcon" value="pyramidOfSpirit" />
<property name="Group" value="Decoration,Necromancy" />
<property name="FilterTags" value="MC_building,SC_decor" />
<property name="Collide" value="movement,melee,bullet,arrow,rocket" />
<property name="StabilitySupport" value="false" />
<property name="MaxDamage" value="2000" />
<property name="EconomicValue" value="0" />
<property name="SellableToTrader" value="false" />
<drop event="Destroy" name="resourceScrapIron" count="10,20" />
</block>
<!-- Гео-оссуарий (1.6.0, 2026-09-30): станция добычи ресурсов на кровавой сфере.
Тело - ванильный коллектор росы (Class=Collector): окно, топливо, таймеры, работа без
игрока рядом - всё его. Своего кода два места, оба в HarmonySrc/GeoOssuaryPatch.cs:
- каждая из трёх ячеек модификаций принимает любой из пяти ресурсов (ваниль даёт
ячейке ровно один предмет из RequiredMods);
- ячейка продукции i выдаёт полный стак того ресурса, что лежит в ячейке
модификации i (ваниль смотрит только "занята/пуста", а не на предмет), пустая
модификация = ячейка стоит и сферу не ест; проверка неба снята.
Отсюда три OutputType os1..os3 на три ячейки продукции: у каждого свой таймер и своя
ячейка. OutputItem в них - заглушка, настоящий ресурс подставляет патч.
Топливо общее: 1 сфера = 1 стак (FuelCost 1, AdditionalFuelCost 0). Время как у росы.
ModTypes=Modify - флаг, который ваниль ни на что не тратит: Speed/Count/Expand
изменили бы скорость, выход или размер сетки.
Модель своя (Blender: кости, корни, сосуды, клыки, черепа с глазами-углями), бандл
necroossuary, собрана из префаба коллектора росы: LODGroup, слои и коллайдер ванильные.
Шейдер материалу ставит GeoOssuaryPatch (шейдер ванильного коллектора). -->
<block name="necroGeoOssuary">
<property name="Group" value="Basics,Food/Cooking,Building,advBuilding,Necromancy"/>
<property name="Extends" value="cntDewCollector" />
<property name="UnlockedBy" value="craftingNecroNecromancy" />
<property name="DescriptionKey" value="necroGeoOssuaryDesc" />
<property name="LootLabelKey" value="xuiNecroGeoOssuary" />
<property name="ItemIconBackdrop" value="ui_game_symbol_mining" />
<property name="ItemBackgroundColor" value="140,20,20,255" />
<property name="FuelTypes" value="{blood,resourceBloodSphere,resourceBloodStone}" /><!-- камень - вечное топливо (GeoOssuaryPatch.removeFuel) -->
<property name="OutputTypes" value="{os1,blood,1,0,1,resourceRockSmall,resourceRockSmall,1,1,6000,10000,collector_complete_item}{os2,blood,1,0,1,resourceRockSmall,resourceRockSmall,1,1,6000,10000,collector_complete_item}{os3,blood,1,0,1,resourceRockSmall,resourceRockSmall,1,1,6000,10000,collector_complete_item}" />
<property name="Outputs" value="os1,os2,os3" />
<property name="OutputGridHeight" value="1" />
<property name="FuelGridHeight" value="2" />
<property name="RequiredMods" value="resourceRockSmall,resourceRockSmall,resourceRockSmall" />
<property name="RequiredModsOnly" value="true" />
<property name="ModTypes" value="Modify,Modify,Modify" />
<property name="ModTransformEnableNames" value=",," />
<property name="EmptyText" value="necroGeoOssuaryEmpty" />
<property name="HasItem1Text" value="necroGeoOssuaryHasItems" />
<property name="HasItem2Text" value="necroGeoOssuaryHasItems" />
<property name="FuelTitleText" value="necroGeoOssuaryFuel" />
<property name="FuelTitleSprite" value="ui_game_symbol_skull" />
<property name="FuelTitleSpriteAtlas" value="UIAtlas" />
<property name="FuelTypesSprites" value="BloodSphere,ItemIconAtlasGreyscale" />
<!-- 22.10.2026 (#67): новая модель - клёпаный котёл на костяной треноге (necroOssuaryCauldronPrefab: body, lid, sphere,
glow; Standard-шейдер, тег коллайдеру - DecorColliderTagPatch). Старый necroOssuaryPrefab пока лежит в бандле. -->
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroossuary?necroOssuaryCauldronPrefab.prefab" />
<property name="CustomIcon" value="necroGeoOssuary" />
<property name="EconomicValue" value="0" />
<property name="SellableToTrader" value="false" />
<property class="RepairItems">
<property name="resourceBone" value="50" />
</property>
</block>
</append>
<!-- «Книга памяти» (03.10.2026): единственный интерактивный предмет чертогов разума, по E - окно
«Память» (HarmonySrc/BlockNecroMemoryBook.cs). Вид - одиночная книга игры, без хранилища.
CreativeMode Dev - чтобы можно было поставить в редакторе префабов. -->
<append xpath="/blocks">
<block name="necroMemoryBook">
<property name="Extends" value="decoEntityClothMaster"/>
<property name="Class" value="NecromancerTome.NecroMemoryBook, NecromancerHarmony"/>
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="necroMemoryBook"/> <!-- 03.10: свой рендер книги памяти -->
<!-- 03.10: своя модель - книга некроманта: чёрная кожа, кроваво-алый рисунок (z-mind), крупнее и толще книг призыва -->
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrobooks?necroBookMindPrefab.prefab"/>
<property name="ModelOffset" value="0,0,0"/>
<property name="GndAlign" value="1"/>
<property name="WaterFlow" value="permitted"/>
<property name="CanPickup" value="false"/>
</block>
</append>
<!-- Нож-декорация в чертогах разума (03.10.2026): копия ножа некроманта на столе с реактивами,
просто декорация, руны светятся (эмиссия материала ножа). Модель - свой бандл necroknife.
Поворот задаёт MindPalace.KnifeRotation (подбирается командой necropalace knife N). -->
<append xpath="/blocks">
<block name="necroKnifeDecor">
<property name="Extends" value="decoEntityClothMaster"/>
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="NecromancersKnife"/> <!-- 03.10: иконка ножа-предмета (имя предмета иконкой не работает) -->
<!-- 03.10: своя модель-декорация - нож уже лежит плашмя, низом на дне клетки (как нижняя обложка
книги памяти). Модель ножа-предмета стоит вертикально (для руки), а блоки-модели в 3.x ставятся
«реквизитом», для которого код блока не вызывается - поэтому плашмя в самой модели, не в коде. -->
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroknife?necroKnifeDecorPrefab.prefab"/>
<property name="ModelOffset" value="0,0,0"/>
<property name="WaterFlow" value="permitted"/>
<property name="CanPickup" value="false"/>
</block>
</append>
<!-- Кровать чертогов (03.10.2026): копия bunkBedMadeWhite без Class="SleepingBag" - просто мебель.
Чертоги ставятся без игрока, и игра делала кровать префаба точкой возрождения: синий камень
портала отправлял в чертоги. MindPalace.Expected подменяет ею кровать префаба при постановке. -->
<append xpath="/blocks">
<block name="necroPalaceBed">
<property name="Extends" value="bunkBedMadeWhite" param1="Class,DescriptionKey,DowngradeBlock"/>
<property name="CreativeMode" value="None"/>
<property name="CanPickup" value="false"/>
</block>
</append>
<!-- Плакаты-схемы в чертогах (03.10.2026): по образцу ванильной pictureFrameGunSchematic, крупнее.
Блок 2×1×1, рамка-плакат 1.405×0.95 м (полотно 3:2 под плакат), тонкий багет 2 см; модель - бандл
necroposters (на каждый плакат свой префаб с тем же багетом). Исходник рамки:
BlenderWork/necroSchemeFramePrefab/build_frame.py. -->
<append xpath="/blocks">
<block name="necroBookDoor">
<!-- Дверь-книжный шкаф 1x2 (09.10.2026): «замаскирована под книжную полку, закрыта, откроется только по событию».
Механика, звуки и прочность - ванильной межкомнатной двери; модель своя (бандл necroposters, собирает
ItemsUnityProject Assets/Editor/NecroBookDoor.cs): створка 0.98x1.98x0.12 с полками на обеих сторонах, петля
слева, Animator IsOpen/OpenTrigger, состояния Open/Close (как ждёт TEFeatureDoor). Чертоги её не открывают
(MindPalace.OpenDoors трогает только exteriorHouseDoorWhite). -->
<property name="Extends" value="interiorHouseDoorWhite" param1="TintColor,CustomIconTint,MeshDamage"/>
<!-- MeshDamage не наследуем: он ищет в модели Door/DMG0..DMG3 (у ванильной двери они есть, у нашей нет) - тест 09.10:
NullReferenceException в BlockShapeModelEntity.UpdateDamageState при постановке. -->
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="necroBookDoor"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroposters?necroBookDoorPrefab.prefab"/>
<property name="ModelOffset" value="0,0,0"/>
<property name="MultiBlockDim" value="1,2,1"/>
</block>
<block name="necroDoorNumber">
<!-- Табличка с номером двери чертогов (09.10.2026): ставится в редакторе префабов рядом с дверью или над ней,
в ней пишется номер. В чертоги не ставится - вместо неё воздух (MindPalace.Expected), видна только в
редакторе. Дверь с номером закрыта, пока событие не откроет её (MindPalace.SetDoorOpen, necropalace door). -->
<property name="Extends" value="playerSignWood1x1"/>
<property name="CreativeMode" value="Dev"/>
</block>
<block name="necroChalkboard">
<!-- Грифельная доска (09.10.2026): «как рамка, только тёмная винтажная доска; вписаться в 2x2; надписи как
на ящиках - для сюжета». Модель - бандл necroposters (собирает ItemsUnityProject Assets/Editor/NecroChalkboard.cs):
рама 1.90x1.40 м, полочка для мела, дочерний TextMesh (шрифт Neucha, OFL). Надпись - TEFeatureSignable,
писать можно только в редакторе префабов / творческом режиме / отладке (ChalkboardPatch.cs).
Размер букв: em = FontSize x 0.01 / 10 м; 110 -> ~9 строк по ~30 знаков. -->
<property name="Extends" value="pictureFrame_01a"/>
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="necroChalkboard"/>
<property name="Material" value="Mwood_weak"/>
<property name="Class" value="CompositeTileEntity"/>
<property class="CompositeFeatures">
<property class="TEFeatureSignable">
<property name="FontSize" value="110"/>
<property name="LineCount" value="9"/>
<property name="LineWidth" value="1.68"/>
<property name="LineSpacing" value="1"/>
</property>
</property>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroposters?necroPosterChalkboardPrefab.prefab"/>
<property name="ModelOffset" value="0,0,-0.5"/>
<property name="MultiBlockDim" value="2,2,1"/>
<property name="OnlySimpleRotations" value="true"/>
<property name="CanPickup" value="false"/>
</block>
<block name="necroChalkboardPlayer">
<property name="Group" value="Decor/Miscellaneous,Necromancy"/>
<!-- Меловая доска игрока (указание 10.10: «мне нравится использовать её во время игры, делая записи»).
Та же модель и надпись, что у сюжетной necroChalkboard, но крафтится и пишется в обычной игре. Отдельный
блок, чтобы сюжетная доска чертогов (на ней пишет мод, MindPalace.UpdateBoards) осталась неизменяемой.
Записи - TEFeatureSignable: свои у каждой доски, хранятся в чанке, как надписи на ящиках. -->
<property name="Extends" value="necroChalkboard"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroChalkboardPlayerDesc"/>
<property name="Class" value="CompositeTileEntity"/>
<property class="CompositeFeatures">
<property class="TEFeatureSignable">
<property name="FontSize" value="110"/>
<property name="LineCount" value="9"/>
<property name="LineWidth" value="1.68"/>
<property name="LineSpacing" value="1"/>
</property>
</property>
<property name="CanPickup" value="true"/>
</block>
<block name="necroPosterKnife">
<!-- Схема ножа некроманта (09.10.2026): синька в стиле ванильного чертежа пистолета, три вида из Blender
(BlenderWork/necroTomePets/make_knife.py poster). Тот же багет; пользователь повесит сам в чертогах. -->
<property name="Extends" value="pictureFrame_01a"/>
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="necroPosterKnife"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroposters?necroPosterKnifePrefab.prefab"/>
<property name="ModelOffset" value="0,0,-0.5"/>
<property name="MultiBlockDim" value="2,1,1"/>
<property name="CanPickup" value="false"/>
</block>
<block name="necroPosterAnatomy">
<property name="Extends" value="pictureFrame_01a"/>
<property name="CreativeMode" value="Dev"/>
<property name="CustomIcon" value="necroPosterAnatomy"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroposters?necroPosterAnatomyPrefab.prefab"/>
<property name="ModelOffset" value="0,0,-0.5"/>
<property name="MultiBlockDim" value="2,1,1"/>
<property name="CanPickup" value="false"/>
</block>
</append>
<!-- Кровавая роза (05.10.2026): «кровавые семена» из 50 семян травы и банки крови некроманта.
Три этапа по образцу ванильного хлопка: росток -> бутон -> чёрный цветок (урожай).
Сажается только на грядку (FertileLevel 15 от cropsGrowingMaster), каждый этап - GrowthRate
мастера (63 мин). Росток - ванильный хлопок; бутоны и цветущий куст - бандл necrorose (BlenderWork/necroBloodRosePrefab:
build_rose.py, set_quality('game'); Unity: NecroRoseSetup.cs). Тег коллайдера - DecorColliderTagPatch.
Иконка BloodSeeds - рендер _private/Extracted/BlenderWork/necroBloodSeed (make_icon.py). -->
<append xpath="/blocks">
<block name="plantedNecroBloodRose1">
<property name="Extends" value="cropsGrowingMaster" param1="CustomIcon"/>
<property name="CreativeMode" value="Player"/>
<property name="CustomIcon" value="BloodSeeds"/>
<property name="DescriptionKey" value="plantedNecroBloodRose1Desc"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="@:Entities/Plants/plantCottonSproutPrefab.prefab"/>
<property class="PlantGrowing">
<property name="Next" value="plantedNecroBloodRose2"/>
</property>
<property name="PlaceAsRandomRotation" value="true"/>
<drop event="Destroy" name="plantedNecroBloodRose1" count="1"/>
<property name="SortOrder1" value="B953"/>
<property name="SortOrder2" value="0100"/>
<property name="Group" value="Resources,Necromancy"/>
<property name="SoundPickup" value="seeds_generic1_grab"/>
<property name="SoundPlace" value="seeds_generic1_place"/>
</block>
<block name="plantedNecroBloodRose2">
<property name="Extends" value="cropsGrowingMaster"/>
<property name="CreativeMode" value="None"/>
<property name="CustomIcon" value="BloodSeeds"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrorose?necroBloodRose2Prefab.prefab"/>
<!-- 16.10: ModelEntity по умолчанию поднимает модель на полклетки (0,0.5,0) - бутоны висели в воздухе
(«бутоны почему-то подняты над землёй»), как ступка 15.10. Меш стоит основанием на y=0. -->
<property name="ModelOffset" value="0,0,0"/>
<property class="PlantGrowing">
<property name="Next" value="plantedNecroBloodRose3HarvestPlayer"/>
</property>
<drop event="Destroy" name="plantedNecroBloodRose1" count="1"/>
<property name="SortOrder1" value="B953"/>
<property name="SortOrder2" value="0101"/>
</block>
<block name="plantedNecroBloodRose3HarvestPlayer">
<property name="Extends" value="cropsHarvestableMaster"/>
<property name="CreativeMode" value="None"/>
<property name="CustomIcon" value="BloodSeeds"/>
<property name="DescriptionKey" value="plantedNecroBloodRose3HarvestPlayerDesc"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrorose?necroBloodRose3Prefab.prefab"/>
<!-- 16.10: ModelEntity по умолчанию поднимает модель на полклетки (0,0.5,0) - бутоны висели в воздухе
(«бутоны почему-то подняты над землёй»), как ступка 15.10. Меш стоит основанием на y=0. -->
<property name="ModelOffset" value="0,0,0"/>
<drop event="Harvest" name="resourceNecroBlackRose" count="3" tag="cropHarvest"/>
<drop event="Harvest" name="resourceNecroBlackRose" count="1" tag="farmerBonusHarvest"/>
<drop event="Harvest" name="resourceNecroBlackRose" prob="0.5" count="1" tag="bonusCropHarvest"/>
<drop event="Harvest" name="plantedNecroBloodRose1" count="1" tag="farmerBonusSeed"/>
<drop event="Destroy" name="plantedNecroBloodRose1" count="1" prob="0.5"/>
<property name="SortOrder1" value="B953"/>
<property name="SortOrder2" value="0102"/>
</block>
</append>
<!-- Ступка (05.10.2026): верстак 1 куб, на нём сок чёрной розы. Устроен как cementMixer (Workstation
с одним модулем output, без топлива); окно - workstation_necroMortar в XUi_InGame/xui.xml.
Модель - бандл necromortar (BlenderWork/necroMortarPrefab, руны запечены в текстуру; Unity:
NecroMortarSetup.cs + NecroAuto.ImportMeshAndBuild). BoxCollider на корне, тег - DecorColliderTagPatch. -->
<append xpath="/blocks">
<block name="necroMortar">
<property name="Class" value="Workstation"/>
<property class="Workstation">
<property name="Modules" value="output"/>
</property>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroMortarDesc"/>
<property name="CustomIcon" value="necroMortar"/>
<property name="WorkstationIcon" value="ui_game_symbol_skull"/>
<property name="CraftIcon" value="ui_game_symbol_skull"/>
<property name="CraftActionName" value="lblContextActionCraft"/>
<property name="Stacknumber" value="1"/>
<property name="Material" value="Mstone"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necromortar?necroMortarPrefab.prefab"/>
<!-- 15.10: без этого ModelEntity поднимает модель на полклетки (по умолчанию 0,0.5,0) - ступка висела
в воздухе (стрим 15.10). Меш уже стоит основанием на y=0, сдвиг не нужен. -->
<property name="ModelOffset" value="0,0,0"/>
<property name="ImposterDontBlock" value="true"/>
<property name="WaterFlow" value="permitted"/>
<property name="Place" value="TowardsPlacer"/>
<property name="OnlySimpleRotations" value="true"/>
<property name="IsTerrainDecoration" value="true"/>
<property name="StabilitySupport" value="false"/>
<property name="MaxDamage" value="300"/>
<property name="EconomicValue" value="50"/>
<property name="OpenSound" value="open_workbench"/>
<property name="CloseSound" value="close_workbench"/>
<property name="TakeDelay" value="5"/>
<property name="Group" value="Building,advBuilding,Necromancy"/>
<property name="FilterTags" value="MC_playerBlocks,SC_decor"/>
<drop event="Destroy" name="resourceRockSmall" count="10"/>
</block>
</append>
<!-- Череп-декорация (15.10.2026): «череп пусть переделывается в блок декора», вид выбирается, как у строительных блоков.
Предмет necroSkull НЕ превращаем в блок - он уже в сейвах (добыт на стриме 12.10), смена класса предмета убила бы
его стаки. Поэтому отдельный блок-помощник necroSkullDecor с двумя видами (SelectAlternates, как lanternOld):
necroSkullDecorCenter - череп лежит на дне клетки по центру;
necroSkullDecorBack - на дне, затылком в заднюю грань (сторона стены, Place как у плакатов).
Модели - бандл necroskull (Unity NecroSkullDecorSetup.cs, тот же меш, что у предмета). Из черепа и обратно -
рецептами (recipes.xml); снятый блок возвращает помощника, разрушенный - череп-предмет (редкий, 2%).
15.10, вторая версия: декор получается из черепа в руке - R, «Череп: по центру» / «у стены» превращает стопку
в блок (превью, повороты блока); обратно - R, «Просто череп» (SkullDecorPlace.cs). Поднятый - снова череп. -->
<append xpath="/blocks">
<block name="necroSkullDecorCenter">
<property name="CreativeMode" value="Player"/>
<property name="CustomIcon" value="necroSkull"/>
<property name="DescriptionKey" value="necroSkullDecorDesc"/>
<property name="Material" value="Mstone"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroskull?necroSkullDecorCenterPrefab.prefab"/>
<property name="ModelOffset" value="0,0,0"/>
<property name="ImposterDontBlock" value="true"/>
<property name="WaterFlow" value="permitted"/>
<property name="Collide" value="movement,melee,bullet,arrow,rocket"/>
<property name="Place" value="TowardsPlacerInverted"/>
<property name="CanPickup" value="true" param1="necroSkull"/> <!-- поднятый - снова просто череп (15.10) -->
<property name="TakeDelay" value="1"/>
<property name="StabilitySupport" value="false"/>
<property name="MaxDamage" value="100"/>
<property class="RepairItems">
<property name="resourceBone" value="2"/>
</property>
<property name="Stacknumber" value="50"/> <!-- как у черепа: стопка превращается целиком (SkullDecorPlace.Convert) -->
<property name="EconomicValue" value="500"/>
<property name="SellableToTrader" value="false"/>
<property name="Group" value="Building,advBuilding"/>
<property name="FilterTags" value="MC_playerBlocks,SC_decor"/>
<drop event="Destroy" name="necroSkull" count="1"/>
</block>
<block name="necroSkullDecorBack">
<property name="Extends" value="necroSkullDecorCenter"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necroskull?necroSkullDecorBackPrefab.prefab"/>
</block>
<block name="necroSkullDecor">
<!-- 15.10: помощник больше не крафтится - декор делается из черепа в руке через R (SkullDecorPlace.cs). Блок
оставлен, чтобы уже сделанные помощники не пропали: рецепт necroSkull из него остался. -->
<property name="Extends" value="necroSkullDecorCenter"/>
<property name="CreativeMode" value="None"/>
<property name="SelectAlternates" value="true"/>
<property name="PlaceAltBlockValue" value="necroSkullDecorCenter,necroSkullDecorBack"/>
<property name="ItemTypeIcon" value="all_blocks"/>
</block>
</append>
<!-- Урна-цинерарий (Harvest Cinerarium), 1.7.0, 16.10.2026: этап 2 некротехнолога (BACKLOG «Некротехнолог v2»).
Составной блок, как земельный камень: TEFeatureStorage - сумка духа (окно хранилища 6x2, «Открыть»),
TEFeatureCinerarium (HarmonySrc/Cinerarium.cs) - череп (положить/забрать), показ зоны 5x5, -1..+4,
лимит ceil(убийств / 500) и запрет пересечения зон при постановке. Всё - в радиальном меню на E (решение 16.10).
Модель (16.10) - своя: бандл necrocinerarium (BlenderWork/necroCinerarium, make_urn.py): чёрная глазурь, черепа по
четырём сторонам, руны футарка кровью «SERVU ĜIS LA LASTA CINDRO», меандр, бусины; свечение рун и глазниц
включает TEFeatureCinerarium по черепу. Иконка - рендер той же модели (make_icon.py). -->
<append xpath="/blocks">
<block name="necroCinerarium">
<property name="Group" value="Decor/Miscellaneous,Necromancy"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumDesc"/>
<property name="UnlockedBy" value="craftingNecroNecromancy"/>
<property name="Class" value="CompositeTileEntity"/>
<property class="CompositeFeatures">
<property class="TEFeatureStorage">
<property name="LootList" value="necroCinerariumBag"/>
</property>
<property class="TEFeatureCinerarium"/>
<property class="TEFeaturePickup">
<property name="TakeDelay" value="2"/>
</property>
</property>
<property name="Material" value="Mstone"/>
<property name="Shape" value="ModelEntity"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumPrefab.prefab"/>
<property name="ModelOffset" value="0,0,0"/> <!-- меш стоит основанием на y=0; без этого ModelEntity поднимает на полклетки -->
<property name="CustomIcon" value="necroCinerarium"/>
<property name="WaterFlow" value="permitted"/>
<property name="OnlySimpleRotations" value="true"/>
<property name="Collide" value="movement,melee,bullet,arrow,rocket"/>
<property name="StabilitySupport" value="false"/>
<property name="MaxDamage" value="500"/>
<property name="EconomicValue" value="0"/>
<property name="SellableToTrader" value="false"/>
<property name="FilterTags" value="MC_playerBlocks,SC_decor"/>
<property class="RepairItems">
<property name="resourceBone" value="5"/>
</property>
</block>
<!-- Урна, поднятая с черепом внутри (как транспорт держит модификации): тот же блок, при постановке череп
уже в багажнике. Получается только подъёмом (Patch_Block_OnBlockPickedUp_Cinerarium). -->
<block name="necroCinerariumSkull">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumDesc"/>
</block>
<!-- Урна-логист (16.10.2026): «Я не могу ставить урны рядом. Может нам для логиста вообще сделать отдельные урны?»
Без зоны (ставится вплотную к любым урнам), только нити и перевозка (CinerariumThreads.cs), лимит урн общий.
18.10 - своя модель: латунное кадило с чеканкой (BlenderWork/necroCinerariumLogist, бандл necrocinerarium), два вида -
на подставке по центру клетки (necroCinerariumLogist - блок уже в сейвах, остаётся видом по умолчанию) и на кронштейне
у стены (necroCinerariumLogistWall, стена - задняя грань, как у черепа-декора). Вид - R с урной в руке, «Форма»
(CinerariumLogistForm.cs). Дух в покое сидит в кадиле, вылетает из окон крышки только на перевозку, втрое меньше. -->
<block name="necroCinerariumLogist">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumLogistDesc"/>
<property name="CustomIcon" value="necroCinerariumLogist"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumLogistPrefab.prefab"/>
<property name="Material" value="Mmetal"/>
</block>
<block name="necroCinerariumLogistSkull">
<property name="Extends" value="necroCinerariumLogist"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumLogistDesc"/>
</block>
<block name="necroCinerariumLogistWall">
<property name="Extends" value="necroCinerariumLogist"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumLogistDesc"/>
<property name="CustomIcon" value="necroCinerariumLogistWall"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumLogistWallPrefab.prefab"/>
<property name="Place" value="TowardsPlacerInverted"/>
</block>
<block name="necroCinerariumLogistWallSkull">
<property name="Extends" value="necroCinerariumLogistWall"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumLogistDesc"/>
</block>
<!-- Урна рабочего (17-18.10.2026, BACKLOG «Урна рабочего»): чаша на трёх костях (BlenderWork/necroCinerariumWorker,
necroCinerariumWorkerPrefab в бандле necrocinerarium). Изготавливает предмет из второй ячейки «Содержимого» (образец)
на станциях по нитям, пока запас меньше стопки образца (CinerariumCraft.cs). Без зоны и вне лимита, как логист.
Рецепт (18.10) - урна и молоток, открывается вместе с урнами; иконка - своя (18.10, рендер модели). -->
<block name="necroCinerariumWorker">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumWorkerDesc"/>
<property name="CustomIcon" value="necroCinerariumWorker"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumWorkerPrefab.prefab"/>
</block>
<block name="necroCinerariumWorkerSkull">
<property name="Extends" value="necroCinerariumWorker"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumWorkerDesc"/>
</block>
<!-- Урна ремонтника и урна лутера (18.10.2026, BACKLOG «Урна ремонтника», «Урна лутера»; CinerariumZone.cs): большая зона -
сторона притязания или меньше, весь столб мира; работа - по кнопке «Запустить» (один проход), кнопки-звонки с черепом
на модели показывают состояние. Ремонтник чинит повреждённые блоки материалами из ящиков по нитям; лутер собирает
предметы на земле, мешки с зомби и красные трупы в ящик по нити. Без зоны 5x5 и вне лимита, как логист. -->
<block name="necroCinerariumRepair">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumRepairDesc"/>
<property name="CustomIcon" value="necroCinerariumRepair"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumRepairPrefab.prefab"/>
</block>
<block name="necroCinerariumRepairSkull">
<property name="Extends" value="necroCinerariumRepair"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumRepairDesc"/>
</block>
<block name="necroCinerariumLoot">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumLootDesc"/>
<property name="CustomIcon" value="necroCinerariumLoot"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumLootPrefab.prefab"/>
</block>
<block name="necroCinerariumLootSkull">
<property name="Extends" value="necroCinerariumLoot"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumLootDesc"/>
</block>
<!-- Урна старателя (22.10.2026, #64; CinerariumProspector.cs): бронзовая катушка с золотой чеканкой на основе банки лутера
(BlenderWork/necroCinerariumProspector, necroCinerariumProspectorPrefab в бандле necrocinerarium). В «Содержимом» череп
и образец - что добывать; дух уходит под землю и раз в игровой час приносит добычу в ящик по нити. Без зоны и вне
лимита, как логист. -->
<block name="necroCinerariumProspector">
<property name="Extends" value="necroCinerarium"/>
<property name="CreativeMode" value="Player"/>
<property name="DescriptionKey" value="necroCinerariumProspectorDesc"/>
<property name="CustomIcon" value="necroCinerariumProspector"/>
<property name="Model" value="#@modfolder(NecromancerTome):Resources/necrocinerarium?necroCinerariumProspectorPrefab.prefab"/>
</block>
<block name="necroCinerariumProspectorSkull">
<property name="Extends" value="necroCinerariumProspector"/>
<property name="CreativeMode" value="None"/>
<property name="DescriptionKey" value="necroCinerariumProspectorDesc"/>
</block>
</append>
</config>