Модификации > Моддинг
Туториал: реакции
dub:
Добавляем продукты:
Продукты, это то, что остается после реакции. Их можно задать сколько угодно, поместить в контейнер и унаследовать материал исходного реагента. Так же у продуктов можно задать вероятность их образования.
Продукт описывается в общем виде следующим образом:[PRODUCT:<probability>:<quantity>:<item token>:<material token>][...modifiers...]<probability> - вероятность образования продукта в процентах, число от 1 до 100. 100 - продукт будет образовываться всегда. Вероятность каждого продукта считается независимо от остальных.
<quantity> - Количество продукта (обычно в штуках).
<item token> - Описание типа предмета, полный список которых доступен тут.
<material token> - Материал, из которого изготовлен продукт. Можно указать, как показано тут, или унаследовать материал от реагента. Наследование материала рассмотрим ниже.
[...modifiers...] - Несколько токенов, список которых можно посмотреть тут. Из них интерес представляют только два:
[PRODUCT_TO_CONTAINER:<id>] - помещает продукт в контейнер. В реагентах должен быть прописан контейнер с именем id и токеном [PRESERVE_REAGENT], чтобы этот контейнер не был уничтожен реакцией.
[PRODUCT_DIMENSION:<size>] - задать размер продукта. Применяется для "измеряемых" предметов: слитки, порошки, жидкости (150), ткани (10000) или нити (15000). В скобочках указан типичный размер. Этот тег нужен, когда из исходных реагентов может получиться больше или меньше материала, чем нужно.
Собираем все вместе:[REACTION:STONE_WEAPON_REACTION]
[NAME:Make stone weapon]
[BUILDING:CRAFTSMAN:NONE]
[REAGENT:A:1:BOULDER:NONE:INORGANIC:OBSIDIAN]
[PRODUCT:50:1:WEAPON:ITEM_WEAPON_AXE_BATTLE:INORGANIC:OBSIDIAN]
[PRODUCT:50:1:WEAPON:ITEM_WEAPON_MACE:INORGANIC:OBSIDIAN]
Здесь на вход идет одна глыба обсидиана, а на выходе может получиться 0-2 каменных орудия.
В итоге файл reaction_mymod.txt принимает вид:reaction_mymod
[OBJECT:REACTION]
[REACTION:DUMMY_REACTION]
[NAME:Play the ass]
[BUILDING:SMELTER:NONE]
[REACTION:PEACE_REACTION]
[NAME:Make peace not war]
[BUILDING:SMELTER:NONE]
[REAGENT:A:1:WEAPON:NONE:NONE:NONE]
[REACTION:STONE_WEAPON_REACTION]
[NAME:Make stone weapon]
[BUILDING:CRAFTSMAN:NONE]
[REAGENT:A:1:BOULDER:NONE:INORGANIC:OBSIDIAN]
[PRODUCT:50:1:WEAPON:ITEM_WEAPON_AXE_BATTLE:INORGANIC:OBSIDIAN]
[PRODUCT:50:1:WEAPON:ITEM_WEAPON_MACE:INORGANIC:OBSIDIAN]
А в файле entity_default.txt появляются три строчки:[PERMITTED_REACTION:DUMMY_REACTION]
[PERMITTED_REACTION:PEACE_REACTION]
[PERMITTED_REACTION:STONE_WEAPON_REACTION]
А в игре это выглядит так:
dub:
Помещение в контейнер:
Для того, чтобы поместить продукт в контейнер необходимо:
1) Упомянуть в реагентах контейнер (который НЕ уничтожается в ходе реакции)
2) Указать продукту, в какой контейнер его надо поместить
Предположим, мы придумали реакцию, которая берет в качестве исходных реагентов 1 кость и пустую сумку, а в результате создает несколько костяных поделок и помещает их в сумку. Опишем такую реакцию:
[REACTION:BONE_CRAFTS_REACTION]
[NAME:Make several bone crafts]
[BUILDING:CRAFTSMAN:NONE]
[REAGENT:A:1:CORPSE:NONE:NONE:NONE][ANY_BONE_MATERIAL]
[REAGENT:B:1:BOX:NONE:NONE:NONE][BAG][PRESERVE_REAGENT]
[PRODUCT:100:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B]
[PRODUCT:100:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B]
[PRODUCT:50:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B]
[PRODUCT:50:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B]
[PRODUCT:50:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B]
А теперь разберем, что тут написано:
[REAGENT:A:1:CORPSE:NONE:NONE:NONE][ANY_BONE_MATERIAL] - реагент с именем A (это имя мы используем, чтобы указать какой материал должны скопировать продукты) должен быть частью тела (CORPSE:NONE), материал которого в самом реагенте не уточняется (NONE:NONE), но в дальнейшем идет пометка, что материал должен относиться к костям ([ANY_BONE_MATERIAL]).
[REAGENT:B:1:BOX:NONE:NONE:NONE][BAG][PRESERVE_REAGENT] - реагент с именем B (это имя мы используем, чтобы указать, в какой контейнер поместить продукты) имеющий общий тип контейнера (BOX:NONE), который конкретизируется до сумок ([BAG]) и НЕ должен уничтожаться в ходе реакции ([PRESERVE_REAGENT]). Последнее важно, потому что в противном случае контейнер будет уничтожен и изделия складывать будет некуда.
[PRODUCT:100:1:CRAFTS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE][PRODUCT_TO_CONTAINER:B] - с вероятностью 100% создается случайная поделка (CRAFTS:NONE), из материала унаследованного от реагента с именем A (GET_MATERIAL_FROM_REAGENT:A:NONE) и помещается в контейнер с именем B ([PRODUCT_TO_CONTAINER:B]).
Проделав обычные операции по добавлению реакции в игру (см. выше), получим следующую операцию в меню мастерской:
И такое содержимое сумки по завершению реакции:
Если нас не устраивает то, что была взята сумка с уже существующими предметами, то реагенту "сумка" надо добавить дополнительный токен [EMPTY].
Наследование материала:
Само наследование материала описано в предыдущем пункте про помещение продукта в контейнер. Однако там используется только одна из двух возможных форм наследования материала:
1) GET_MATERIAL_FROM_REAGENT:REAGENT_NAME:NONE
2) GET_MATERIAL_FROM_REAGENT:REAGENT_NAME:OPERATION_NAME
В первом случае материал наследуется у реагента с именем REAGENT_NAME и именно этот пример рассмотрен выше.
Второй вариант интереснее: он позволяет унаследовать не сам материал реагента, а производный от него материал. Поясню на примере: предположим мы взяли исходный жир оленя, обработали его и хотим получить уже не жир, а сало, но из того же оленя. Т.е. хотим у продукта получить не исходный материал "жир оленя", а производный материал "сало оленя". Похожие реакции в игре используются для выделки кож. Чтобы это заработало, необходимо:
* В исходном материале (жир, необработанная кожа и т.п.) указать токен с именем операции и идентификатором производного материала:
[MATERIAL_REACTION_PRODUCT:X:Y]
X - операция (например RENDER_MAT)
Y - токен материала (например LOCAL_CREATURE_MAT:TALLOW)
Итого, токен для получения сала из жира выглядит так:
[MATERIAL_REACTION_PRODUCT:RENDER_MAT:LOCAL_CREATURE_MAT:TALLOW]
* В самой реакции надо пометить реагент токеном [HAS_MATERIAL_REACTION_PRODUCT:RENDER_MAT], который укажет для какой операции (в нашем случае RENDER_MAT) в материале посмотреть токен производного материала (это и будет как раз тот самый LOCAL_CREATURE_MAT:TALLOW).
* Наконец, у продукта надо указать не только имя реагента, у которого брать материал, но и имя операции:
GET_MATERIAL_FROM_REAGENT:A:RENDER_MAT
Сама стандартная реакция по превращению жира в сало выглядит так:[REACTION:RENDER_FAT]
[NAME:render fat]
[BUILDING:KITCHEN:CUSTOM_R]
[REAGENT:A:1:GLOB:NONE:NONE:NONE][REACTION_CLASS:FAT][UNROTTEN][HAS_MATERIAL_REACTION_PRODUCT:RENDER_MAT]
[PRODUCT:100:1:GLOB:NONE:GET_MATERIAL_FROM_REAGENT:A:RENDER_MAT]
[SKILL:COOK]
[AUTOMATIC]
В этой реакции так же используются интересные теги [REACTION_CLASS:FAT], [UNROTTEN], [SKILL:COOK] и [AUTOMATIC], которые рассмотрим позже.
Класс реакции:
Другая интересная возможность связана с использованием классов реакций. Допустим, мы хотим научиться изготавливать костяные гарпуны из костей животных. Но не из каких попало, а только из особо крупных и прочных костей: клыки саблезубых тигров, бивни мамонтов и т.п. В этом случае, мы можем пометить материал таких клыков/бивней/прочего тегом [REACTION_CLASS:BIG_BONE]. Благодаря этому, в любой реакции, мы можем ограничить материал реагента только "крупными костями" если укажем после реагента токен REACTION_CLASS с точно таким же значением.
Собственно, в примере выше именно этот механизм и использовался, чтобы ограничить все органические материалы, только классом жиров ([REACTION_CLASS:FAT]) для реакции превращения жира в сало.
Вы можете этот тег использовать, например, чтобы пометить "эпические металлы, сплавы, кости мега тварей и т.п." и создать реакцию "Создать убер-оружие из эпического материала". То есть, по-сути, токен REACTION_CLASS позволяет создавать произвольные подмножества материалов для дальнейшего фильтрования материала реагентов по этим подмножествам.
Украшение:
Украшение/улучшение - еще один токен который может быть добавлен в реакцию наряду с реагентами и продуктами. Он имеет следующий вид:
[IMPROVEMENT:<probability>:<reagent name>:<improvement type>:<material token>]<probability> - Вероятность улучшения в процентах (100 - гарантированно сработает). Для каждого из улучшений вероятность вычисляется независимо от остальных.
<reagent name> - Имя реагента, к которому должно быть применено улучшение. Очевидно, что такой реагент должен быть помечен тегом [PRESERVE_REAGENT], чтобы защитить реагент от уничтожения в ходе реакции. Сам реагент можно дополнительно пометить тегом [NOT_IMPROVED], если вы хотите украсить реагент, которые ранее вообще был без украшений.
<improvement type> - Тип улучшения. Допускаются следующие значения: COVERED (инкрустирован/усеян/декорирован), GLAZED (покрыт), RINGS_HANGING (украшен цепочками), BANDS (обмотан полосами), SPIKES (усеян шипами).
<material token> - Токен материала. Тут действуют точно такие же правила, что и для продуктов (см. выше): можно указать конкретный материал, а можно скопировать материал из другого реагента.
Предположим, мы хотим научиться покрывать кровати костяными шипами (отыгрываем дварфов-йогов или дфварфов-мазохистов). Тогда реакция может выглядеть так:
[REACTION:SPIKE_BED_REACTION]
[NAME:Spike a bed]
[BUILDING:CRAFTSMAN:NONE]
[REAGENT:A:1:BED:NONE:NONE:NONE][PRESERVE_REAGENT][NOT_IMPROVED]
[REAGENT:B:1:CORPSE:NONE:NONE:NONE][ANY_BONE_MATERIAL]
[IMPROVEMENT:100:A:SPIKES:GET_MATERIAL_FROM_REAGENT:B:NONE]
[REAGENT:A:1:BED:NONE:NONE:NONE][PRESERVE_REAGENT][NOT_IMPROVED] - нужна НЕ украшенная ([NOT_IMPROVED]) кровать (в том числе любое другое украшение будет блокировать эту реакцию). Кровать в ходе работы сохраняется ([PRESERVE_REAGENT]).
[IMPROVEMENT:100:A:SPIKES:GET_MATERIAL_FROM_REAGENT:B:NONE] - гарантированно украшается реагент A шипами из материала реагента B.
В итоге получили такую кровать:
Следует отметить, что операция выполняется над ВСЕМ стеком костей, что печально.
Прочие токены:
[UNROTTEN] - указывается после имени реагента и говорит о том, что материал реагента не должен быть гнилым (касается органических материалов).
[FUEL] - для проведения реакции дополнительно требуется одна единица топлива (каменный или древесный уголь), либо не требуется, если реакция идет в постройке, работающей от магмы.
[SKILL:NAME] - для проведения реакции требуется включенный навык с именем NAME. В процессе реакции этот навык тренируется. Можно указать несколько навыков, но использоваться/тренироваться будет только один.
[AUTOMATIC] - реакция добавляется в очередь мастерской автоматически, как только становятся доступны все реагенты.
[ADVENTURE_MODE_ENABLED] - реакция доступна только в режиме приключения через x->create. Реагенты должны или находиться в руках, или лежать под ногами (в рюкзаке реагенты не воспринимаются).
dub:
Примеры реакций:
Тренировка навыков
зарезервировано
Изготовление еды
зарезервировано
Создание каменных кроватей
зарезервировано
Кремация ненужных вещей
зарезервировано
Разборка деревянных и каменных предметов обратно
зарезервировано
Работа с частями тел
Пример взят с офф форума. Две реакции, которые позволяют создавать строительные блоки из частей тел и случайное оружие из костей.
Тут, так же показано, как добавить новую мастерскую, но подробно я на ней останавливаться не буду. Разберу только реакции.
Мастерская (файл building_graveforge.txt):building_graveforge
[OBJECT:BUILDING]
[BUILDING_WORKSHOP:GRAVEFORGE]
[NAME:Graveforge]
[WORK_LOCATION:2:2]
[BUILD_LABOR:ARCHITECT]
[BUILD_KEY:CUSTOM_ALT_G]
[BLOCK:1:0:1:0]
[BLOCK:2:0:0:0]
[BLOCK:3:1:1:1]
[DIM:3:3]
[TILE:0:1:32:32:32]
[TILE:0:2:32:233:32]
[TILE:0:3:32:32:32]
[COLOR:0:1:0:0:0:0:0:0:0:0:0]
[COLOR:0:2:0:0:0:7:0:0:0:0:0]
[COLOR:0:3:0:0:0:0:0:0:0:0:0]
[TILE:1:1:32:32:32]
[TILE:1:2:32:233:239]
[TILE:1:3:32:233:32]
[COLOR:1:1:0:0:0:0:0:0:0:0:0]
[COLOR:1:2:0:0:0:7:0:0:7:0:0]
[COLOR:1:3:0:0:0:7:0:0:0:0:0]
[TILE:2:1:32:239:32]
[TILE:2:2:32:233:233]
[TILE:2:3:32:32:233]
[COLOR:2:1:0:0:0:7:0:0:0:0:0]
[COLOR:2:2:0:0:0:7:0:0:7:0:0]
[COLOR:2:3:0:0:0:0:0:0:7:0:0]
[TILE:3:1:32:239:32]
[TILE:3:2:32:32:32]
[TILE:3:3:233:233:233]
[COLOR:3:1:0:0:0:7:0:0:0:0:0]
[COLOR:3:2:0:0:0:0:0:0:0:0:0]
[COLOR:3:3:7:0:0:7:0:0:7:0:0]
[BUILD_ITEM:3:COFFIN:NONE:NONE:NONE]
[BUILD_ITEM:1:SLAB:NONE:NONE:NONE]
Разрешить новую постройку и реакции (файл entity_default.txt):[PERMITTED_BUILDING:GRAVEFORGE]
[PERMITTED_REACTION:CORPSEBLOCK]
[PERMITTED_REACTION:BONEWEAPON]
Сами реакции (файл reaction_graveforge.txt):reaction_graveforge
[OBJECT:REACTION]
[REACTION:CORPSEBLOCK]
[NAME:Turn Corpse to Blocks]
[BUILDING:GRAVEFORGE:CUSTOM_C]
[REAGENT:A:1:CORPSE:NONE:NONE:NONE][USE_BODY_COMPONENT]
[PRODUCT:100:1:BLOCKS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE]
[PRODUCT:50:1:BLOCKS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE]
[PRODUCT:50:1:BLOCKS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE]
[PRODUCT:50:1:BLOCKS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE]
[SKILL:BUTCHER]
[REACTION:BONEWEAPON]
[NAME:Turn Bones into a Weapon]
[BUILDING:GRAVEFORGE:CUSTOM_W]
[REAGENT:A:1:CORPSE:NONE:NONE:NONE][ANY_BONE_MATERIAL]
[PRODUCT:100:1:WEAPON:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE]
[SKILL:BONECARVE]
[BUILDING:GRAVEFORGE:CUSTOM_C] - реакция проходит в мастерской GRAVEFORGE и для нее назначена горячая кнопка 'c'.
[REAGENT:A:1:CORPSE:NONE:NONE:NONE] - реагент называется A, подходят останки любого подтипа (CORPSE:NONE) и из любого материала (NONE:NONE).
[USE_BODY_COMPONENT] - реагент должен обязательно являться частью тела.
[ANY_BONE_MATERIAL] - реагент должен обязательно быть костью.
[PRODUCT:100:1:BLOCKS:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE] - с вероятностью 100% получится 1 блок из материала, взятого у реагента A (GET_MATERIAL_FROM_REAGENT:A:NONE).
[PRODUCT:100:1:WEAPON:NONE:GET_MATERIAL_FROM_REAGENT:A:NONE] - с вероятностью 100% получится 1 случайное оружие (WEAPON:NONE) из материала, взятого у реагента A.
[SKILL:BUTCHER] - для этой реакции нужно обладать навыком мясника (BUTCHER), который в процессе реакции тренируется.
Скрины:
Andys:
Упомяну об ограничениях, на которые я напоролся при создании реакций на еду.
1. реакция производится только над всем стеком "ингредиентов". Если есть Plump Helmet [5], то все пять сразу и используются, на выходе будет результат реакции * 5 или вроде того, не помню. Невозможно заставить по одиночке обработать все вещи в стеке или разделить стек .
2. [PRODUCT_TO_CONTAINER:<id>] - не сработает, если получаемый после реакции стек больше вместимости контейнера. Например, крайний случай - на выходе жидкость[12], в бочку влазит только 10. Её просто выльют на пол и она будет валяться вечно (поскольку выпить с пола в коде не прописано, а положить в бочку - не влезло)
dub:
Ага. Спасибо за уточнение: где-нибудь в примерах реакций уточню про это.
Навигация
Перейти к полной версии