# Эгида — База Знаний Minecraft

Это Эгида — кладезь знаний для начинающих и продвинутых разработчиков сборок Minecraft. Здесь собраны сведения о самых популярных и полезных технических модификациях.

С использованием данного сервиса Вы узнаете о составляющих современной сборки, освоите актуальный материал по модам и откроете для себя мир Minecraft по-новому.

{% embed url="<https://youtu.be/l1kqGINYneM>" %}


# Создание контента


# CraftTweaker

Это мощный мод использующий собственный язык скриптов ZenScript для изменения игрового контента: добавление и удаление рецептов, изменение названий предметов, добавление различных функций и др.


# Minecraft 1.12.2

Это мощный мод использующий собственный язык скриптов ZenScript для изменения игрового контента: добавление и удаление рецептов, изменение названий предметов, добавление различных функций и др.


# Начало работы

Для того чтобы начать работать с этим модом, Вам необходимо загрузить его и, при необходимости, аддоны, расширяющие функционал.

→ [**Скачать CraftTweaker**](https://www.curseforge.com/minecraft/mc-mods/crafttweaker/files/all?filter-game-version=2020709689%3A6756)

После первого запуска игры с установленным модом в папке `.minecraft` будет создана новая папка `scripts` (`.minecraft/scripts`), где будут храниться все ваши скрипты. Скрипты необходимо создавать в файле текстового формата с расширением `.zs` (например, `script.zs`). Для этого сначала создайте обычный текстовый документ формата `.txt`, а затем поменяйте значение `.txt` на `.zs` (если Вы не видите расширение файла, прочитайте эту [**инструкцию**](https://htfi.ru/windows_10/kak_v_windows_10_vklyuchit_rasshirenie_fajlov.html).

**Чтобы скрипты начали работать, необходимо перезагрузить игру!**

Для удобного редактирования скриптов Вам пригодится специальный текстовый редактор. Среди наиболее известных программ можно выделить Notepad++, Sublime Text и VS.

{% hint style="info" %}
В данной статье работа с модом CraftTweaker будет рассмотрена через программу Notepad++, так как она является интуитивно более понятной.
{% endhint %}


# Комментарии

Это записи, которые не читаются системой, но позволяют улучшить понимание скриптов за счет некоторых пояснений, а также заблокировать некоторую часть скрипта.

Синтаксис <mark style="color:blue;">**ZenScipt**</mark> поддерживает 3 типа комментариев:

* Одиночный основной: `//`
* Одиночный альтернативный: `#`&#x20;
* Многострочный: `/* */'`

<div align="left"><figure><img src="/files/05N1HSV9J5vjIv9gwFv2" alt=""><figcaption></figcaption></figure></div>


# Применение нескольких скриптов

Для более удобной работы со скриптами рекомендовано создавать несколько файлов формата `.zs` для разделения рецептов и их типов в разных модах. Также Вы можете в папке `scripts` дополнительно создавать папки и помещать туда Ваши скрипты.

Таким образом, **самый простой способ организации скриптов** для сборки модов может выглядеть следующим образом:

* В папке `scripts` Вы воздаете папки с названием модов, рецепты которых вы собираетесь изменять
* В каждой папке с названием мода Вы создаете файлы формата `.zs` с названием типа рецепта *(например: `crafting` - для верстака, `furnace` - для печки)*
* А далее, например, в файле `crafting.zs` Вы создаете рецепты для верстака, в файле `furnace.zs` – для печки и т. д.

При этом организация файлов может отличаться от приведенной выше. Делайте так, как Вам будет удобнее.


# Элементы крафтов

Условно элементы крафта можно поделить на:

* Конкретные предметы (например, для крафта еловой двери требуется конкретный предмет Еловые доски с именем для скриптов `minecraft:planks:1`),
* OreDict – совокупность взаимосвязанных и взаимозаменяемых предметов (например, для крафта верстака требуется не конкретный вид досок, а доски в целом – с именем для скриптов `ore:plankWood`),
* предметы с nbt (каждый предмет может обладать дополнительной информацией, выраженной через nbt)

К **nbt** относятся в том числе изменённое название предмета, зачарования и др; например, для предмета Еловые доски, переименованного в **«Ель»**, в **nbt** будет информация о имени «Ель», а общее именование для скриптов будет `minecraft:planks:1.withTag({RepairCost: 0, display: {Name: "Ель"}})`.


# Команды

Вся текстовая информация мода хранится в файле `crafttweaker.log` в папке `.minecraft`

Все команды этого мода начинаются с префикса <mark style="color:blue;">**/ct**</mark>. Полный список команд Вы можете получить командой <mark style="color:blue;">**/ct help**</mark>.

Рассмотрим **список основных команд**, облегчающих работу с модом:

* <mark style="color:blue;">**/ct biomes**</mark> Выводит список всех биомов игры в виде текстового документа, который Вы можете открыть щелчком ЛКМ по сообщению, появившемуся в чате после команды
* <mark style="color:blue;">**/ct conflict**</mark> Выводит список всех конфликтующих рецептов в текстовом формате. Работает только с установленным JEI.
* <mark style="color:blue;">**/ct wiki**</mark> Открывает в браузере официальное вики по моду
* <mark style="color:blue;">**/ct entities**</mark> Выводит список всех сущностей (в т. ч. мобов) в текстовом формате
* <mark style="color:blue;">**/ct hand**</mark> Выводит название находящегося в руке предмета для использования в скриптах. Клик ЛКМ по появившемуся названию предмета в чате, чтобы скопировать его
* <mark style="color:blue;">**/ct inventory**</mark> Выводит список всех предметов в Вашем инвентаре в текстовом формате
* <mark style="color:blue;">**/ct jeiCategories**</mark> Выводит список всех категорий JEI (информация, рецепты верстака, рецепты плавки, рецепты наковальни и др. в текстовом формате. Требует JEI.
* <mark style="color:blue;">**/ct liquids**</mark> Выводит список всех жидкостей игры с их характеристиками в текстовом формате
* <mark style="color:blue;">**/ct mods**</mark> Выводит список всех установленных модов в чате и в текстовом формате
* <mark style="color:blue;">**/ct names \[category]**</mark> Выводит список всех предметов игры в текстовом формате для использования в скриптах
* <mark style="color:blue;">**/ct oredict**</mark> Выводит список всех OreDict в текстовом формате
* <mark style="color:blue;">**/ct recipeNames**</mark> Выводит список всех названий рецептов в текстовом формате
* <mark style="color:blue;">**/ct syntax**</mark> Выводит ошибки в синтаксисе Ваших скриптов


# Графический редактор рецептов

Для работы с рецептами верстака и печки Вы можете использовать графический редактор рецептов (который можно открыть командой <mark style="color:blue;">**/ctgui id**</mark>). В целом, редактор интуитивно понятный. Все необходимые скрипты при этом создаются автоматически.

<mark style="color:blue;">**/ctgui craftingtable**</mark> - Верстак

<mark style="color:blue;">**/ctgui furnace**</mark> - Печь

<div><figure><img src="/files/G7Q1xRyD3fPt9PxiykjP" alt=""><figcaption></figcaption></figure> <figure><img src="/files/CszZnpFSMoE1NlDlcLO2" alt=""><figcaption></figcaption></figure></div>


# Приоритеты и переменные

Приоритеты позволяют определить приоритет загрузки Ваших скриптов. Просто добавьте <mark style="color:blue;">#priority</mark> number перед необходимым текстом (скриптом), чтобы определить его приоритет (number - число (0, 1, 2, 3, 4 и т. д.), определяющее приоритет загрузки). Чем выше приоритет скрипта, тем раньше он выполняется. Этой функцией можно воспользоваться, например, тогда, когда Вам сначала требуется удалить все предметы мода, а затем некоторые из предметов вернуть. Тогда Вы расставляете приоритеты таким образом, чтобы сначала загружался скрипт с удалением, а затем скрипт с добавлением, ставя перед скриптами информацию о приоритете, например <mark style="color:blue;">#priority 0</mark> и <mark style="color:blue;">#priority 1</mark>.

Чтобы упростить работу со скриптом, Вы можете использовать переменные. Например, вместо того чтобы каждый раз писать <mark style="color:blue;">**minecraft:apple**</mark>, просто создайте переменную, например, с именем <mark style="color:blue;">**apple**</mark> и после знака равно укажите название предмета. После чего Вы сможете в скриптах обращаться к яблоку через имя переменной <mark style="color:blue;">**apple**</mark>.

<div align="left"><figure><img src="/files/7rXgmlx1ktbO7Jj1LaIG" alt=""><figcaption></figcaption></figure></div>


# Minecraft 1.16.5

Это мощный мод использующий собственный язык скриптов ZenScript для изменения игрового контента: добавление и удаление рецептов, изменение названий предметов, добавление различных функций и др.


# Начало работы

Для того чтобы начать работать с этим модом, Вам необходимо загрузить его и, при необходимости, аддоны, расширяющие функционал.

→ [**Скачать CrafTweaker**](https://www.curseforge.com/minecraft/mc-mods/crafttweaker/files/all?filter-game-version=2020709689%3A6756)

После первого запуска игры с установленным модом в папке `.minecraft` будет создана новая папка `scripts` (`.minecraft/scripts`), где будут храниться все ваши скрипты. Скрипты необходимо создавать в файле текстового формата с расширением `.zs` (например, `script.zs`). Для этого сначала создайте обычный текстовый документ формата `.txt`, а затем поменяйте значение `.txt` на `.zs` (если Вы не видите расширение файла, прочитайте эту [**инструкцию**](https://htfi.ru/windows_10/kak_v_windows_10_vklyuchit_rasshirenie_fajlov.html).

**Чтобы скрипты начали работать, необходимо перезагрузить игру!**


# Комментарии

Это записи, которые не читаются системой, но позволяют улучшить понимание скриптов за счет некоторых пояснений, а также заблокировать некоторую часть скрипта.

Синтаксис <mark style="color:blue;">**ZenScipt**</mark> поддерживает 3 типа комментариев:

* Одиночный основной: `//`
* Одиночный альтернативный: `#`&#x20;
* Многострочный: `/* */'`

<div align="left"><figure><img src="/files/05N1HSV9J5vjIv9gwFv2" alt=""><figcaption></figcaption></figure></div>


# Применение нескольких скриптов

Для более удобной работы со скриптами рекомендовано создавать несколько файлов формата `.zs` для разделения рецептов и их типов в разных модах. Также Вы можете в папке `scripts` дополнительно создавать папки и помещать туда Ваши скрипты.

Таким образом, **самый простой способ организации скриптов** для сборки модов может выглядеть следующим образом:

* В папке `scripts` Вы воздаете папки с названием модов, рецепты которых вы собираетесь изменять
* В каждой папке с названием мода Вы создаете файлы формата `.zs` с названием типа рецепта *(например: `crafting` - для верстака, `furnace` - для печки)*
* А далее, например, в файле `crafting.zs` Вы создаете рецепты для верстака, в файле `furnace.zs` – для печки и т. д.

При этом организация файлов может отличаться от приведенной выше. Делайте так, как Вам будет удобнее.


# Команды

Перед тем, как использовать команды, стоит упомянуть следующее: вся информация, генерируемая модом в процессе использования, хранится в файле `crafttweaker.log` в папке `.minecraft/logs`.

Все команды этого мода начинаются с префикса <mark style="color:blue;">**/ct**</mark>. Полный список команд Вы можете вызвать командой <mark style="color:blue;">**/ct help**</mark>. Теперь рассмотрим список основных команд, облегчающих работу с модом.

<div align="left"><figure><img src="/files/61xksasQ5Hva79Wd4dWd" alt=""><figcaption></figcaption></figure></div>


# Приоритеты

Приоритеты позволяют определить приоритет загрузки Ваших скриптов. Просто добавьте <mark style="color:blue;">**#priority**</mark> <mark style="color:blue;">**`number`**</mark> перед необходимым текстом (скриптом), чтобы определить его приоритет (<mark style="color:blue;">**`number`**</mark> - число (0, 1, 2, 3, 4 и т. д.), определяющее приоритет загрузки).

Чем выше приоритет скрипта, тем раньше он выполняется. Этой функцией можно воспользоваться, например, тогда, когда Вам сначала требуется удалить все предметы мода, а затем некоторые из предметов вернуть. Тогда Вы расставляете приоритеты таким образом, чтобы сначала загружался скрипт с удалением, а затем скрипт с добавлением, ставя перед скриптами информацию о приоритете, например <mark style="color:blue;">**#priority 0**</mark> и <mark style="color:blue;">**#priority 1**</mark>.

Чтобы упростить работу со скриптом, Вы можете использовать переменные. Например, вместо того чтобы каждый раз писать <mark style="color:blue;">**minecraft:apple**</mark>, просто создайте переменную, например, с именем <mark style="color:blue;">**apple**</mark> и после знака равно укажите название предмета. После чего Вы сможете в скриптах обращаться к яблоку через имя переменной <mark style="color:blue;">**apple**</mark>.

<div align="left"><figure><img src="/files/QXMa1eNxiyPjkrLvvtq1" alt=""><figcaption></figcaption></figure></div>


# Менеджер рецептов

Менеджер рецептов – это система создания рецептов, основанная на датапаках, имеющая следующий формат: <mark style="color:blue;">**recipetype:modid:name**</mark>.

Ниже приведены примеры обращения к менеджеру рецептов коптильни, наполнителя маны (Botania) и измельчителя (Thermal Expansion):\ <mark style="color:blue;">**recipetype:minecraft:smoking**</mark>\ <mark style="color:blue;">**recipetype:botania:mana\_infusion**</mark>\ <mark style="color:blue;">**recipetype:thermal:pulverizer**</mark>

Ванильные менеджеры рецептов (глобальная переменная является альтернативой обработчику):

<div align="left"><figure><img src="/files/qgu0U6Ee2AroG7IcyI5f" alt=""><figcaption></figcaption></figure></div>


# Удаление рецептов

В данном разделе Вы найдёте различные принципы удаления игровых рецептов.

1. Образец удаления рецептов: `Обработчик (глобальная переменная).removeRecipe(удаляемый объект);`

Например, текст ниже удаляет рецепт палки для верстака: `craftingTable.removeRecipe(item:minecraft:stick);`

2. Удаление по имени рецепта: `removeByName(String name);`

Также сначала указывается обработчик или глобальная переменная, а затем в скобках название рецепта (пример ниже удаляет рецепт стрелы из ванильного minecraft, при этом рецепты стрелы с другими именами удалены не будут!): `craftingTable.removeByName("minecraft:arrow");`

3. Удаление всех рецептов мода: `removeByModid(modid);`

Пример, удаляющий все рецепты minecraft: `craftingTable.removeByModid("minecraft");`

Если Вам необходимо удалить все рецепты мода «КРОМЕ», используйте следующий скрипт (удаляет все рецепты minecraft, кроме рецепта оранжевой шерсти, записанного в виде имени рецепта):

{% code fullWidth="false" %}

```typescript
craftingTable.removeByModid("minecraft", (name as string) => {
    return name == "orange_wool";
});
```

{% endcode %}

Состоит из: обработчика/глобальной переменной.метода удаления(«modid», функции (name as string) => {return name == «название рецепта»;});.

4. Удаление всех рецептов определенного менеджера рецептов: `Обработчик (глобальная переменная).removeAll();`

Пример, удаляющий все рецепты для плавильной печи: `blastFurnace.removeAll();`


# Рецепты для верстака

Рецепты верстака делятся на **форменные** (важно расположение элементов, элементы крафта должны находиться в конкретных ячейках верстака) и **бесформенные** (элементы крафта могут располагаться любым образом).

## Бесформенные рецепты

### Синтаксис

`craftingTable.addShapeless("recipe_name", output, [input]);`

где\
*<mark style="color:blue;">**recipe\_name**</mark>* – имя рецепта (может быть любым из еще не зарегистрированных),\
*<mark style="color:blue;">**output**</mark>* – результат крафта,\
*<mark style="color:blue;">**input**</mark>* – входной/входные предметы.

### Примеры

Снизу приведено 2 примера: в первом из земли создаются два алмаза, а во втором из глины и пшеницы - один хлеб. О статусе бесформенности рецепта говорит значок в виде переплетающихся стрелочек в правом верхнем углу.

{% code overflow="wrap" lineNumbers="true" %}

```lua
craftingTable.addShapeless("diamond_from_dirt", <item:minecraft:diamond> * 2, [<item:minecraft:dirt>]);
craftingTable.addShapeless("new_bread", <item:minecraft:bread>, [<item:minecraft:clay_ball>, <item:minecraft:wheat>
]);
```

{% endcode %}

<div><figure><img src="/files/gqAuUmf6BCOO8AukocDa" alt=""><figcaption></figcaption></figure> <figure><img src="/files/buSdkERR5cc79WMzzdte" alt=""><figcaption></figcaption></figure></div>

## Форменные рецепты

### Синтаксис

#### Для рецепта 2x2

```lua
craftingTable.addShaped("recipe_name", output, [ [input, input], [input, input] ]);
```

#### Для рецепта 3x3

```lua
craftingTable.addShaped("recipe_name", output, [ [input, input, input], [input, input, input], [input, input, input] ]);
```

где\
*<mark style="color:blue;">**recipe\_name**</mark>* – имя рецепта (может быть любым, из еще незарегистрированных, соответственно),\
*<mark style="color:blue;">**output**</mark>* – результат крафта,\
*<mark style="color:blue;">**input**</mark>* – входной/входные предметы.

В случае отсутствия предмета пишется <mark style="color:blue;">**item:minecraft:air**</mark>.

### Примеры

#### Пример рецепта 2x2

```lua
craftingTable.addShaped("netherite_recipe_new", <item:minecraft:netherite_ingot>, [ 
[<item:minecraft:gold_block>, <item:minecraft:netherite_scrap>], 
[<item:minecraft:fire_charge>, <item:minecraft:netherite_scrap>]
]);
```

<div align="left"><figure><img src="/files/sAmm1BmUdilgoXOGWJ8o" alt=""><figcaption></figcaption></figure></div>

#### Пример рецепта 3x3

```lua
craftingTable.addShaped("piston_recipe_new", <item:minecraft:piston>, [ 
[<tag:items:minecraft:logs>, <tag:items:minecraft:logs>, <tag:items:minecraft:logs>], 
[<item:minecraft:smooth_stone>, <item:minecraft:iron_bars>, <item:minecraft:smooth_stone>], 
[<item:minecraft:smooth_stone>, <item:minecraft:air>, <item:minecraft:smooth_stone>]
]);
```

<div align="left"><figure><img src="/files/8ohoiPAXKEMXg5dNNEY2" alt=""><figcaption></figcaption></figure></div>


# Рецепты для др. блоков

Различные функциональные блоки в Minecraft имеют уникальные формы создания рецептов в них.

## Печь

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.FurnaceManager;
furnace.addRecipe(name, output, input, xp, time);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input**</mark>* – входной элемент,\
*<mark style="color:blue;">**xp**</mark>* – опыт,\
*<mark style="color:blue;">**time**</mark>* – время рецепта в тиках.

Пример ниже плавит рычаг в красный факел за 3 секунды (60 тиков) с 15 единицами опыта.

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.FurnaceManager;
furnace.addRecipe("lever_to_torch", <item:minecraft:redstone_torch>, <item:minecraft:lever>, 15.0, 60);
```

{% endcode %}

<figure><img src="/files/1nvqppfYbVNIwvWJjMQu" alt=""><figcaption></figcaption></figure>

## Плавильная печь

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.BlastFurnaceManager;
blastFurnace.addRecipe(name, output, input, xp, time);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input**</mark>* – входной элемент,\
*<mark style="color:blue;">**xp**</mark>* – опыт,\
*<mark style="color:blue;">**time**</mark>* – время рецепта в тиках.

## Костёр

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.CampFireManager;
campfire.addRecipe(name, output, input, xp, time);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input**</mark>* – входной элемент,\
*<mark style="color:blue;">**xp**</mark>* – опыт,\
*<mark style="color:blue;">**time**</mark>* – время рецепта в тиках.

## Коптильня

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.SmokerManager;
smoker.addRecipe(name, output, input, xp, time);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input**</mark>* – входной элемент,\
*<mark style="color:blue;">**xp**</mark>* – опыт,\
*<mark style="color:blue;">**time**</mark>* – время рецепта в тиках.

## Стол кузнеца

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.SmithingManager;
smithing.addRecipe(name, output, input_base, input_add);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input\_base**</mark>* – входной элемент (основной),\
*<mark style="color:blue;">**input\_add**</mark>* – входной элемент (дополнительный).

## Камнерез

Общая форма рецептов для печки выглядит следующим образом:&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```java
import crafttweaker.api.StoneCutterManager;
stoneCutter.addRecipe(name, output, input);
```

{% endcode %}

где\
*<mark style="color:blue;">**name**</mark>* – имя рецепта,\
*<mark style="color:blue;">**output**</mark>* – результат рецепта,\
*<mark style="color:blue;">**input**</mark>* – входной элемент.


# Массивы и циклы

Для работы одновременно с большим количеством предметов и данных удобно использовать массивы.

Массивы имеют следующий вид:

`var arr = ["A", "B", "C"] as string[];`

`var arr = [item, item, item];`

где\
*<mark style="color:blue;">**arr**</mark>* – имя массива (может быть почти любым),\
*<mark style="color:blue;">**as string**</mark>* – тип данных массива,\
*<mark style="color:blue;">**\[]**</mark>* – сам массив.

Массивы удобно применять с циклами и условными операторами.

Пример использования цикла for с массивами для добавления рецептов печки:

{% code lineNumbers="true" %}

```java
import crafttweaker.api.FurnaceManager;
var name = ["clay_to_brick", "packed_ice_to__ice", "grass_to_dir"] as string[];
var output = [<item:minecraft:bricks>, <item:minecraft:ice>, <item:minecraft:dirt>];
var input = [<item:minecraft:clay>, <item:minecraft:packed_ice>, <item:minecraft:grass_block>];
for i, item in output {
    furnace.addRecipe(name[i], item, input[i], 1.0, 30);
}
```

{% endcode %}

В этом примере первый массив name содержит список имен рецептов, массив <mark style="color:blue;">**output**</mark> – результат плавки, а массив <mark style="color:blue;">**input**</mark> – входные элементы. Затем создается цикл, который последовательно обрабатывает рецепт плавки для всех элементов массива.


# Работа с тэгами

Большинство предметов имеют тэги – определенные группы, объединяющие несколько предметов или жидкостей, имеющих что-то общее. Например, каменный уголь и древесный уголь связаны тэгом <mark style="color:blue;">**tag:items:minecraft:coals**</mark>. Ниже рассмотрим детали работы с тегами:

## Импорт тэгов

Сначала необходимо импортировать тэги. Делается это следующим кодом:

```java
import crafttweaker.api.tag.MCTag;
```

Добавление предметов в тэг Добавить предмет можно как в существующий тэг, так и в новый (при этом для создания нового тэга не требуются дополнительные строчки). Общая форма добавления имеет следующий вид:

```java
MCTag.add(items); 
```

где <mark style="color:blue;">**MCTag**</mark> – существующий или новый тэг, <mark style="color:blue;">**item**</mark> - предмет.

Следующий пример добавляет бедрок в новый, ранее не существовавший, тэг <mark style="color:blue;">**tag:items:forge:saudade\_gems**</mark>:

```java
tag:items:forge:saudade_gems.add(item:minecraft:bedrock); 
```

Помимо одного предмета, можно добавить сразу несколько предметов, используя массив или тэг в тэг. При этом общая форма остается аналогичной ранее упомянутой.

Пример ниже добавляет железный и золотой слиток, записанные в массив, в ранее используемый тэг <mark style="color:blue;">**tag:items:forge:saudade\_gems**</mark>:

```java
tag:items:forge:saudade_gems.add([
    item:minecraft:iron_ingot, 
    item:minecraft:gold_ingot
]);
```

Следующий пример добавляет тэг <mark style="color:blue;">**tag:items:forge:rods**</mark> в тэг <mark style="color:blue;">**tag:items:forge:saudade\_gems**</mark>:&#x20;

<pre class="language-java"><code class="lang-java">tag:items:forge:saudade_gems.add(
<strong>    tag:items:forge:rods
</strong>);
</code></pre>

## Удаление предмета из тэга

Для удаления предмета из тэга используется форма, аналогичная добавлению лишь с той разницей, что <mark style="color:blue;">**add**</mark> меняется на <mark style="color:blue;">**remove**</mark>:

```java
MCTag.remove(items); 
```

где <mark style="color:blue;">**MCTag**</mark> – существующий или новый тэг, <mark style="color:blue;">**item**</mark> - предмет.

Пример ниже удаляет красный песок из общего тэга <mark style="color:blue;">**tag:items:minecraft:sand**</mark>, объединяющего обычный и красный песок:

```java
tag:items:minecraft:sand.remove(item:minecraft:red_sand);
```

В удалении также можно использовать вместо предмета массив предметов или другой тэг.


# Армированные мобы

Используя мод-дополнение <mark style="color:blue;">**ArmoreableMobs**</mark>, Вы можете изменить экипировку мобов.

Сначала необходимо импортировать группы мода:

```java
import mods.armoreablemods.ArmorGroup;
```

Создание новой группы:

```java
new ArmorGroup(group_name)
```

Установка предмета и слота:

```java
.inSlot(slot, item)
```

Устанавливается вес появления экипировки:

```java
.setWeight(x)
```

Регистрация сущности (моба), которая будет экипирована:&#x20;

```java
.register(entity);
```

где\
*<mark style="color:blue;">**group\_name**</mark>* – имя группы (может быть почти любым),\
*<mark style="color:blue;">**slot**</mark>* – слот,\
*<mark style="color:blue;">**item**</mark>* – предмет, который будет находиться в слоту,\
*<mark style="color:blue;">**x**</mark>* – число, вес появления,\
*<mark style="color:blue;">**entity**</mark>* – сущность (моб).

### Доступные слоты:

* <mark style="color:blue;">**equipmentslottype:head**</mark> - шлем;
* <mark style="color:blue;">**equipmentslottype:chest**</mark> - нагрудник;
* <mark style="color:blue;">**equipmentslottype:legs**</mark> - поножи;
* <mark style="color:blue;">**equipmentslottype:feet**</mark> - ботинки;
* <mark style="color:blue;">**equipmentslottype:mainhand**</mark> - ведущая рука;
* <mark style="color:blue;">**equipmentslottype:offhand**</mark> - второстепенная рука.

Пример, создающий новую группу: зомби в железной броне с железным мечом и щитом.

```java
import mods.armoreablemods.ArmorGroup;

new ArmorGroup("zombie_test_1")
    .inSlot(<equipmentslottype:head>, <item:minecraft:iron_helmet>)
    .inSlot(<equipmentslottype:chest>, <item:minecraft:iron_chestplate>)
    .inSlot(<equipmentslottype:legs>, <item:minecraft:iron_leggings>)
    .inSlot(<equipmentslottype:feet>, <item:minecraft:iron_boots>)
    .inSlot(<equipmentslottype:mainhand>, <item:minecraft:iron_sword>)
    .inSlot(<equipmentslottype:offhand>, <item:minecraft:shield>)
    .setWeight(5.0)
    .register(<entitytype:minecraft:zombie>);
```

<div align="left"><figure><img src="/files/9qoflsOgo4oWkEwXV3Dx" alt=""><figcaption></figcaption></figure></div>


# Эффекты экипировки

Используя мод-дополнение <mark style="color:blue;">**ArmorSetEffect**</mark>, вы можете добавить экипировке специальные эффекты.

Сначала необходимо импортировать группы мода:

```java
import mods.seteffect.ArmorSetEffect;
```

Затем создается новый эффект для экипировки (в примере `iron_set`). Потом перечисляются элементы брони с указанием слотов, в которых они должны находиться: `.inSlot(slot, item)`

После устанавливаются дополнительные параметры, по типу:&#x20;

* `addParticle(particles, particle_options)` – добавляет частицы при ношении брони.
* `.setIgnoreNBT()` – для игнорирования NBT,
* `.requireGamestages("saudade")` – для учета эры при наличии мода Game Stages,
* `.setPackmode("saudade_mode")` – для учета режима при наличии мода PackMode.
* `.applyFlight(true/false)` – для установки возможности летать при надетой броне.

И теперь самое главное – эффекты:

* `.addEffect(effect.newInstance(time, level).hideParticles())` – устанавливает эффект, накладываемый при ношении брони;
* `.addImmunity(effect)` – дает иммунитет к эффекту при ношении брони;
* `.addAttackerEffect(effect:minecraft:poison.newInstance(time, level))` – накладывает эффект на атакующее существо.

где\
*<mark style="color:blue;">**slot**</mark>* – слот,\
*<mark style="color:blue;">**item**</mark>* – предмет экипировки,\
*<mark style="color:blue;">**effect**</mark>* – эффект,\
*<mark style="color:blue;">**time**</mark>* – длительность эффекта в тиках (1 секунда = 20 тиков)\
*<mark style="color:blue;">**level**</mark>* – уровень эффекта,\
*<mark style="color:blue;">**particles**</mark>* – вид частиц,\
*<mark style="color:blue;">**particle\_options**</mark>* – настройки частиц.

## Пример для железной брони

* Устанавливает эффект скорости без частиц
* Добавляет иммунитет от слепоты
* Накладывает эффект отравления на атакующих врагов
* Добавляет частицы злых жителей при надетой брони

<pre class="language-java"><code class="lang-java">import mods.seteffect.ArmorSetEffect;

<strong>val iron_set = new ArmorSetEffect("iron_set")
</strong>    .inSlot(&#x3C;equipmentslottype:head>, &#x3C;item:minecraft:iron_helmet>)
    .inSlot(&#x3C;equipmentslottype:chest>, &#x3C;item:minecraft:iron_chestplate>)
    .inSlot(&#x3C;equipmentslottype:legs>, &#x3C;item:minecraft:iron_leggings>)
    .inSlot(&#x3C;equipmentslottype:feet>, &#x3C;item:minecraft:iron_boots>)
    .setIgnoreNBT()
    .addEffect(&#x3C;effect:minecraft:speed>.newInstance(100, 5).hideParticles())
    .addImmunity(&#x3C;effect:minecraft:blindness>)
    .addAttackerEffect(&#x3C;effect:minecraft:poison>.newInstance(60, 1))
    .addParticle("minecraft:angry_villager", 1.0f, 1.0f, 1.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, -5.0f, -5.0f, -5.0f, 2.0f, 0.3f, 2);
iron_set.register();
</code></pre>


# Стартовые предметы

Используя мод-дополнение <mark style="color:blue;">**InitialInventory**</mark>, Вы можете установить предметы, выдаваемые в начале игры.

Сначала необходимо импортировать группы мода:

```java
import mods.initialinventory.InvHandler;
```

Затем можно добавлять предметы. Ниже приведены простые формы для добавления предметов: `InvHandler.addStartingItem(name, item);` или `InvHandler.addStartingItem(name, item, index);`

где\
*<mark style="color:blue;">**name**</mark>* – имя функции добавления,\
*<mark style="color:blue;">**item**</mark>* – выдаваемый предмет,\
*<mark style="color:blue;">**index**</mark>* – дополнительный параметр номера слота в инвентаре (индексация слотов начинается с 0).

<div align="left"><figure><img src="/files/W0fWOjuF0U5b1RVKeIp0" alt=""><figcaption><p>Индексация слотов</p></figcaption></figure></div>

Ниже приведены примеры: первый выдает 3 яблока, а второй - каменную лопату в слот с индексом 5.

```java
import mods.initialinventory.InvHandler;

InvHandler.addStartingItem("apples", <item:minecraft:apple> * 3);
InvHandler.addStartingItem("stone_shovel", <item:minecraft:stone_shovel>, 5);
```

<figure><img src="/files/WjiCpIzXMaaccIoWkfav" alt=""><figcaption></figcaption></figure>


# Minecraft 1.19.2


# Секвенция

Невероятно мощная штука в ситуациях, когда Вам нужны инструменты для реализации скриптов с последовательным выполнением или таймером.

Находится он в <mark style="color:blue;">**level$sequence**</mark>. Приведём пример на основе <mark style="color:blue;">**crafttweaker.api.event.entity.player.ItemPickupEvent**</mark>.

## Пример секвенции

```java
import crafttweaker.api.event.entity.player.ItemPickupEvent;
import crafttweaker.api.events.CTEventManager;
CTEventManager.register<crafttweaker.api.event.entity.player.ItemPickupEvent>((event) => {
    var player = event.player;
    if (player.level.isClientSide) return;
    var level = player.level;
    var item = event.getStack();
    if (item.registryName == <item:minecraft:dirt>.registryName) level.sequence();
});
```

Сиквенцер создаётся просто, вдобавок в него можно поместить <mark style="color:blue;">**MapData**</mark>, которая будет хранить какие-либо параметры.

```java
level.sequence({version: "1.0.0"});
```

Но писать <mark style="color:blue;">**MapData**</mark> необязательно, она может иметь пустое значение.

```java
level.sequence();
```

Создадим такой код, который будет выдавать игроку через <mark style="color:blue;">**100 ticks**</mark> алмаз, если он подберёт землю.

```java
level.sequence().addTask(new SleepTask(100)).run((player, context) => player.inventory.add(<item:minecraft:diamond>));
```

Для удобства объяснения я буду объяснять всё на уровне кода, а точнее по нижнему примеру. Давайте разбираться.

```java
level.sequence().addTask(ISequenceTask<T,U>).run(BiConsumer<T,SequenceContext<T,U>>);
```

В методе <mark style="color:blue;">**addTask**</mark> у нас во входных параметрах выступает <mark style="color:blue;">**ISequenceTask**</mark>, в конструкторе которого есть <mark style="color:blue;">**T**</mark> и <mark style="color:blue;">**U**</mark>, они являются <mark style="color:blue;">**Objects**</mark>, то есть любой объект, будь то <mark style="color:blue;">**int**</mark> или передача собственного класса.

В самом <mark style="color:blue;">**craftTweaker**</mark> есть самобытное задание - это <mark style="color:blue;">**SleepTask**</mark>. У него есть метод <mark style="color:blue;">**tick**</mark>, который имеет входные параметры <mark style="color:blue;">**T**</mark> и <mark style="color:blue;">**SequenceContext\<T,U>**</mark>.

Вы можете вызывать sequence по завершении иного <mark style="color:blue;">**sequence**</mark>. Для этого в метод <mark style="color:blue;">**tick**</mark> мы должны передать <mark style="color:blue;">**level**</mark> и <mark style="color:blue;">**SequenceContext**</mark> и в него же передать наш <mark style="color:blue;">**sequnce**</mark> по окончании которого запустится другой <mark style="color:blue;">**sequence**</mark> и <mark style="color:blue;">**MapData**</mark>, в которую будет записана информация для выполнения.

{% code lineNumbers="true" %}

```java
import crafttweaker.api.util.sequence.SequenceContext;
import crafttweaker.api.sequence.task.ISequenceTask;
import crafttweaker.api.data.MapData;

var sequence1 = level.sequence().addTask(new SleepTask(100)).run((player, context) => player.inventory.add(<item:minecraft:diamond>));
var task = new SleepTask(20).tick(level, new SequenceContext(sequence1, new MapData()));
if (task.isComplete()) {
    var sequence2=leve.sequence().addTask(new SleepTask(60)).run((player,context)=>player.sendMessage("Во работает"));
}
```

{% endcode %}

Секвенция невероятно сложная тема без внятной документации. Всё написанное здесь базируется на личном опыте журналиста.

В методе <mark style="color:blue;">**run**</mark> во входных данных используется <mark style="color:blue;">**BiConsumer\<T,U>**</mark>: вместо <mark style="color:blue;">**U**</mark> у нас <mark style="color:blue;">**SequenceContext\<T,U>**</mark>.

В <mark style="color:blue;">**T**</mark> мы пишем любой <mark style="color:blue;">**Object**</mark>, который хотим использовать. В нашем случае это <mark style="color:blue;">**player**</mark>. Заместо <mark style="color:blue;">**SequenceContext\<T,U>**</mark> Вы можете написать какой-либо другой <mark style="color:blue;">**Object**</mark>, но это не рекомендуется.

Т.е., Вы можете написать `run((player, level) => {})`, и оно будет работать. Но, если Вам понадобится <mark style="color:blue;">**SequenceContext**</mark>, уже его получить не удастся.

***

## <mark style="color:blue;">InstantTask</mark>

Поговорим теперь про все <mark style="color:blue;">**Task**</mark>, которые у нас существуют. Он выполняется немедленно, в отличие от <mark style="color:blue;">**SleepTask**</mark> и <mark style="color:blue;">**SleepUntilTask**</mark>.

```java
import import crafttweaker.api.sequence.task.type.InstantTask;
level.sequence().addTask(new InstantTask((player, context) => player.sendMessage("Я выполняюсь мгновенно!")));
```

***

## <mark style="color:blue;">SleepUntilTask</mark>

В отличие от <mark style="color:blue;">**SleepTask**</mark>, секвенция будет остановлена, пока условие не будет выполнено.

```java
import crafttweaker.api.sequence.task.type.SleepUntilTask;
level.sequence().addTask(new SleepUntilTask((player, context) => player.inventory.contains(<item:minecraft:diamond>))).run((player, context) => player.sendMessage("Вау, у тебя есть алмаз !"));
```


# Реплейсер

Надоело ли Вам постоянно удалять рецепт, когда нужно изменить значение всего 1 предмета? Если да, то это разработано специально для Вас!

Перед объяснением работы <mark style="color:blue;">**Replacer**</mark>, Вам стоит знать следующее, чтобы избежать возможных проблем с производительностью: Старайтесь использовать как можно меньше <mark style="color:blue;">**Replacer**</mark> и объединять все <mark style="color:blue;">**Replacer**</mark> в один!

В начале Вам стоит правильным образом портировать <mark style="color:blue;">**crafttweaker.api.recipe.replacement.Replacer**</mark>.

После чего создайте `Replacer.create()`.

```java
import crafttweaker.api.recipe.replacement.Replacer;
Replacer.create();
```

***

## <mark style="color:blue;">filter</mark>

Теперь разберём ряд методов. Первым будет `filter` Он отвечает, при каких условиях будет происходить замена предмета. Список того, какие условия есть на момент написания статьи:

* ComponentFilteringRule
* CustomFilteringRule
* ManagerFilteringRule
* ModsFilteringRule
* NameFilteringRule
* NotFilteringRule

В качестве примера мы разберём `ManagerFilteringRule`, `ModsFilteringRule` и `NameFilteringRule`.

***

## <mark style="color:blue;">**ManagerFilteringRule**</mark>

Начнём с `ManagerFilteringRule`. Он отвечает за то, в каком `<recypestype:` будет происходить замена.

Для того, чтобы получить список всех `recypesType` нужно написать команду `/ct dump recipetype`.

Допустим, мы хотим изменить рецепты только в верстаке. Для этого нужно написать следующее:

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.ManagerFilteringRule;

Replacer.create().filter(ManagerFilteringRule.of([<recipetype:minecraft:crafting>]));
```

В таком случае `Replacer` будет работать только с верстаком.

***

## <mark style="color:blue;">**ModsFilteringRule**</mark>

Также существует фильтр `ModsFilteringRule`, который работает с рецептами из определённого мода.

Для примера изменим рецепты только из <mark style="color:blue;">**Divine RPG**</mark>

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.ModsFilteringRule;

Replacer.create().filter(ModsFilteringRule.of(["divinerpg"]));
```

Теперь Replacer будет работать только ко всем предметам из Divine RPG.

***

## <mark style="color:blue;">**NameFilteringRule**</mark>

Фильтр, который работает в ситуации, когда у предмета есть что-то в названии, например `hoe` или `axe`, тогда он будет производить замену.

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.NameFilteringRule;

Replacer.create().filter(NameFilteringRule.anyOf(["stone_axe", "wodden_hoe", "iron_block"]));
```

Здесь фильтр работает в соответствии с перечисленными наименованиями, не отклоняясь от этой траектории.

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.NameFilteringRule;

Replacer.create().filter(NameFilteringRule.containing("axe"));
```

Функционирует с предметами, в названии которых есть вышеперечисленное слово `pump == minecraft:pumpkin_pie`. Не учитывает регистр.

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.NameFilteringRule;

Replacer.create().filter(NameFilteringRule.regex("\\D{3}"));
```

Фильтр на основе заданного регулярного выражения. Для лучшего понимания этого прочитайте Регулярные выражения в Java replace.

Данный метод выполняет всю логику нашего Replacer. У него есть ряд параметров, рассмотрим же их.

```java
Replacer.replace<T : Object>(component as IRecipeComponent<T>, toReplace as T, with as T) as Replacer
```

`replace<T : Object>` - нужна чтобы сказать `Replacer` какой тип нужно изменять. Всегда это `IIngredient`, кроме случаев когда заменяем рецепт в модовом `recipeType`

`component as IRecipeComponent<T>` - отвечает к какому предмету в рецепте он будет применять изменение. Чтобы узнать все `IRecipeComponent` пропишите команду `/ct dump recipecomponent`.

`toReplace` - предмет который необходимо заменить. `with` - на что необходимо заменить.

***

## <mark style="color:blue;">execute</mark>

Заключительный метод, который обозначает конец нашего `Replacer` Replacer.

Теперь, для примера, создадим простой `Replacer`. Заменим все палки в рецептах из мода <mark style="color:blue;">**Divine RPG**</mark> на огненные стержни.

```java
import crafttweaker.api.recipe.replacement.Replacer;
import crafttweaker.api.recipe.replacement.type.ManagerFilteringRule;
import crafttweaker.api.recipe.replacement.type.ModsFilteringRule;
import crafttweaker.api.ingredient.IIngredient;

Replacer.create().filter(ModsFilteringRule.of(["divinerpg"])).filter(ManagerFilteringRule.of([<recipetype:minecraft:crafting>])).replace<IIngredient>(<recipecomponent:crafttweaker:output/items>, <item:minecraft:stick>, <item:minecraft:blaze_rod>).execute();
```


# Классы

В моде CraftTwekaer используется язык программирования zenScript, так что знания классов Вам будут очень полезны для написания профессионального рода скриптов!

Создадим класс, который будет отвечать за данные <mark style="color:blue;">**entity**</mark>

## Пример

```java
public class EntityData {
    
}
```

Также нужно создать конструктор, который позволит динамически создавать класс, который не будет постоянно храниться в памяти. В любой другом ЯП мы бы писали следующим образом - `public EntityData(){}`, но в <mark style="color:blue;">**zenScript**</mark> стоит писать `public this(){}`.

## Пример

```java
public class  EntityData {
    public this() {
        
    }
}
```

Следует ещё добавить в класс наше существо или же <mark style="color:blue;">**Entity**</mark>. Необходимо импортировать его так - `import crafttweaker.api.entity.Entity;`. Кроме этого, нужно хранить данные или же <mark style="color:blue;">**IData**</mark>. Импортируем - `import crafttweaker.api.data.IData`.

## Пример

```java
import crafttweaker.api.entity.Entity;
import crafttweaker.api.data.IData;

public class EntityData {
    public val entity as Entity;
    public val data as IData;
    
    public this(entity as Entit, data as IDatay) {
        this.entity = entity;
        this.data = data;
    }
}
```

Теперь нам важно создать метод, который будет проверять, есть ли у существа или же <mark style="color:blue;">**Entity**</mark> соответствующие данные. Поможет в этом <mark style="color:blue;">**customData**</mark>, так как в data мы записать ничего не сможем. Ключевое слово <mark style="color:blue;">**in**</mark> аналогично <mark style="color:blue;">**contains & includes**</mark>.

```typescript
public isHaveData() as bool {
    if (this.data in this.entity.customData) return true;
    else return false;
}
```

Таким образом, у нас есть метод, который позволит проверить, есть ли у игрока нужные нам данные. После этого создадим нужно класс, который сможет записать в игрока новые данные.

## Пример

```typescript
public sendData() as bool {
    if (isHaveData()) return false;
    else this.entity.updateCustomData(this.data);
}
```

Теперь нас есть всё необходимое. Остаётся только применить данный класс. `crafttweaker.api.event.entity.player.ItemPickupEvent`.

## Пример

```java
import crafttweaker.api.events.CTEventManager;
import crafttweaker.api.event.entity.player.ItemPickupEvent;
CTEventManager.register<crafttweaker.api.event.entity.player.ItemPickupEvent>((event) => {
    var player = event.player;
    if (player.level.isClientSide) return;
    var myData as EntityData = new EntityData(player, {"firstPickUp" : true});
    myData.sendData();
});
```

При подборе любого предмета в игрока будут внесены новые данные в <mark style="color:blue;">**customData**</mark>. Вы можете задаться вопросом, как же мы передали player в наш класс, если в его параметрах <mark style="color:blue;">**Entity**</mark>? Всё потому, что игрок наследуется от <mark style="color:blue;">**EntityLiving**</mark>, а он, в свою очередь, от <mark style="color:blue;">**Entity**</mark>.

## Полный код

```typescript
import crafttweaker.api.entity.Entity;
import crafttweaker.api.data.IData;

public class EntityData {
    public val entity as Entity;
    public val data as IData;
    
    public this (entity as Entit, data as IDatay) {
        this.entity = entity;
        this.data = data;
    }

    public isHaveData() as bool {
        if (this.data in this.entity.customData) return true;
        else return false;
    }
    
    public sendData() as bool {
        if (isHaveData()) return false;
        else this.entity.updateCustomData(this.data);
    }
}
```


# ООП

Поговорим про наследование, ведь zenScript считается полноценным ЯП.

Создадим `virtual` класс `myEntity`, у которого будет параметр имени и метод `move`, не имеющий пока что действий.

## **Пример**

```java
public virtual class myEntity {
    public val name as string;
    public this(name as string) {
        this.name = name;
    }
    
    public move() as void {
        
    }
}
```

`virtual` означает, что мы сможем переопределить функции класса и сам класс. Создадим новый класс `myFish` и через `:` напишем `myEntity`. `:` - это будет значить, что мы наследуемся от следующего класса.

## **Пример**

```java
public class myFish : myEntity {
    public this() {
        super("bat");
    }
}
```

Про `suepr` прочитайте в документации по <mark style="color:blue;">**Java**</mark>. Переопределим наш метод `move` из класса `myEntity` в классе `myFish` с помощью `override`. Сделаем так, чтобы при вызове метода `move` в консоль выводилось какое-то сообщение.

```java
public override move() {
    println("Существо " + this.name as string + " перемещается !");    
}
```

Если мы вызовем данный метод, нам напечатается сообщение в `crafttwekaer.log`.

## **Пример**

```java
new myFish().move();
```

## **Полный Код**

```java
public virtual class myEntity {
    public val name as string;
    public this(name as string) {
        this.name = name;
    }
    
    public move() as void {
        
    }
}

public class myFish : myEntity {
    public this() {
        super("bat");
    }

    public override move() {
        println("Существо " + this.name as string + " перемещается !");
    }
}
```


# Интерфейсы

Здесь мы расскажем о том, как использовать интерфейсы. Они невероятно полезны при написании кода с множеством однотипных методов или иных элементов.

Создадим интерфейс `myInterface` у которого будет 2 метода `send` и `sum`

## **Пример**

```java
public interface myInterface{
    public send() as void;
    public sum(a as int, b as int) as int;
}
```

Внесём класс `myClass`

## **Пример**

```java
public class myClass{
}
```

Чтобы подключить наш интерфейс, необходимо написать следующее:

## **Пример**

```java
public class myClass {
    public implements myInterface {

    }
}
```

Теперь, подключив интерфейс, пишем в теле `myInterface` методы, которые заявленные ранее в `myInterface`.

## **Пример**

```java
public class myClass {
    public implements myInterface {
        public send() as void{
                
        }
        public sum(a as int, b as int) as int{
            return 0;
        }
    }
}
```

В методе `send` мы можем написать подобное - `println(sum(1, 2) as string)`.

## **Пример**

```java
public send() as void{
    println(sum(1, 2) as string);
}
```

При вызове данного метода нам вернётся `0`, далее исправим это! Добавим элемент сложения.

## **Пример**

```java
public sum(a as int, b as int) as int{
    return a + b;
}
```

Больше ошибок не будет. Можем вызвать метод `send`

## **Пример**

```java
new myClass().send();
```

Вы можете подключать неограниченное число различных интерфейсов!

## **Полный Код**

```java
public interface myInterface {
    public send() as void;
    public sum(a as int, b as int) as int;
}

public class myClass {
    public implements myInterface {
        public send() as void{
            println(sum(1, 2) as string);
        }
        public sum(a as int, b as int) as int{
            return a + b;
        }
    }
}
```


# KubeJS

Модификация, предоставляющая разработчику сборок свои собственные скрипты на языке JavaScript. С помощью скриптов Вы сможете изменять рецепты, добавлять новые блоки или предметы и многое другое.

Перед началом работы советуем подробнее ознакомиться с базой [JavaScript](https://www.w3schools.com/js/default.asp).


# Начало работы

Сперва Вам необходимо загрузить саму модификацию. Не забудьте также про зависимости для [KubeJS](https://www.curseforge.com/minecraft/mc-mods/kubejs) - [Architecture](https://www.curseforge.com/minecraft/mc-mods/architectury-api) и [Rhino](https://www.curseforge.com/minecraft/mc-mods/rhino).

Далее необходимо запустить игру, чтобы сгенерировались необходимые папки и файлы. После первого запуска в .minecraft будет создана папка kubejs (**.minecraft/kubejs**). Именно в ней Вы будете хранить все скрипты и файлы.

## **Содержание папки KubeJS**

* **assets** - в ней хранятся все текстуры, модели, переводы.
* **client\_scripts** - скрипты, которые загружаются каждый раз при перезагрузке и загрузке клиентских ресурсов. Используется для создания событий JEI, всплывающих подсказок и другого материала. Для перезагрузки скрипта можно использовать следующую игровую команду: `/kubejs reload client_scripts` или через комбинацию клавиш `F3+T`.
* **config** - настройки KubeJS.
* **data** - здесь расположены тэги, рецепты, таблицы лута.
* **exported** - в данной папке можно посмотреть выгруженные предметы и рецепты.
* **server\_scripts** - скрипты, которые загружаются каждый раз при перезагрузке ресурсов сервера (world load, `/reload`). Используется для изменения рецептов, тегов, таблиц добычи, а также для обработки событий сервера Для перезагрузки скрипта можно использовать следующую игровую команду: `/kubejs reload server_scripts`
* **startup\_scripts** - скрипты, которые загружаются один раз во время запуска игры. Используется для добавления предметов и других вещей, которые могут происходить только во время загрузки игры Для перезагрузки скрипта можно использовать следующую игровую команду: `/kubejs reload_startup_scripts` Чтобы перезагрузить весь код, вы должны перезапустить игру.


# Ивенты

В KubeJS всё выполняется благодаря **Ивентам**/**Events**, которые делятся на:

* **Startup** - Выполняется при **Загрузке** **Майнкрафт**.
* **Server** - Выполняется на стороне **Сервера.**
* **Server Startup** - Выполняется при **Загрузке Сервера.**
* **Client** - Выполняется на стороне **Клиента.**
* **Client Startup** - Выполняется при **Загрузке Клиента.**

*Также некоторые Events можно отменить.*


# Ваш первый скрипт

В папке KubeJS откройте файл <mark style="color:blue;">**server\_script**</mark>, а затем - <mark style="color:blue;">**script.js**</mark>. Вы увидите следующий код, который мы рассмотрим далее:

```javascript
// priority: 0
settings.logAddedRecipes = true
settings.logRemovedRecipes = true
settings.logSkippedRecipes = false
settings.logErroringRecipes = true
console.info('Hello, World! (You will see this line every time server resources reload)')
onEvent('recipes', event => {
 // Change recipes here
})
onEvent('item.tags', event => {
 // Get the #forge:cobblestone tag collection and add Diamond Ore to it
 // event.get('forge:cobblestone').add('minecraft:diamond_ore')
 // Get the #forge:cobblestone tag collection and remove Mossy Cobblestone from it
 // event.get('forge:cobblestone').remove('minecraft:mossy_cobblestone')
})
```

**//priority** - устанавливает приоритет скрипта 0-∞.

За отображение информации в логах отвечают следующие параметры:

* **settings.logAddedRecipes** - Добавление рецепта.
* **settings.logRemovedRecipes** - Удаление рецепта.
* **settings.logSkippedRecipes** - Пропуск рецепта.
* **settings.logErroringRecipes** - Ошибки в рецепте.

**console.info** - выводит сообщение в logs. **onEvent('recipes', event => {** - регистрация Event. **'recipes'**, - имя Event.

Теперь создадим первый скрипт. Мы добавим рецепт для кремня из 3-х гравия.

У нас для таких целей есть **2 способа:**

1. Форменный рецепт (**shaped**)
2. Бесформенный рецепт (**shapeless**)

Мы воспользуемся 2 способом, так как нам не нужна строгая последовательность.

```javascript
// priority: 0
settings.logAddedRecipes = true
settings.logRemovedRecipes = true
settings.logSkippedRecipes = false
settings.logErroringRecipes = true
console.info('Hello, World! (You will see this line every time server resources reload)')
onEvent('recipes', event => {
 // Change recipes here
 event.shapeless("flint", ["gravel", "gravel", "gravel"])
})
onEvent('item.tags', event => {
 // Get the #forge:cobblestone tag collection and add Diamond Ore to it
 // event.get('forge:cobblestone').add('minecraft:diamond_ore')
 // Get the #forge:cobblestone tag collection and remove Mossy Cobblestone from it
 // event.get('forge:cobblestone').remove('minecraft:mossy_cobblestone')
})

```

Теперь сохраним и напишем в чате игры `/reload` для запуска изменений.

<div align="left"><figure><img src="/files/S8E8G6BLmQs80VJJWbKR" alt=""><figcaption></figcaption></figure></div>


# Удаление рецепта

**Шаблон скрипта для удаления рецепта:**

```javascript
onEvent('recipes', event => {
 event.remove({output: 'minecraft:stick'})
})
```


# Форменные рецепты

Теперь добавим **форменный рецепт**. Разработаем рецепт саженца дуба из 6 губок и 2 яблок

```javascript
onEvent('recipes', event => {
 // Change recipes here
 event.shapeless("flint", ["gravel", "gravel", "gravel"])
 event.shaped('minecraft:oak_sapling', [
 'SAS',
 'S S',
 'SAS'
 ], {
 S: 'minecraft:sponge',
 A: 'minecraft:apple'
 })
})
```

Расположите ресурсы в скрипте, ориентируясь на интерфейс верстака (3х3).

<div align="left"><figure><img src="/files/Ibhimd0UylcAiX6PqxnZ" alt=""><figcaption></figcaption></figure></div>


# Создание предмета

Теперь мы попробуем создать свой собственный предмет. Добавим осколок, который будет называться *Теневой кусочек.* Первым делом переместите свою текстуру предмета в **KubeJS —> assets —> kubejs —> textures —> item**. Название текстуры должно быть с маленькой буквы и на английском языке *(shadow\_piece)*.

Откройте папку **KubeJS —> startup\_scripts —> script.js**

```javascript
// priority: 0
console.info('Hello, World! (You will only see this line once in console, during startup)')
onEvent('item.registry', event => {
// Register new items here
// event.create('example_item').displayName('Example Item')
})
onEvent('block.registry', event => {
 // Register new blocks here
 // event.create('example_block').material('wood').hardness(1.0).displayName('Example Block')
})
```

Здесь нам нужен **item.registry** Для добавления предмета нам необходимо написать `event.create('имя вашего предмета')`

**Список методов:**

* **maxStackSize(size)** - Максимальное количество в стаке 1-64.
* **displayName(name)** - Отображаемое имя предмета.
* **unstackable()** - Установка предмета, невозможного к стаку.
* **maxDamage(damage)** - Максимальная прочность предмета.
* **burnTime(ticks)** - Время горения.
* **glow(bool)** - Заставляет предмет светиться (как зачарованный).
* **rarity('rarity')** - Редкость предмета.
* **group('group\_id')** - Группа предметов.
* **color(index, colorHex)** - Цвет предмета.
* **texture(customTexturePath)** - Собственное расположение текстуры.
* **parentModel(customParentModel)** - Модель предмета.
* **food(foodBuilder => ...)** - Создание еды.
* **tier('toolTier')** - Уровень инструмента.
* **modifyTier(tier => ...)** - Тот же синтаксис, что и у пользовательского уровня инструментов.
* **attackDamageBaseline(damage)** - Урон предмета.
* **attackDamageBonus** - Дополнительный урон.
* **speedBaseline**
* **speed**

Для примера, создадим предмет, который будет храниться по 32 шт., а также сможет гореть 340 тиков (17 секунд).

```javascript
event.create('shadow_piece').maxStackSize(32).burnTime(340)
```

После добавления собственного ресурсы нужно добавить к нему перевод. Перемещаемся: **kubejs —> assets —> kubejs**. Создаём папку **lang**, а в ней файл `en_us.json` и `ru_ru.json`

```javascript
{
 "item.kubejs.shadow_piece": "Shadow Piece"
}
```

Тоже самое делаем для `ru_ru.json`.

```javascript
{
 "item.kubejs.shadow_piece": "Теневой кусочек"
}
```

**Создадим свою кирку и меч:**

```javascript
//Мечь
event.create('custom_sword','sword').tier('diamond').attackDamageBaseline(10.0)
//Кирка
event.create('custom_pickaxe','pickaxe').tier('diamond').maxDamage(5)
```

**Допустимые типы предметов:**

* `"basic"` – Базовый.
* `"sword"` – Меч.
* `"pickaxe"` – Кирка.
* `"axe"` – Топор.
* `"shovel"` – Лопата.
* `"hoe"` – Мотыга.
* `"helmet"` – Шлем.
* `"chestplate"` – Нагрудник.
* `"leggings"` – Поножи.
* `"boots"` – Ботинки.

**Методы, доступные, если вы используете тип `"sword"`, `"pickaxe"`, `"axe"`, `"shovel"` или `"hoe"`:**

* `"wood"` – Дерево.
* `"stone"` – Камень.
* `"iron"` – Железо.
* `"gold"` – Золото.
* `"diamond"` – Алмаз.
* `"netherite"` – Незерит.

**Методы, доступные, если Вы используете тип `"helmet"`, `"chestplate"`, `"leggings"` или `"boots"`:**

* `"leather"` – Кожа.
* `"chainmail"` – Кольчуга.
* `"iron"` – Железо.
* `"gold"` – Золото.
* `"diamond"` – Алмаз.
* `"turtle"` - Черепаший панцирь.
* `"netherite"` – Незерит.

<div align="left"><figure><img src="/files/ZGlj8duKMJ0YMFl05PhZ" alt=""><figcaption></figcaption></figure></div>


# Кастомный тир

*Что делать, если Вы вдруг захотели сделать кирку с уровнем добычи выше незерита?* Вам нужно создать свой собственный тир предметов, в котором установите уровень добычи. Помимо уровня добычи так же можно добавить прочность, скорость добычи, уровень зачарования, урон и предмет для починки.

***

**Создадим новый ивент** `item.registry.tool_tiers`

```javascript
// priority: 0
console.info('Hello, World! (You will only see this line once in console, during startup)')
onEvent('item.registry.tool_tiers', event => {
 event.add('godtier', tier => {
 tier.uses = 5000
 tier.speed = 12.0
 tier.attackDamageBonus = 14.0
 tier.level = 6
 tier.enchantmentValue = 14
 tier.repairIngredient = '#forge:ingots/iron'
 })
})
onEvent('item.registry', event => {
 event.create('shadow_piece').maxStackSize(32).burnTime(340)
 //Мечь
 event.create('custom_sword', 'godtier').tier('diamond').attackDamageBaseline(10.0)
 //Кирка
 event.create('custom_pickaxe', 'godtier').tier('diamond')
})

```

Рассмотрим данный скрипт:

* **event.add(’имя тира’, tier ⇒** { - создание нового тира.
* **tier.uses** - Прочность предметов.
* **tier.speed** - Скорость добычи.
* **tier.attackDamageBonus** - Бонусный урон.
* **tier.level** - Уровень добычи.
* **tier.enchantmentValue** - Уровень зачарований.
* **tier.repairIngredient** - Предмет для починки.

И теперь вместо значения `diamond` мы ставим свой тир – `godtier`.


# Использование предмета

Начнём с того, что у нас есть 2 способа использовать предмет:

1. Нажать `ПКМ`, держа в руке предмет `item.right_click`
2. Нажимать предметом `ПКМ` по блоку `block.right_click`

**Разберём первый способ.**

Зайдите в папку с серверным скриптом. Вы можете создать новый скрипт **.js** или писать всё в **script.js**. Нам нужно установить приоритет `// priority: 0`, а потом создать ивент -`item.right_click onEvent(’item.right_click’, event => {})`

Далее понадобится вывести сообщение в чат, чтобы убедиться в правильности работы скрипта - `Utils.server.tell("Вы используете n-ый предмет")`

```javascript
// priority: 0
onEvent('item.right_click', event => {
 Utils.server.tell("Вы используете какой-то предмет")
})
```

Пишем `/reload` и пытаемся нажать `ПКМ` с любым предметом в руке Теперь попробуем вывести сообщение при использовании алмаза: Если `event.item.id == ‘minecraft:diamond’` то `Utils.server.tell("Вы используете Алмаз")`

```javascript
onEvent('item.right_click', event => {
 if(event.item.id == 'minecraft:diamond'){
 Utils.server.tell("Вы используете Алмаз")
 }
})
```

Пишем `/reload` и проверяем использование Алмаза с зажатым `ПКМ`. Давайте теперь удалим Алмаз при применении. Для этого воспользуемся: `item.setCount` и `item.getCount (Int)`

Нам нужно установить количество предметов, которое мы получим при применении, а потом заберём 1 шт.

```javascript
onEvent('item.right_click', event => {
 if(event.item.id == 'minecraft:diamond'){
 event.item.setCount( event.item.getCount() - 1)
 Utils.server.tell("Вы используете Алмаз")
 }
})
```

Давайте теперь выдадим предмет игроку (изумруд) после удаления алмаза: `player.give`

```javascript
onEvent('item.right_click', event => {
 if(event.item.id == 'minecraft:diamond'){
 event.item.setCount( event.item.getCount() - 1)
 Utils.server.tell("Вы используете Алмаз")
 event.player.give('minecraft:emerald')
 }
})
```

Но что, если мы хотим выдать игроку изумруд при использовании алмаза на Изумрудном блоке? Тогда нам нужно использовать другой ивент: `block.right_click`

В этом примере будем использовать константу var, чтобы упростить понимание кода.

Опираемся на конструкцию: `item.id` `block.id` `player.give`

```javascript
onEvent('block.right_click', event => {
 var block = event.block;
 var blockid = block.id;
 var item = event.item;
 var itemid = item.id;
 var player = event.player;
 if(itemid == 'minecraft:diamond' && blockid == 'minecraft:emerald_block'){
 event.item.setCount( item.getCount() - 1)
 event.player.give('minecraft:emerald')
 }
})
```


# Взаимодействие с миром

{% hint style="danger" %}
**Не работает на версиях ниже 1.18.2!**
{% endhint %}

KubeJS (Cкрипт, который манипулирует погодой, т.е. выключает дождь или ставит день):

```javascript
onEvent('level.tick', event => {
 if(event.level.raining){
 Utils.server.runCommandSilent(weather clear)
 }
 if(!event.level.daytime){
 Utils.server.runCommandSilent(time set 999)
 }
})
```


# Смена названия окна и иконки игры

Для того, чтобы **изменить название окна** необходимо найти файл <mark style="color:blue;">**client.properties**</mark> (путь к файлу: <mark style="color:blue;">**kubejs/config/client.properties**</mark>), открыть его, далее перейти к строке `"title="` и напротив написать собственное название. *Например, `"title= MoonLight"`.*

**Чтобы изменить иконку игры**, Вы должны добавить изображение по пути: <mark style="color:blue;">**kubejs/config/packicon.png**</mark>

Предпочтительны стандартные текстуры Minecraft (*<mark style="color:blue;">64x64, 128x128, 256x256</mark>*).

{% hint style="warning" %}
**Изображение должно быть сохранено как 32-битный PNG-файл.**
{% endhint %}


# Перевод модификаций

Добавление перевода модификации осуществляется по пути: `kubejs/assets`.В качестве примера поработаем над модом <mark style="color:blue;">**dankstorage**</mark>. Для начала необходимо найти файл для перевода, для этого мы открываем архив мода, далее переходим в папку <mark style="color:blue;">**assets**</mark>, после направляемся в папку `названием мода, -> lang` и уже в ней находим и копируем файл <mark style="color:blue;">**en\_us**</mark>. Копируем его <mark style="color:blue;">**assets**</mark>, но не все так просто – нам понадобится создать файлу, который сделал разработчик мода и который мы видели в его архиве. В нашем случае путь будет такой: **`assets/dankstorage/lang/en_us`**. Файл, предназначенный для перевода (<mark style="color:blue;">**en\_us**</mark>) нужно переименовать в <mark style="color:blue;">**ru\_ru**</mark>. Теперь Вы можете открыть его и приступить к самому переводу.

<div align="left"><figure><img src="/files/OjXZHcfzUepPTR6MF7B6" alt=""><figcaption></figcaption></figure></div>

## Пример файлов в архиве мода

Каждый файл отвечает за свой язык, но для нас самый простой – <mark style="color:blue;">**en\_us**</mark>, потому что он на английском языке.

<div align="left"><figure><img src="/files/jEvJnubE8tiqX6OLPWaj" alt=""><figcaption><p>Весь путь к нужному файлу в архиве.</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/ltRnD53eEGwFyiwMjrPO" alt=""><figcaption><p>Весь путь к нужному файлу в kubejs, который сделали мы.</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/Lc5wh6WfGq8K7N7zPOXp" alt=""><figcaption><p>Имя файла для русского перевода.</p></figcaption></figure></div>


# Interactio

Этот мод добавляет возможность создавать предметы, блоки и жидкости новыми необычными способами.


# Предмет из жидкости

Рецепт, создающий предметы из жидкости и других предметов.

* **Вход**: предметы, жидкость&#x20;
* **Выход**: предметы

У жидкости можно указать тип и шанс потребления в каждом создаваемом рецепте. За это отвечает параметр `"consume_fluid":`` `<mark style="color:blue;">`x`</mark>, где <mark style="color:blue;">**x**</mark> – вероятность потребления.

* У входных предметов можно указать следующие параметры: предмет (item) или тег (tag), количество (count), шанс возврата предмета при совершении рецепта (return\_chance).
* У выходных предметов можно указать следующие данные: тип предмета, количество, вес предмета (при нескольких выходных предметов), вес неудачного крафта (empty\_weight), число попыток скрафтить предмет (rolls). Например, при 10 попытках и шансе неудачного крафта 0.2, шанс создания предмета в каждой из 10 попыток составляет 80%. Таким образом игрок, вероятнее всего, получит 8 выходов рецепта.

Также у всех предметов можно указать NBT-тэг в следующем формате:

```json
"nbt": {
  "Potion": "minecraft:water"
}
```

Пример рецепта в формате json приведен ниже:

```json
{
  "type": "interactio:item_fluid_transform",
  "inputs": [
    {
      "item": "minecraft:spruce_log",
      "count": 3,
      "return_chance": 0.75
    },
    {
      "tag": "forge:ingots/gold",
      "count": 2
    }
  ],
  "fluid": {
    "fluid": "water"
  },
  "output": {
    "entries": [
      {
        "result": {
          "item": "minecraft:diamond",
          "count": 2
        },
        "weight": 7
      },
      {
        "result": {
          "item": "minecraft:orange_wool",
          "count": 3
        },
        "weight": 10
      }
    ],
    "empty_weight": 83,
    "rolls": 10
  },
  "consume_fluid": 0.1
}
```

<figure><img src="/files/myTVMNJy8BLtV5AY9oWT" alt=""><figcaption></figcaption></figure>


# Жидкость из жидкости

Рецепт, создающий жидкости из предметов и других жидкостей.

* **Вход**: предметы, жидкость&#x20;
* **Выход**: предметы

У жидкости можно указать тип жидкости.

У входных предметов можно указать тип: предмет (item) или тег (tag), количество (count), шанс возврата предмета при совершении рецепта (return\_chance).

В значении выхода можно указать возможные к получению жидкости с шансом получения каждой.

**Пример рецепта** создания молока или латекса из воды и железа:

```json
{
  "type": "interactio:fluid_fluid_transform",
  "items": [
    {
      "tag": "forge:ingots/iron",
      "count": 4,
      "return_chance": 1
    }
  ],
  "input": {
    "fluid": "water"
  },
  "output": {
    "entries": [
      {
        "result": {
          "fluid": "industrialforegoing:milk"
        },
        "weight": 2
      },
      {
        "result": {
          "fluid": "industrialforegoing:latex"
        },
        "weight": 4
      }
    ],
    "empty_weight": 5
  }
}
```


# Создание взрывом

Рецепт, создающий предметы из предметов с помощью взрывов.

* **Вход**: предметы + взрыв рядом&#x20;
* **Выход**: предметы

Предметы в данном рецепте создаются посредством взрыва из других предметов.

У входных предметов можно указать: сам предмет (item), тег (tag) или количество (count).

У выходных предметов указываются: тип предмета, количество, вес предмета (при нескольких выходных предметов), вес неудачного крафта (empty\_weight), число попыток скрафтить предмет (rolls).

Пример рецепта в формате json приведен ниже:

```json
{
  "type": "interactio:item_explode",
  "inputs": [
    {
      "item": "minecraft:redstone",
      "count": 1
    },
    {
      "tag": "forge:ingots/gold",
      "count": 2
    }
  ],
  "output": {
    "entries": [
      {
        "result": {
          "item": "minecraft:gold_nugget",
          "count": 3
        },
        "weight": 2
      },
      {
        "result": {
          "item": "minecraft:redstone_block",
          "count": 1
        },
        "weight": 1
      }
    ],
    "empty_weight": 0,
    "rolls": 1
  }
}
```

<figure><img src="/files/ZbCZx7wNg9TNJYQCoIG2" alt=""><figcaption><p>Приведенный рецепт создает золотой самородок или редстоун блоки из пыли редстоуна или золота.</p></figcaption></figure>

Рецепт, создающий блок из блока с помощью взрывов.&#x20;

* **Вход**: блоки + взрыв рядом
* **Выход**: блоки

Блоки в данном рецепте создаются посредством взрыва из других блоков. Игрок устанавливает блок, создает взрыв и получает на месте установленного блока новый.

У входных блоков можно указать тип блок (block) и сам блок.

У выходных блоков можно указать шанс получения каждого блока. То есть, из одного входного блока можно создавать разные выходные блоки. Также можно указать вес неудачного крафта (empty\_weight), который будет означать вероятность того, что блок просто израсходуется впустую.

Пример рецепта:

```json
{
  "type": "interactio:block_explode",
  "input": {
    "block": "netherrack"
  },
  "output": {
    "type": "block",
    "entries": [
      {
        "result": {
          "block": "gold_ore"
        },
        "weight": 3
      },
      {
        "result": {
          "block": "obsidian"
        },
        "weight": 2
      }
    ],
    "empty_weight": 5
  }
}
```

<figure><img src="/files/0DG9c5kKDnwGbVzDy8gp" alt=""><figcaption><p>Приведенный рецепт создает блок обсидиана или блок золотой руды из незерака.</p></figcaption></figure>


# Удар молнии

Рецепт, создающий предметы из предметов с помощью удара молнии.

* **Вход**: предметы + удар молнии
* **Выход**: предметы

Предметы в данном рецепте создаются посредством удара молнии по каким-либо ресурсам.

У входных предметов можно указать тип: предмет (item) или тег (tag), количество (count).

У выходных предметов можно указать тип предмета, количество, вес предмета (при нескольких выходных предметов), вес неудачного крафта (empty\_weight), число попыток скрафтить предмет (rolls).

Например:

```json
{
  "type": "interactio:item_lightning",
  "inputs": [
    {
      "tag": "forge:ores",
      "count": 1
    },
    {
      "tag": "forge:stone",
      "count": 2
    }
  ],
  "output": {
    "entries": [
      {
        "result": {
          "item": "minecraft:diamond",
          "count": 1
        },
        "weight": 2
      }
    ],
    "empty_weight": 1,
    "rolls": 1
  }
}
```

<figure><img src="/files/jMsD3n9N4x1tAWNQksSe" alt=""><figcaption></figcaption></figure>


# Падение наковальни

Рецепт, создающий предметы из предметов с помощью падения на них наковальни.

* **Вход**: предметы под наковальней
* **Выход**: предметы

У входных предметов можно указать тип: предмет (item) или тег (tag), количество (count).

У выходных предметов можно указать: тип предмета, количество, вес предмета (при нескольких выходных предметов), вес неудачного крафта (empty\_weight), число попыток скрафтить предмет (rolls).

Вы можете написать что-то подобное:

```json
{
  "type": "interactio:item_anvil_smashing",
  "inputs": [
    {
      "item": "minecraft:gold_nugget",
      "count": 9
    }
  ],
  "output": {
    "entries": [
      {
        "result": {
          "item": "minecraft:gold_ingot"
        },
        "weight": 20
      },
      {
        "result": {
          "item": "minecraft:iron_nugget"
        },
        "weight": 10
      }
    ],
    "rolls": 2,
    "empty_weight": 1
  },
  "damage": 1
}
```

<figure><img src="/files/kwrJhm4XWb459RoyHPnR" alt=""><figcaption></figcaption></figure>


# Game Stages

Мод, с помощью которого в модпаке можно сделать стадии с целью разграничения игрового контента, когда пользователь сможет открыть часть содержания проекта сразу, а оставшееся лишь в конце прохождения.

С помощью данной модификации Вы можете реализовать механику поэтапного развития и создать самые универсальные методы прогрессии.

{% content-ref url="/pages/dWxo3iSL1qSwzRVszsDE" %}
[ZenStages](/modifications/sozdanie-kontenta/game-stages/zenstages)
{% endcontent-ref %}

{% content-ref url="/pages/3ihmzp7J4zYlWotcVKIg" %}
[Gamestage Books](/modifications/sozdanie-kontenta/game-stages/gamestage-books)
{% endcontent-ref %}

{% content-ref url="/pages/VpeUgohzYWoFmFVnlsBq" %}
[Recipe Stages](/modifications/sozdanie-kontenta/game-stages/recipe-stages)
{% endcontent-ref %}

{% content-ref url="/pages/pZdPL7Y9cg8dMItMxIqd" %}
[Dimension Stages](/modifications/sozdanie-kontenta/game-stages/dimension-stages)
{% endcontent-ref %}

{% content-ref url="/pages/ntq6RaPjtHaEhhzrDyOW" %}
[Item Stages](/modifications/sozdanie-kontenta/game-stages/item-stages)
{% endcontent-ref %}

{% content-ref url="/pages/5W26h1xJTFXJrnrzBDqo" %}
[MultiBlock Stages](/modifications/sozdanie-kontenta/game-stages/multiblock-stages)
{% endcontent-ref %}

{% content-ref url="/pages/Ckwc4zTVm7B3kJGJT3hK" %}
[TinkerStages](/modifications/sozdanie-kontenta/game-stages/tinkerstages)
{% endcontent-ref %}


# ZenStages

Это инструмент для создателей модпаков, когда использование GameStages является основной частью их проекта.

И так, для начала Вы должны понимать, что основная функция этого мода – создание этапов с возможность настроить их под себя, дать соответствующее название и продумать логику использования.

*Пример ниже отвечает за регистрацию этапов.*

```java
import mods.zenstages.ZenStager;
import mods.zenstages.Stage;

static one as Stage = ZenStager.initStage("one");
static two as Stage = ZenStager.initStage("two");
static three as Stage = ZenStager.initStage("three");
static four as Stage = ZenStager.initStage("four");
```

После создания этапа мы можем воспользоваться модификациями на квесты, чтобы привязать их к прогрессии в сборке. Например, [**Better Questing**](/modifications/quests/better-questing) или [**FTB Quests**](/modifications/quests/ftb-quests), с их помощью Вы сможете награждать игроков этапами по мере прохождения самого модпака. Этапы сами по себе не меняют игровую составляющую, их нужно выдавать каким-либо способом. Для этого также можно использовать всевозможные аддоны, например <mark style="color:blue;">**"Gamestage Books"**</mark>, с его помощью игрок сможет получить этап и его награды, и стремиться к следующему этапу для открытия больше числа контента.


# Gamestage Books

Аддон Gamestage, который позволяет создать книги для разблокировки этапов с помощью модификаций FTBquests или Better Questing. Также же можно задать книге свое описание, название и цвет.

Как и говорилось ранее, эта модификация добавляет книги, с помощью которых игрок откроет у себя новые этапы и с ними же новые предметы.

## Пример скрипта

Первые две строки `#loader gamestagebooks` и `import mods.gamestagebooks.Book;` - одни из самых важных, если одной из них не будет, то Вы не сможете зарегистрировать книги для получения этапа. Ниже описаны примеры этапов, их всего приведено 4, но для своего мод пака возможно создать сколько угодно.

```java
#loader gamestagebooks 
import mods.gamestagebooks.Book; 

Book.addBook("one", "Этап камня", "Исследование Ада", "primal:rock_stone", 0x0cf200);
```

<div align="left"><figure><img src="/files/BVDRWkTevThkzwTnq7P8" alt=""><figcaption></figcaption></figure></div>

* Название стадии = `"one"`
* Описание книги = `"Этап камня"`
* Название книги = `"Исследование Ада"`
* Предмет, который отображается при разблокировке = `"primal:rock_stone"`
* Цвет книги = `0x0cf200`

***

{% code overflow="wrap" %}

```java
Book.addBook("two", "Знакомство с энергией", "Обустройства дома", "mekanism:controlcircuit", 0x0cf200);
```

{% endcode %}

<div align="left"><figure><img src="/files/yG3gs6wZdJauMkO2TFWP" alt=""><figcaption></figcaption></figure></div>

* Название стадии = `"two"`
* Описание книги = `"Знакомство с энергией"`
* Название книги = `"Обустройство дома"`
* Предмет, который отображается при разблокировке = `"mekanism:controlcircuit"`
* Цвет книги = `0x0cf200`

***

{% code overflow="wrap" %}

```java
Book.addBook("three", "Продвинутая энергия", "Продвинутый дом", "extendedcrafting:material@40", 0x0cf200);
```

{% endcode %}

<div align="left"><figure><img src="/files/bu9X1nYtyJeWrJUDSaVz" alt=""><figcaption></figcaption></figure></div>

* Название стадии = `"three"`
* Описание книги = `"Продвинутая энергия"`
* Название книги = `"Продвинутый дом"`
* Предмет, который отображается при разблокировке = `"extendedcrafting:material@40"`
* Цвет книги = `0x0cf200`

***

{% code overflow="wrap" %}

```java
Book.addBook("four", "Близок конец", "Собственник ада", "minecraft:ender_eye", 0x0cf200);
```

{% endcode %}

<div align="left"><figure><img src="/files/vaS05czhDEqpqIJ8ZTf5" alt=""><figcaption></figcaption></figure></div>

* Название стадии = `"four"`
* Описание книги = `"Близок конец"`
* Название книги = `"Собственник ада"`
* Предмет, который отображается при разблокировке = `"minecraft:ender_eye"`
* Цвет книги = `0x0cf200`

***

После того, как Вы создали книги со своими стадиями в <mark style="color:blue;">**JEI**</mark> должны появиться соответствующие предметы.

<div align="left"><figure><img src="/files/q2yzgtszZLat1WiZHOtU" alt=""><figcaption></figcaption></figure></div>

Теперь, когда мы имеем предметы для выдачи этапов, их можно выложить в качестве награды за квесты.

<div align="left"><figure><img src="/files/ZpjCVycUKHR5fGNDcJMc" alt=""><figcaption></figcaption></figure></div>

Каждый раз, когда игрок активирует определённую книгу, у него открывается новый этап. Каждому этапу нужно привязать некие действия, имеющие позицию в продвижении игрока по сборке.


# Recipe Stages

С данным аддоном Вы можете настроить рецепты создания в зависимости от этапа продвижения, заблокировать какой-либо крафт и скрыть его из поиска.

Игрок не сможет увидеть в самом начале модпака те крафты, что входят в этапы. *Ниже приведены несколько примеров:*

## Методы написания

1. Открытие целого мода через этап:

{% code overflow="wrap" %}

```java
// В данных строках написано, что моды "Mekanism" и "EnderIO" добавлены во второй этап - "two". 

mods.recipestages.Recipes.setRecipeStageByMod("two", "mekanism");
mods.recipestages.Recipes.setRecipeStageByMod("two", "enderio");

// В данных строках написано, что моды  "ic2" и "AppliedEnergistics2" добавлены в третий этап - "three". 

mods.recipestages.Recipes.setRecipeStageByMod("three", "ic2");
mods.recipestages.Recipes.setRecipeStageByMod("three", "appliedenergistics2");

// В данных строках написано, что моды  "УxtendedСrafting" и "Tombstone" добавлены в четвертый этап - "four". 

mods.recipestages.Recipes.setRecipeStageByMod("four", "extendedcrafting");
mods.recipestages.Recipes.setRecipeStageByMod("four", "tombstone");
```

{% endcode %}

2. Устанавливает стадию для отдельного рецепта:

Пример похож на тот, что Вы уже писали ранее, только вместо ID мода нужно написать ID предмета.

{% code overflow="wrap" %}

```java
// В данных строках написано, что предметы "mekanism:basicblock2:1" и "mekanism:machineblock:8" добавлены во второй этап - "two". 

mods.recipestages.Recipes.setRecipeStage("two", <mekanism:basicblock2:1>);
mods.recipestages.Recipes.setRecipeStage("two", <mekanism:machineblock:8>);
```

{% endcode %}

<div align="left"><figure><img src="/files/wYAhvAANJoxNir3IO2QI" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данных строках написано, что рецепты "ic2:resource:12" и "ic2:crafting:13" добавлены в третий этап -  "three". 

mods.recipestages.Recipes.setRecipeStage("three", <ic2:resource:12>);
mods.recipestages.Recipes.setRecipeStage("three", <ic2:crafting:13>);
```

{% endcode %}

<div align="left"><figure><img src="/files/0MinTGo2tnAhGQVXAFD9" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данных строках написано, что предметы "minecraft:ender_eye" и "extendedcrafting:ender_alternator" добавлены в четвертый этап - "four". 

mods.recipestages.Recipes.setRecipeStage("four", "minecraft:ender_eye");
mods.recipestages.Recipes.setRecipeStage("four", <extendedcrafting:ender_alternator>);
```

{% endcode %}

<div align="left"><figure><img src="/files/IwHUB4cS2r8Oq6bTrxrZ" alt=""><figcaption></figcaption></figure></div>

После того, как игрок получает этап, в панели отображения рецепта можно увидеть следующую надпись:

<div align="left"><figure><img src="/files/MBtVbFubbYO1ShiwqhZJ" alt=""><figcaption></figcaption></figure> <figure><img src="/files/cD0cZ6UvILNgfGQesJDV" alt=""><figcaption></figcaption></figure> <figure><img src="/files/Njgq1Y1nadDHpmqrHp4E" alt=""><figcaption></figcaption></figure></div>

До того времени увидеть крафт предмета игрок не сможет.

{% code overflow="wrap" %}

```java
// В данных строках написан форменный крафт, "яблоко" добавлено ко второму этапу и делается из 2 золотых слитков и 5 железных слитков:
mods.recipestages.Recipes.addShaped("two",<minecraft:apple>,[[<minecraft:gold_ingot>, <minecraft:gold_ingot>, <minecraft:iron_ingot>],[<minecraft:iron_ingot>, null, <minecraft:iron_ingot>],[<minecraft:iron_ingot>, null, <minecraft:iron_ingot>]]);
```

{% endcode %}

<div align="left"><figure><img src="/files/7xy7tYI0s8z0Gi0kvHsk" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данных строках написан форменный крафт, "золотой меч" добавлено к третьему этапу делается из 2 золотых слитков и 5 железных слитков:
mods.recipestages.Recipes.addShaped("Начало", "three", <minecraft:golden_sword>,[[<minecraft:gold_ingot>, <minecraft:iron_ingot>, <minecraft:iron_ingot>],[<minecraft:iron_ingot>, null, <minecraft:iron_ingot>],[<minecraft:iron_ingot>, null, <minecraft:iron_ingot>]]);
```

{% endcode %}

<div align="left"><figure><img src="/files/ih4yBFB8QYkNNR30w7uY" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данных строках написан бесформенный крафт, "алмаз" добавлен ко второму этапу и  делается из 2 песка, 1 железного слитка и 1 золотого слитка:
mods.recipestages.Recipes.addShapeless("two", <minecraft:diamond>, [<ore:sand>, <ore:sand>, <ore:ingotIron>, <minecraft:gold_ingot>]);
```

{% endcode %}

<div align="left"><figure><img src="/files/JThqTlT02fFSFyPpYrmc" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данных строках написан бесформенный крафт, предмет "железные поножи" добавлен к третьему этапу и делается из 2 песка, 1 железного слитка и 1 золотого слитка. 
mods.recipestages.Recipes.addShapeless("Начало", "three", <minecraft:iron_leggings>, [<ore:sand>, <ore:sand>, <ore:ingotIron>, <minecraft:gold_ingot>]);
```

{% endcode %}

{% code overflow="wrap" %}

```java
// Для начала нужно создать файл "post Init.zs", после его создания напишите в нём следующие строчки: 
#priority -100
import mods.zenstages.ZenStager; // Импортируем класс
initSpecificStaging(); // Это специфические сценарии для постановки
ZenStager.buildAll(); // Подгружает все этапы
function initSpecificStaging() {
	scripts.GameStages.stages.init(); // Показывает путь нахождения Ваших этапов, 
}
```

{% endcode %}

Эти все строки считаются основными в отображении этапов для дальнейшей работы с ними. Так как в примере показан путь к файлу , вот его примерное внутреннее содержание:

<div align="left"><figure><img src="/files/EgDNYVRrsb6EALrUmaeK" alt=""><figcaption></figcaption></figure></div>

Вам нужно написать следующее, как указано в примере ниже, первый, второй и третий этапы можно использовать в крафте только на <mark style="color:blue;">**WorkStump**</mark>:

{% code overflow="wrap" %}

```java
import mods.zenstages.ZenStager;
import mods.zenstages.Stage;

static one as Stage = ZenStager.initStage("one");
static two as Stage = ZenStager.initStage("two");
static three as Stage = ZenStager.initStage("three");
static four as Stage = ZenStager.initStage("four");

function init() { // Означает открытие функции "init" для написания изменений.
    ZenStager.addContainer("primal_tech.inventory.ContainerWorkStump" /* говорит об использовании мода primal_tech и добавление особого инвентаря в контейнер  "WorkStump" */, [one, two, three] /* отвечает за этапы, которые Вы можете добавить для "WorkStump" */); // Отвечает за добавление контейнера
} // Закрытие функции
```

{% endcode %}

<div align="left"><figure><img src="/files/qV3j31ZTqvYo9zRGWoH5" alt=""><figcaption></figcaption></figure></div>


# Dimension Stages

Аддон для Gamestage, что представляет собой ограничитель телепортаций в измерения. Как бы Вы не старались, у Вас не получиться телепортироваться в то место, куда был заблокирован путь через этап.

{% code overflow="wrap" %}

```java
// Для начала Вам нужно создать файл "post Init.zs"  , после его создания в нем напишите строки, как показано ниже: 
#priority -100
import mods.zenstages.ZenStager; // Импортируем класс
initSpecificStaging(); // Это специфические сценарии для постановки
ZenStager.buildAll(); // Подгружает все этапы
function initSpecificStaging() {
    scripts.GameStages.stages.init(); // Показывает путь нахождения Ваших этапов
}
```

{% endcode %}

Эти все строки считаются основными в отображении этапов для дальнейшей работы.

Так как в примере показан путь к файлу , рассмотрим внутреннее содержание:

<div align="left"><figure><img src="/files/ewjZFHUClRVNgD7vrzn1" alt=""><figcaption></figcaption></figure></div>

Вам нужно написать следующее, а также указать ID измерения, в которое нельзя будет попасть, в примере используется 3 этап:

{% code overflow="wrap" %}

```java
import mods.zenstages.ZenStager;
import mods.zenstages.Stage;

static one as Stage = ZenStager.initStage("one");
static two as Stage = ZenStager.initStage("two");
static three as Stage = ZenStager.initStage("three");
static four as Stage = ZenStager.initStage("four");

function init() { // Означает открытие функции "init" для написания изменений.
    three.addDimension(0); // здесь "three" означает этап, а addDimension(0); блокировку возможности посещения верхнего мира(Overworld).
} // Закрытие функции "init".
```

{% endcode %}

После написание этого, Вы, находясь, например в аду, сумеречном мире, в раю попасть в верхний мир не сможете.


# Item Stages

Этот аддон способен убрать из JEI предметы и блоки до определенного этапа. То есть, чтобы увидеть и скрафтить необходимый предмет, тебе нужно достичь этапа, на котором он открывается.

Ниже описаны функции, с помощью которых Вы не сможете увидеть или же взять в руки предмет.

## Эффекты, наложенные на предметы через этап

В этом аддоне все эффекты настраиваются в <mark style="color:blue;">**config/itemstages.cfg**</mark>, все они вкратце описаны ниже:

* Если держать предмет с ограничением, он будет немедленно сброшен.
* Если экипировать предмет в слот для брони или безделушки, он будет сброшен.
* Игроки не могут щелкнуть правой или левой кнопкой мыши, используя этот предмет.
* Предмет не будет виден в JEI.

Вот пример того, что будет если модификацию <mark style="color:blue;">**"mekanism"**</mark> добавить в этап, который игрок еще не достиг:

<div align="left"><figure><img src="/files/GKwZYAFV1wPpadLv6lC4" alt=""><figcaption></figcaption></figure></div>

После того, как игрок получит этап:

<div align="left"><figure><img src="/files/G7SNuNOFeJDeycPMi4K9" alt=""><figcaption></figcaption></figure></div>

## Пример скрипта

{% code overflow="wrap" %}

```java
// С помощью этих строк Вы можете запереть необходимые предметы на первом этапе - "one":
mods.ItemStages.addItemStage("one", <minecraft:stone>); 
mods.ItemStages.addItemStage("one", <ic2:casing:3>); 
mods.ItemStages.addItemStage("one", <aeadditions:storage.component>); 
mods.ItemStages.addItemStage("one", <extendedcrafting:material:32>); 

// С помощью этих строк Вы можете запереть необходимые предметы на втором этапе - "two":

mods.ItemStages.stageModItems("two", "mekanism");
mods.ItemStages.stageModItems("two", "enderio");
mods.ItemStages.stageModItems("two", "bigreactors");
mods.ItemStages.stageModItems("two", "Immersiveengineering");

// С помощью этих строк Вы можете запереть необходимые предметы на третьем этапе - "three":

mods.ItemStages.stageModItems("three", "ic2");
mods.ItemStages.stageModItems("three", "appliedenergistics2");
mods.ItemStages.stageModItems("three", "thermalfoundation");
mods.ItemStages.stageModItems("three", "thermalexpansion");
mods.ItemStages.stageModItems("three", "aeadditions");

// С помощью этих строк Вы можете запереть необходимые предметы на четвертом этапе - "four":
mods.ItemStages.stageModItems("four", "extendedcrafting");
mods.ItemStages.stageModItems("four", "tombstone");

```

{% endcode %}

До: показывает способ добыть воды:

<div align="left"><figure><img src="/files/hDSvFTfRioHkgT3pX3qU" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// Пример отвечает за то, что Вы можете узнать способы добычи "воды" только при достижении третего этапа:
mods.ItemStages.stageLiquid("three", <liquid:water>);
```

{% endcode %}

После:

<div align="left"><figure><img src="/files/GoWrKbzSLcz5PWp9o2Zp" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В данной строке можно рассмотреть пример этапа с блокированием "защита",  то есть игрок не сможет зачаровать броню на защиту, не достигнув третьего этапа:
mods.ItemStages.stageEnchant("three", <enchantment:minecraft:protection>);
```

{% endcode %}

Пример отображения:

<div align="left"><figure><img src="/files/3JzaTO2r9srFWhiGLLNn" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// Пример ограничения получения зачарования "защита 2 уровня", игрок не сможет зачаровать броню на это защиту II, не достигнув третьего этапа:
mods.ItemStages.stageEnchantByLevel("three", <enchantment:minecraft:protection>.makeEnchantment(2));
```

{% endcode %}

<div align="left"><figure><img src="/files/JCzqD3mc8Ef6r63qvTuH" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// В строке ниже показано, как можно изменить название предмета, которого Вы еще не достигли до определённого этапа:
mods.ItemStages.setUnfamiliarName("AHAHAHHA", <enderio:block_vat>);
```

{% endcode %}

<div align="left"><figure><img src="/files/nHOzm8dRAb2R389ZLpty" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// Ограничение просмотра использования механизма или предмета:
mods.ItemStages.stageRecipeCategory("three", "minecraft.anvil");
```

{% endcode %}

<div align="left"><figure><img src="/files/AqjO6VuW2YwhaWQymEfu" alt=""><figcaption></figcaption></figure></div>

При достижении третьего этапа игрок сможет увидеть предметы, которые используются в наковальне:

<div align="left"><figure><img src="/files/Jb3qGtLnOOsLmQo6IbrA" alt=""><figcaption></figcaption></figure></div>


# MultiBlock Stages

С помощью этого аддона для Gamestage можно сделать так, что бы активация мультиблочного механизма была ограничена этапом. В частности, это работает с тем же Immersive Engineering.

## Пример скрипта

{% code overflow="wrap" %}

```java
import mods.multiblockstages.IEMultiBlockStages; 
IEMultiBlockStages.addStage("BlastFurnace", "IE:BlastFurnace"); 
```

{% endcode %}

<div align="left"><figure><img src="/files/QPxfGGTzB11AJf8wr72C" alt=""><figcaption></figcaption></figure></div>

```java
IEMultiBlockStages.addStage("CokeOven", "IE:CokeOven", "YOU CAN'T DO THAT");
```

<div align="left"><figure><img src="/files/38ihv36zYK2WOmv0ia51" alt=""><figcaption></figcaption></figure></div>

В первом примере написано, что при попытке активации структуры игрок не сможет её активировать.&#x20;

Во втором примере видно, что при попытке активации структуры игроку будет на показывать на экране надпись **"YOU CAN'T DO THAT"**.

Чтобы получить список всех мультиблоков <mark style="color:blue;">**Immersive Engineering**</mark>, нужно прописать в чате Minecraft команду: `/ct ieMultiBlocks`


# TinkerStages

Если Вы не хотите, чтобы в самом начале развития на сборке игроки могли сделать инструменты или броню из Tinker, смело используйте этот аддон.

С его помощью Вы можете настроить этап, когда именно игрок может использовать/сделать материал или блок-механизм из мода.

## Примеры

На примерах можно увидеть накладываемые на предметы из мода ограничения, первыми идут инструменты, без этапа «one» их создание будет недоступно

{% code overflow="wrap" %}

```java
// Ограничивает создание инструментов до "one" этапа:
mods.TinkerStages.addGeneralCraftingStage("one");
```

{% endcode %}

<div align="left"><figure><img src="/files/MZIVUHEkh76zvdYuw3SW" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" %}

```java
// Ограничивает создание материалов до "two" этапа:
mods.TinkerStages.addGeneralPartBuildingStage("two");
```

{% endcode %}

<div align="left"><figure><img src="/files/UoM7dsRE1dUjJm4m7GtF" alt=""><figcaption></figcaption></figure></div>

```java
// Ограничивает применение модификаторов до "three" этапа:
mods.TinkerStages.addGeneralModifierStage("three");
```

<div align="left"><figure><img src="/files/bwr1B2ud2Yg2hcXgByxp" alt=""><figcaption></figcaption></figure></div>


# Ore Stage Reborn

Мод позволяет скрыть или заменить блоки, пока у игрока не будет определённого этапа (Game Stages).

### Что нужно для работы?

* [CraftTweaker](broken://pages/DBVreWJxl8ifSomzVasL)
* [Game Stages](/modifications/sozdanie-kontenta/game-stages)

Для начала Вам нужно создать скрипт в папке **scripts** или использовать уже существующий.

Далее необходимо импортировать пакет `mods.orestages.OreStages` или использовать пакет при вызова методов.

Разберём несколько методов данного аддона:

Метод скрывает блок по его <mark style="color:blue;">**BlockState**</mark>.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, BlockState block);

OreStages.addOreStage("one", <blockstate:minecraft:grass_block:snowy=false>);
```

{% endcode %}

| Параметр | Тип        | Описание                 | Пример                                           |
| -------- | ---------- | ------------------------ | ------------------------------------------------ |
| stage    | String     | Этап                     | `"one"`                                          |
| block    | BlockState | Блок, кторый будет скрыт | `<blockstate:minecraft:grass_block:snowy=false>` |

<br>

Метод, который скрывает блок по его <mark style="color:blue;">**BlockState**</mark> и заменяет его на другой блок по <mark style="color:blue;">**BlockState**</mark>.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, BlockState block, BlockState replaceBlock);

OreStages.addOreStage("one", <blockstate:minecraft:deepslate_coal_ore>, <blockstate:minecraft:deepslate:axis=y>);
```

{% endcode %}

| Параметр     | Тип        | Описание                                    | Пример                                      |
| ------------ | ---------- | ------------------------------------------- | ------------------------------------------- |
| stage        | String     | Этап                                        | `"one"`                                     |
| block        | BlockState | Блок, кторый будет скрыт                    | `<blockstate:minecraft:deepslate_coal_ore>` |
| replaceBlock | BlockState | Блок, на который будет заменён скрытый блок | `<blockstate:minecraft:deepslate:axis=y>`   |

<br>

Метод, что скрывает блок по его <mark style="color:blue;">**BlockState**</mark> и позволяет отключить возможность разрушения взрывами.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, BlockState block, boolean explosion);

OreStages.addOreStage("one", <blockstate:minecraft:deepslate_coal_ore>, true);
```

{% endcode %}

| Параметр  | Тип        | Описание                        | Пример                                      |
| --------- | ---------- | ------------------------------- | ------------------------------------------- |
| stage     | String     | Этап                            | `"one"`                                     |
| block     | BlockState | Блок, кторый будет скрыт        | `<blockstate:minecraft:deepslate_coal_ore>` |
| explosion | bool       | Будет ли блок разрушен взрывами | `true`                                      |

<br>

Метод, который скрывает блок по его <mark style="color:blue;">**BlockState**</mark> и заменяет его на другой блок по <mark style="color:blue;">**BlockState**</mark>, а также позволяет отключить возможность разрушения взрывами.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, BlockState block, BlockState replaceBlock, boolean explosion);

OreStages.addOreStage("one", <blockstate:minecraft:deepslate_coal_ore>, <blockstate:minecraft:deepslate:axis=y>, true)
```

{% endcode %}

| Параметр     | Тип        | Описание                                    | Пример                                      |
| ------------ | ---------- | ------------------------------------------- | ------------------------------------------- |
| stage        | String     | Этап                                        | `"one"`                                     |
| block        | BlockState | Блок, кторый будет скрыт                    | `<blockstate:minecraft:deepslate_coal_ore>` |
| replaceBlock | BlockState | Блок, на который будет заменён скрытый блок | `<blockstate:minecraft:deepslate:axis=y>`   |
| explosion    | bool       | Будет ли блок разрушен взрывами             | `true`                                      |

<br>

Метод, который скрывает блоки по <mark style="color:blue;">**Forge Tag**</mark> и заменяет их на другой блок по <mark style="color:blue;">**BlockState**</mark>.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, KnownTag<Block> tag, BlockState replaceBlock);

OreStages.addOreStage("one", <tag:blocks:forge:stone>, <blockstate:minecraft:deepslate:axis=y>);
```

{% endcode %}

| Параметр     | Тип        | Описание                                     | Пример                                    |
| ------------ | ---------- | -------------------------------------------- | ----------------------------------------- |
| stage        | String     | Stage                                        | `"one"`                                   |
| tag          | KnownTag   | Блоки по Forge Tag, что будут скрыты         | `<tag:blocks:forge:stone>`                |
| replaceBlock | BlockState | Блок, на который будет заменён скрытые блоки | `<blockstate:minecraft:deepslate:axis=y>` |

<br>

Метод, который скрывает блоки по <mark style="color:blue;">**Forge Tag**</mark> и заменяет их на другой блок по <mark style="color:blue;">**BlockState**</mark>, а также позволяет отключить возможность разрушения взрывами.

{% code overflow="wrap" %}

```java
OreStages.addOreStage(String stage, KnownTag<Block> tag, BlockState replaceBlock, boolean explosion)

OreStages.addOreStage("one", <tag:blocks:forge:stone>, <blockstate:minecraft:deepslate:axis=y>, true);
```

{% endcode %}

| Параметр     | Тип        | Описание                                     | Пример                                    |
| ------------ | ---------- | -------------------------------------------- | ----------------------------------------- |
| stage        | String     | Stage                                        | `"one"`                                   |
| tag          | KnownTag   | Блоки по Forge Tag, которые будут скрыты     | `<tag:blocks:forge:stone>`                |
| replaceBlock | BlockState | Блок, на который будет заменён скрытые блоки | `<blockstate:minecraft:deepslate:axis=y>` |
| explosion    | bool       | Будет ли блок разрушен взрывами              | `true`                                    |


# Modular Machinery

Модификация, добавляющая инструментарий для создания мультиблочных структур. Имеет поддержку CraftTweaker. Позволяет организовать в кастомных конструкциях выработку и передачу RF и EU энергии, жидкост


# Начало работы

Сперва необходимо установить [Modular Machinery](https://www.curseforge.com/minecraft/mc-mods/modular-machinery) и [Crafttweaker](https://www.curseforge.com/minecraft/mc-mods/crafttweaker). В качестве текстового редактора, для удобного пользования, рекомендуется использовать [Notepad++](https://notepad-plus-plus.org/downloads/).

После первого запуска в config должна появиться папка **«modularmachinery»**, в которой будут храниться файлы **«machinery»**, **«recipes»** и конфигурация мода. В папке **machinery** располагаются все созданные Вами мультиблочные структуры (при первом заходе появляются 3 начальные конструкции, служащие шаблоном). В recipes расположены скрипты крафтов (эта папка Вам не понадобится, так как с крафтами мы будем работать в scripts).

**Перед началом изучения данной модификации рекомендуется ознакомиться со статьёй по CraftTweaker 1.12.2.**


# Компоненты для создания

Для работы мультиблочной стуруктуры нужны определённые блоки. Входы и выходы поддерживают:

* Жидкости.
* Энергию.
* Предметы.

Во входные (**input**) люки нужно поставлять жидкости/энергию/предметы и через настраиваемое время получать в выходном люке (**output**) заданный ресурс.

Центром нашей мультиблочной структуры является **контроллер**. Он предоставляет информацию о структуре и производимом рецепте. У каждого входного и выходного люка есть уровень, от Tiny до Ludicrous. Каждый уровень отличается размерами резервуара (например, у **Tiny** - 1 слот, а у **Ludicrous** - 32 слота). При создании базовой конструкции стоит использовать минимальный уровень.

<figure><img src="/files/lXXi3CUxNpSkhORy5UvQ" alt=""><figcaption></figcaption></figure>


# Создание конструкции

Чтобы начать создавать мультиблочные структуры Вам понадобится **construct selection tool** в виде гаечного ключа, используемого для выделения блоков, относящихся к конструкции (выделяйте по слоям, контроллер - только в последнюю очередь, чтобы структура была правильно сформирована). Затем необходимо добавить люки входа и выхода для производства ресурсов/энергии. После выделения блоков нажмите shift+ПКМ по контроллеру, держа в руке construct selection tool, чтобы файл Вашей мультиблочной машины отправился в формате .json в папку **«machinery»**, также Minecraft оповестит Вас об успешном создании (рис.3). Желательно переименовать .json файл, чтобы не путаться и иметь в дальнейшем определённую структуру.

<figure><img src="/files/m4HccrDQCrn21R5d8AFy" alt=""><figcaption><p>Пример структуры, потребляющей жидкость, энергию и предмет, чтобы произвести более сложное создание материала</p></figcaption></figure>

<div align="left"><figure><img src="/files/2agsoR6Zvg2P09LmS4AB" alt=""><figcaption></figcaption></figure></div>


# Настройка файла

За созданием структуры в игре следует её детальная настройка в файлах. При открытии .json файла перед Вами будет скрипт. Первым делом удалите все NBT-тэги, и, для того, чтобы Ваша конструкция имела поддержку всех люков входа и выхода, нужно в нижней строке elements, в id блока входа или выхода удалить @0, произведите это действие со всеми видами люков.

Перейдём к регистрации нашего механизма.

Сперва напишите следующее: `"registryname": "test",` `"localizedname": "тест",` `"color" : "a5bfc3",`

В **«registryname»** мы пишем наименование машины, которое будет использоваться в крафтах, а в **«localizedname»** имя, которое будет отображаться в игре. Параметр **«color»** отвечает за назначение цвета люков и контроллера. После чего перезаходим в игру и видим появившийся **machine blueprint**. Он показывает, как нужно строить механизм.

<figure><img src="/files/ynpHp8O8nqHKRqzOM7gd" alt=""><figcaption></figcaption></figure>

<div align="left"><figure><img src="/files/O6FMsTiQdb0WsSatJpvt" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/H9fXLXLlQHT9dl4uMu3O" alt=""><figcaption></figcaption></figure>


# Создание крафта

Все рецепты будут создаваться в файле с разрешением .zs, через CraftTweaker. Вам необходимо написать `import mods.modularmachinery.RecipeBuilder;` для начала работы машин.

В скобках нужно написать вместо **«name»** название рецепта, вместо **«test»** - название Вашей структуры, а в конце, вместо **«80»** - время (*в тиках, 20тиков=1секунда*).

Ниже в конфигурации указаны компоненты крафта. Рассмотрим 5 строчку:

* **recipe** – номер рецепта, при создании другого рецепта используйте наименования recipe2, recipe3 и т.д..
* **Fluid** - тип загружаемого материала,
* **input** – обозначение использования материала в рецепте, в скобочках указывается **id** жидкости или предмета (чтобы добавить, например, в крафт 1000мб жидкости, нужно указывать через \* объём).
* **addEnergyPerTickInput** – количество потребляемой энергии (за тик).
* **Recipe.build();** - завершает крафт.

```java
var recipe = RecipeBuilder.newBuilder("name", "test", 80);
recipe.setChance(50);
recipe.addEnergyPerTickInput(100);
recipe.addFluidInput(<liquid:water> * 1000);
recipe.addItemInput(<minecraft:iron_ingot>);
recipe.addItemOutput(<minecraft:gold_ingot>);
recipe.build();
```

<figure><img src="/files/IhXsDFDn4GUlhB9XuOcz" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Crx7mGqCS25iW6Cv7dhj" alt=""><figcaption></figcaption></figure>


# Конфигурация

Файл конфигурации можно найти в папке modularmachinery.

Рассмотрим все составляющие файла конфигруации: **Energy** - отображение энергии.. Если у Вас в модпаке только FE/RF энергия, то пишите в значении Display\_Energy\_Type=FE. EnergyHatch (это размеры люка энергии). **Limit** - предел передачи энергии (зависит от напряжения). **Tier** определяет уровень напряжения (IC 2; gtvoltage – отвечает за тот же параметр, но в комплектации с модом GregTech; **Gt amperage** - настройка силы тока (только GregTech); **Fluidhatch** - параметр резервуаров жидкости.

```
general {
    # Defines the _default_ color for machine casings as items or blocks. (Hex color without alpha) Has to be defined both server and clientside! [default: FF4900]
    S:general-casing-color=FF4900
}
```

Важная строчка, на которую стоит обратить внимание! Она отвечает за назначение цвета люкам, контроллеру и блокам конструкции. Вместо <mark style="color:red;">**FF4900**</mark> нужно написать номер цвета, который Вы желаете установить.

<figure><img src="/files/a4jxPXOIzCEL2PKFE58s" alt=""><figcaption></figcaption></figure>


# SDM CraftTweaker Plus

Аддон для мода CraftTweaker, который позволяет расширить возможности создателей модпаков. Помимо расширения базовых классов

CraftTweaker добавлено немало новых возможностей. Например:

* Новые Ивенты
* Интеграция с известными модами
* Делает возможным создание диалогов с проигрыванием звуковых файлов.
* Позволяет воспроизводить видео на экране игроков.
* Добавляет возможность изменять условия генерации мира.


# Ивенты

## <mark style="color:blue;">PlayerCloneEvent</mark>

Время от времени многим разработчикам проектов в Minecraft необходимо записывать в игрока свои параметры и для этого обычно используют <mark style="color:blue;">**player.customData**</mark>, но вот беда, всё, что Вы запишите в игрока - пропадёт после его возрождения. Чтобы этого избежать, Вам пригодится следующий ивент - <mark style="color:blue;">**mods.sdmcrtplus.events.entity.player.PlayerCloneEvent**</mark>. У него есть 2 метода.

* `getOriginal()` - позволит получить игрока до его смерти.
* `isWasDeath()` - можно проверить умер игрок или зашёл в портал в Эндер мире.

### Пример

{% code lineNumbers="true" %}

```typescript
import crafttweaker.api.events.CTEventManager;
import mods.sdmcrtplus.events.entity.player.PlayerCloneEvent;
CTEventManager.register<mods.sdmcrtplus.events.entity.player.PlayerCloneEvent>((event) => {
    var player = event.player;
    if(player.level.isClientSide || !event.isWasDeath()) return;
    player.updateCustomData(event.getOriginal().customData);
});
```

{% endcode %}

***

## <mark style="color:blue;">PlayerChestLootEvent</mark>

Когда Вы хотите создать свою RPG сборку, Вам может понадобиться возможность изменить лут в генерируемых сундуках, а для этого пригодится ивент <mark style="color:blue;">**mods.sdmcrtplus.events.entity.player.PlayerChestLootEvent**</mark>. Он вызывается каждый раз, когда лут в сундуке или любом контейнере с генерируемым лутом заполняется содержимым. Существует 4 метода:

* `getPos()` - позволяет получить координаты, на которых был открыт контейнер
* `getInventory()` - предоставляет возможность получить инвентарь контейнера
* `getQueriedLootTableId()` - разрешает получить ID таблицы, которой заполняется контейнер
* `getContext()` - повзоляет получить условие заполнения контейнера

### Пример

{% code lineNumbers="true" %}

```typescript
import crafttweaker.api.events.CTEventManager;
import mods.sdmcrtplus.events.entity.player.PlayerChestLootEvent;

CTEventManager.register<mods.sdmcrtplus.events.entity.player.PlayerChestLootEvent>((event) => {
    var player = event.player;
    if(player.level.isClientSide) return;
    var inventory = event.getInventory();

    if(inventory.countItem(<item:minecraft:potato>) > 2){
        var count = 0;
        for i in 0 .. inventory.getMaxStackSize(){
            if(count >= 2) {
                player.sendMessage("Ну я у тебя заберу 2 картошечки, а то кушац хочетца");
                break;
            }

            var item = inventory.getItem(i).asIItemStack();
            if(item.registryName == <item:minecraft:potato>.registryName){
                if(item.amount > 2){
                    count += 2;
                    item.asMutable().shrink(2);
                } else {
                    count++;
                    item.asMutable().shrink();
                }
            }
        }
    }
});
```

{% endcode %}

***

## <mark style="color:blue;">ColonyCreatedEvent</mark>

*Ивент работает только в том случае, когда у Вас установлен MineColonies.*

Для одного из наших проектов нужно было сделать следующий функционал - когда колония создавалась, игрок получает сообщение. Для этого можно использовать ивент <mark style="color:blue;">**mods.sdmcrtplus.integration.api.events.colony.ColonyCreatedEvent**</mark>. Он вызывается всякий раз, когда игрок создаёт колонию.

### Пример

{% code lineNumbers="true" %}

```typescript
import crafttweaker.api.events.CTEventManager;
import mods.sdmcrtplus.integration.api.events.colony.ColonyCreatedEvent;
import stdlib.List;
import crafttweaker.api.world.Level;
import crafttweaker.api.world.ServerLevel;
import crafttweaker.api.entity.Entity;
import crafttweaker.api.entity.LivingEntity;
import crafttweaker.api.entity.type.player.Player;

CTEventManager.register<mods.sdmcrtplus.integration.api.events.colony.ColonyCreatedEvent>((event) => {
    val colony = event.getColony();
    if(colony.getWorld().isClientSide) return;
    
    val level as ServerLevel = colony.getWorld() as ServerLevel;
    val entityList as List<Entity> = level.getEntities((entity as Entity) => (entity.uuid == colony.getPermissions().getOwner() ? true : false), <entitytype:minecraft:player>);
    
    if(entityList.isEmpty) return; 
    if!(entityList[0] is Player) return;
    
    println("[INFO] : (ColonyCreatedEvent) Player Detected !");

    val player as Player;
    try {
        player = entityList[0] as Player;

        player.sendMessage("Колония создана, и Вы являетесь её создателем!");
    } catch ex as Exception{
        println("ERROR ON SCRIPT !\n" + (ex as string));
    }
});
```

{% endcode %}

***

## <mark style="color:blue;">FillBiomesFromNoiseEvent</mark>

Допустим, Вам хочется сделать сборку про выживание в пустыне, и Вы не можете найти мод на пустыню. Но это совершенно не проблема с данной модификацией. Можете воспользоваться <mark style="color:blue;">**mods.sdmcrtplus.events.level.generation.FillBiomesFromNoiseEvent**</mark> - он позволяет заменять нежелательные биомы и может даже что-то ещё. Доступны 4 метода:

* `getBiome()` - позволяет получить ID биома в виде `ResourceLocation`
* `setBiome(biome)` - разрешает установить биом
* `getChunkpos()` - даёт возможность получить координаты в чанке
* `getPlayer()` - можно получить игрока, который генерирует биом

### Пример

{% code lineNumbers="true" %}

```typescript
import crafttweaker.api.events.CTEventManager;
import mods.sdmcrtplus.events.level.generation.FillBiomesFromNoiseEvent;

CTEventManager.register<mods.sdmcrtplus.events.level.generation.FillBiomesFromNoiseEvent>((event) => {
    event.setBiome(<resource:minecraft:biomes/desert>)
});
```

{% endcode %}

***

## <mark style="color:blue;">StructureSpawnEvent</mark>

Ох, нет. Я не хочу, чтобы у меня в мире спавнились пирамиды! Что же мне делать? Воспользуюсь-ка ивентом <mark style="color:blue;">**mods.sdmcrtplus.events.level.generation.StructureSpawnEvent**</mark>, он позволит избавиться от любых структур или заменить их!

У нас есть 7 методов:

* `getStructure()` - позволяет получить структуру
* `setStructure()` - делает возможным изменение структуры
* `getChunkpos()` - разрешает получить координаты структуры в чанке
* `getSectionpos()` - разрешает полчить координаты структуры в секции
* `getStructureManager()` - позволяет получить менеджера структур
* `getLevel()` - можно получить мир, в котором создаётся структура
* `@Nullable getPlayer()` - предоставляет право получить данные об игроке, который спавнит структуру при генерации чанков

### Пример

{% code lineNumbers="true" %}

```typescript
import crafttweaker.api.events.CTEventManager;
import mods.sdmcrtplus.events.level.generation.StructureSpawnEvent;

CTEventManager.register<mods.sdmcrtplus.events.level.generation.StructureSpawnEvent>((event) => {
    if(!event.getLevel().isClientSide) {
        if(event.getStructure().registryName == <resource:minecraft:desert_pyramid>){
            event.setStructure(<resource:minecraft:end_city>);
        }
    }
});
```

{% endcode %}


# Глобальные функции

## Скажи мне сегодняшнюю дату!

Возможно, Вам когда-то нужно было проверять дату при запуске сборки. Так вот, теперь Вы можете это сделать! Всё, что нужно - это `mods.sdmcrtplus.utils.Data`!

Данный класс отсылает нас к <mark style="color:blue;">**Data**</mark> в <mark style="color:blue;">**Java**</mark>.

Здесь есть 7 методов:

* `getSeconds()` - разрешает получить секунды от 0 до 59
* `getMinutes()` - позволяет получить минуты от 0 до 59
* `getHours()` - можно получить часы от 0 до 23
* `getDay()` - теперь доступно получение дня недели (<mark style="color:blue;">**0**</mark> - Воскресенье, <mark style="color:blue;">**1**</mark> - Понедельник, <mark style="color:blue;">**2**</mark> - Вторник, <mark style="color:blue;">**3**</mark> - Среда, <mark style="color:blue;">**4**</mark> - Четверг, <mark style="color:blue;">**5**</mark> - Пятница, <mark style="color:blue;">**6**</mark> - Суббота)
* `getMonth()` - позволяет получить месяц от 0 до 11
* `getYear()` - если хотите получить год
* `getTime()` - делает возможным получение точной даты в секундах с (January 1, 1970, 00:00:00 GMT) по текущую дату.

### Пример

```java
import mods.sdmcrtplus.utils.Data;
var d = new Data();
if (d.getSeconds() >= 40) println("Уже 40 секунд прошло!");
```

Воспроизведение сообщений Работает только с загрузчиком <mark style="color:blue;">**sdmcrtplus**</mark>.

Возможно, только ради этого Вы и скачали или скачаете данный мод.

Если хотите воспроизвести сообщение на экране игрока, да и не просто текстом, а и со звуком, тогда Вам нужно использовать `mods.sdmcrtplus.utils.functions.sixikLore.LoreBuilder`.

Текст сообщения пишется в <mark style="color:blue;">**lang**</mark> файле.

### Пример №1

```java
// loader sdmcrtplus
import mods.sdmcrtplus.utils.functions.sixikLore.LoreBuilder;
import mods.sdmcrtplus.utils.functions.sixikLore.LoreQuote;
import mods.sdmcrtplus.utils.functions.sixikLore.LoreSubtitles;
```

`addSubtitles` - добавляет текст\
`add` - добавляет дополнительное сообщение

<pre class="language-java"><code class="lang-java"><strong>//LoreBuilder.registerLore(new LoreQuote(&#x3C;Имя вашего сообщения>).addSubtitles(new LoreSubtitles(&#x3C;Время проигрывания сообщения>).add(&#x3C;Сколько проигрваается дополнительное сообщение>)))
</strong>LoreBuilder.registerLore(new LoreQuote("test_message").addSubtitles(new LoreSubtitles(20).add(8).add(8).add(8)));
</code></pre>

### Пример №2

```java
import crafttweaker.api.events.CTEventManager;
import crafttweaker.api.event.entity.player.ItemPickupEvent;
import mods.sdmcrtplus.utils.functions.sixikLore.LoreQuoteUtils;
CTEventManager.register<crafttweaker.api.event.entity.player.ItemPickupEvent>((event) => { val player = event.player;
    //LoreQuoteUtils.play(сообщение, игрок, задержка);
    LoreQuoteUtils.play(LoreQuoteUtils.getByName("test_message"), player, 80);
});
```

## Воспроизведение видео

Если Вы хотите включить какое-либо видео игроку, используйте класс `mods.sdmcrtplus.utils.functions.sixikLore.LoreQuoteUtils`.

Для начала Вам нужно переместить видео в папку <mark style="color:blue;">**video**</mark>, которая находится в папке с Minecraft

### Пример

```java
import crafttweaker.api.events.CTEventManager;
import crafttweaker.api.event.entity.player.ItemPickupEvent;
import mods.sdmcrtplus.utils.functions.sixikLore.LoreQuoteUtils;
import crafttweaker.api.entity.type.player.ServerPlayer;
import crafttweaker.api.entity.type.player.Player;
CTEventManager.register<crafttweaker.api.event.entity.player.ItemPickupEvent>((event) => { val player as Player = event.player;
    //LoreQuoteUtils.playVideo(игрок, имя видео, громкость);
    LoreQuoteUtils.playVideo(player as ServerPlayer, "video.mp4", 100);
});
```

## Отключение частей интерфейса

Хотели ли Вы когда-нибудь отключить части интерфейса игрока?

Хотбар? Показатели еды или хп?

Теперь, благодаря `mods.sdmcrtplus.client.ClientRestricted` это стало возможно!

### Пример

```java
import mods.sdmcrtplus.client.ClientRestricted;
ClientRestricted.setClientGUIRestricted(constant:overlay:hotbar);
ClientRestricted.setClientGUIRestricted(constant:overlay:hotbar, "one");
ClientRestricted.setClientGUIRestricted(constant:overlay:hotbar, { "close" : true });
/*
    ClientRestricted.setClientGUIRestricted(<overlay>)
    ClientRestricted.setClientGUIRestricted(<overlay>, <stage>)
    ClientRestricted.setClientGUIRestricted(<overlay>, <IData>)
*/
```


# Модули

## RPG Модуль

{% hint style="info" %}
Перед использование нужно включить в <mark style="color:blue;">**config**</mark> файле <mark style="color:blue;">**RPG Module**</mark> и другие нужные Вам функции.
{% endhint %}

Если Вы хотели когда-то создать RPG Сборку и сделать собственную систему лута с множеством условий на выпадение предметов - используйте `mods.sdmcrtplus.utils.functions.sixikrpg.utils.SixikRPGUtils`.

### Пример

```java
import mods.sdmcrtplus.utils.functions.sixikrpg.property.entity.EntityPropertyItemBase;
import crafttweaker.api.item.IItemStack;
import stdlib.List;
import mods.sdmcrtplus.utils.functions.sixikrpg.utils.SixikRPGUtils;
import mods.sdmcrtplus.utils.functions.sixikrpg.entity.elements.EntityElementBase;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.entity.EntityDropLootProperty;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.loot.ItemLootPropertyDay;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.loot.ItemLootPropertyBase;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.entity.EntityPropertyBase;
import crafttweaker.api.entity.EntityType;
import crafttweaker.api.entity.Entity;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.loot.ItemLootBase;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.loot.ItemLootPropertyKillCurrentItem;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.loot.ItemLootPropertyOnlyPlayer;
import mods.sdmcrtplus.utils.functions.sixikrpg.block.BlockSkillBase;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.block.destroy.BlockNoDestroy;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.block.destroy.BlockPropertyDestroy;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.block.BlockDropLoot;
import mods.sdmcrtplus.utils.functions.sixikrpg.property.block.BlockExplosion;
```

Со слизней при убийстве деревянным мечом, после 10 дня игры, будет падать алмаз или золотой слиток с шансом в 50%, а максимальное количество выпадаемых за раз предметов равно 10 ед.

```java
SixikRPGUtils.register(
  new EntityElementBase([ < entitytype: minecraft: slime > ] as EntityType < Entity > [], [
    new EntityDropLootProperty(
      new ItemLootBase(
        [ <
          item: minecraft: diamond > , <
          item: minecraft: gold_ingot >
        ],
        [
          new ItemLootPropertyDay(10),
          new ItemLootPropertyKillCurrentItem([ < item: minecraft: wooden_sword > ]),

        ],
        50.0
      ),
      10
    )
  ] as EntityPropertyBase[])
);
```

Со слизней при убийстве деревянным мечом, после 12 дня игры, будет падать изумруд или медный слиток с шансом в 50%, а максимальное количество выпадаемых за раз предметов равно 10 ед.&#x20;

```java
SixikRPGUtils.register(
  new EntityElementBase([ < entitytype: minecraft: slime > ] as EntityType < Entity > [], [
    new EntityDropLootProperty(
      new ItemLootBase(
        [ <
          item: minecraft: diamond > , <
          item: minecraft: gold_ingot >
        ],
        [
          new ItemLootPropertyDay(10),
          new ItemLootPropertyKillCurrentItem([ < item: minecraft: wooden_sword > ]),

        ],
        50.0
      ),
      10 aSixikRPGUtils.register(
        new EntityElementBase([ < entitytype: minecraft: slime > ] as EntityType < Entity > [], [
          new EntityDropLootProperty(
            new ItemLootBase(
              [ <
                item: minecraft: emerald > , <
                item: minecraft: copper_ingot >
              ],
              [
                new ItemLootPropertyDay(12),
                new ItemLootPropertyKillCurrentItem([ < item: minecraft: wooden_sword > ]),

              ],
              50.0
            ),
            10
          )
        ] as EntityPropertyBase[])
      );
    )
  ] as EntityPropertyBase[])
);
```

При ломании камня он будет взрываться!

```java
SixikRPGUtils.register(new BlockSkillBase(blockstate:minecraft:stone, [ new BlockExplosion(10.0, 20.0, 50.0) ]));
```


# Patchouli

Многофункциональный мод с всевозможным полезным для автора сборок инструментарием, таким как создание игровых заданий, реализация мультиблочных механизмов и даже оборудование кастомной справочкой книг


# Начало работы

**Для начала нужно установить саму модификацию** [**Patchouli**](https://www.curseforge.com/minecraft/mc-mods/patchouli).

После установки зайдите в корневую папку игры .minecraft на Вашем компьютере, найдите mods и перенесите туда скачанный файл мода.

***

Для редактирования же файлов разрешения json мы рекомендуем использовать какой-либо текстовый редактор. В статье будет представлена работа на VisualStudio.


# Создание книги

Перво-наперво следует заняться созданием кастомной книги, в которой будут находиться основные сведения, заполняемые Вами же впоследствии.

Разберём данный процесс поэтапно:

**1. Найдите каталог&#x20;**<mark style="color:blue;">**patchouli\_books**</mark>\
Ваши книги и их содержимое будут размещены в папке <mark style="color:blue;">**patchouli\_books**</mark>. Обратите внимание, что Вам нужно один раз запустить игру с установленным Patchouli, чтобы папка появилась.

**2. Создайте свою структуру папок**\
Как только Вы найдёте папку <mark style="color:blue;">**patchouli\_books**</mark>, выберите название для своей книги. Разрешены только символы нижнего регистра. Это внутреннее название Вашей книги, и мы рекомендуем сделать его особенным. Что касается модов, Вы должны назвать их именно так, для чего, непосредственно, будет предназначена книга (например, lexicon для Botania). Для модпаков назовите их как-нибудь с именем Вашего модпака. После того, как закончите с этим, создайте папки и файлы внутри **patchouli\_books**, чтобы это выглядело следующим образом:

<div align="left"><figure><img src="/files/2JcYwxC2YPRHwPxEvBuJ" alt=""><figcaption></figcaption></figure></div>

Обратите внимание, что создание **en\_us** папки означает, что вы создаете **"английскую"** версию своей книги. Содержимое, которое Вы помещаете в **en\_us** папку, всегда загружается как "основное", поэтому, даже если изначально книга не должна быть на английском языке, Вам нужно поместить туда свой основной материал. (Но Вы можете писать в этот файл на русском языке)

**3. Заполните&#x20;**<mark style="color:blue;">**book.json**</mark>\
Откройте файл **book.json** с помощью текстового редактора и заполните его следующим образом:

```json
{
    "name": "BOOK NAME",
    "landing_text": "LANDING TEXT",
    "version": 1
}
```

где **"name"** — это название, под которым будет отображаться Ваша книга, а **"landing\_text"** - текст, который будет отображаться на левой странице книги в игре. В **version** указывается, к какому изданию она относится. Всякий раз, когда Вы обновляете свой справочник, необходимо также изменять значение издания.

<div align="left"><figure><img src="/files/xctxmhRCobk7FDQKUWC2" alt=""><figcaption></figcaption></figure></div>

**4. Проверьте в игре**\
Запустите Майнкрафт и проверьте, появилась ли книга. Если Вы нигде не ошиблись, она будет на вкладке **Разное**. Если Вы не видите своей книги, проверьте, правильно ли загружен Patchouli и нет ли каких-либо ошибок в настраиваемом файле.

<div align="left"><figure><img src="/files/jvr6zzvTQYsPXZssjVmp" alt=""><figcaption></figcaption></figure></div>

Книгу можно изменять без выхода из игры!


# Содержимое книги

Пришло время добавить содержимое книги. Перейдите в папку спправочника, а затем в en\_us и создайте здесь следующую структуру файлов:

* en\_us
* entries (папка)
* test (папка)
* test\_entry.json (файл)
* categories (папка)&#x20;
* test\_category.json (файл)&#x20;
* templates (папка)

<div align="left"><figure><img src="/files/QvTluSn4KmfipLIeZhxL" alt=""><figcaption></figcaption></figure></div>

Откройте **test\_entry.json** и **test\_category.json**, а после заполните их следующим образом:

{% code title="test\_entry.json" %}

```json
{
  "name": "test",
  "icon": "minecraft:writable_book",
  "category": "test_category",
  "pages": [
    {
      "type": "patchouli:text",
      "text": "Это тестовая запись, но она должна появиться!!"
    }
  ]
}
```

{% endcode %}

{% code title="test\_category.json" %}

```json
{
    "name": "Test Category",
    "description": " Это тестовая категория для тестирования!",
    "icon": "minecraft:writable_book"
}
```

{% endcode %}

Сохраните свои файлы, затем вернитесь в игру и откройте книгу. Щелкните по карандашу в левом нижнем углу с помощью клавиши Shift. Когда Вы это сделаете, содержимое книги будет перезагружено, и станут доступны категорию и записи, сделанные Вами ранее.


# Стартовая книга

У Patchouli нет возможности выдачи книг игроку при заходе в мир. Однако эта функциональность легко воспроизводится с помощью достижений.

Мы реализуем скрытое достижение, которое немедленно активируется для игрока, наградой которого станет сам справочник. Награды за достижение предоставляются только разово, поэтому, если у игрока не отменено достижение, это должно произойти один раз, сразу после того, как игрок впервые присоединится к миру.

***Например:*** Замените в файлах мода yourbooknamespace на имя Вашей книги (см. шаг 2) для получения информации об идентификаторе справочника. *`/patchouli_books/yourbooknamespace/advancements/grant_book_on_first_join.json`*

{% code title="/patchouli\_books/yourbooknamespace/advancements/grant\_book\_on\_first\_join.json" %}

```json
{
  "criteria": {
    "tick": {
      "trigger": "minecraft:tick"
    }
  },
  "rewards": {
    "loot": [
      "yourbooknamespace:grant_book_on_first_join"
    ]
  }
}
```

{% endcode %}

{% code title="/patchouli\_books/yourbooknamespace/loot\_tables/grant\_book\_on\_first\_join.json" %}

```json
{
  "type": "advancement_reward",
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "item",
          "name": "patchouli:guide_book",
          "functions": [
            {
              "function": "set_nbt",
              "tag": "{\"patchouli:book\": \"YOURBOOKIDHERE\"}"
            }
          ]
        }
      ]
    }
  ]
}
```

{% endcode %}

**Вставьте данные строки к себе в файл, если их нет, а затем введите идентификатор своей книги там, где это указано.**


# Мультиблочные структуры

Мультиблочные механизмы позволяют разработчику проектов по Minecraft реализовать самые необычные функции через кастомные структуры, которые Вы сами же можете создать.

Подобные дополнения создают особый этап развития в модпаке и добавляют антуража техническим проектам. Итак, чтобы создать свою структуру, Вам нужно обратиться к соответствующему JSON файлу: `"multiblock": { }`

Здесь мыбираем блоки для своей структуры, и начинаем их вписывать в наш JSON файл.

```json
"multiblock": {
    "mapping": {
        "G": "minecraft:gold_block",
        "R": " minecraft:stained_hardened_clay[color=red]",
        "W": "minecraft:wool"
    }
}
```

**Узор**\
Теперь, когда мы указали, какие блоки использовать в структуре механизма, нам нужно задать ему форму. Для этого мы идем сверху вниз, слой за слоем, и переводим каждый слой из блоков в строки в файле.

Получается как бы вид сбоку по слоям:

<div align="left"><figure><img src="/files/AqLskZnkSQPuiW5GeuBJ" alt=""><figcaption></figcaption></figure></div>

Осталось сделать еще одну последнюю вещь. **Нам нужно указать игре, где находится центр мультиблочной структуры**. Можно подумать, что он находится в центре кода, но в некоторых случаях у Вас могут быть механизмы, которые имеют необычную форму и вид, а их центр находится не ровно по центру или в середине.

**Мы указываем центр, заменяя один из символов** в шаблоне на ноль. По умолчанию ноль сопоставляется с воздухом, но если Вам нужно придать ему другое значение, Вы всегда можете просто поставить "0" в отношении того, с чем Вы собираетесь это сделать.

Идеально подходящее место расположения контролера/центра может выглядеть следующим образом:

<div align="left"><figure><img src="/files/C7pdIIj9pm8VZDb76Pbj" alt=""><figcaption></figcaption></figure></div>

**Несколько дополнительных нюансов**

У мультиблочной структуры может быть еще **несколько разных значений:**

* **symmetrical** (логический) По умолчанию используется значение false. Установите значение true, если механизм симметричен относительно вертикальной оси своего центра. Это не обязательно, но если Вы это сделаете, Patchouli не будет проверять все вращения, так что это лучше оптимизирует игру.
* **offset** (массив int, 3 значения) Массив int из 3 значений (\[X, Y, Z]) для смещения мультиблока относительно его центра. В нашем случае мы установим значение symmetric равным true и не будем указывать offset, поскольку мы уже поставили 0 в нужном месте.

## Итоговый вариант

Давайте сложим наш шаблон, отображение и другие значения вместе, чтобы получить следующий текст в файле настроки:

```json
"multiblock": {
    "pattern": [
        [ " GRG ", "GGRGG", "RRRRR", "GGRGG", " GRG " ], 
        [ "GG GG", "G G", " ", "G G", "GG GG" ],
        [ "G G", " ", " ", " ", "G G" ], 
        [ "G G", " ", " 0 ", " ", "G G" ], 
        [ "_WWW_", "WWWWW", "WWWWW", "WWWWW", "_WWW_" ]
    ],
    "mapping": {
        "G": "minecraft:gold_block",
        "W": "minecraft:wool",
        "R": "minecraft:stained_hardened_clay[color=red]"
    },
    "symmetrical": true
}
```

В самой книге можно отобразить структуру механизма в мире, чтобы посмотреть её и даже заполнить, проверив тем самым, правильно ли мы всё сделали.

<figure><img src="/files/USq7SDGlwP2hftO2G29j" alt=""><figcaption></figcaption></figure>


# Revelationary

В [**Revelationary**](/modifications/sozdanie-kontenta/revelationary) Вы можете использовать пакеты данных или <mark style="color:blue;">**API Revelation**</mark>, чтобы постепенно раскрывать блоки в мире по мере продвижения игрока. Простая расщелина, заполненная камнями, может оказаться наполненной жизнью и рудой, когда игрок побеждает босса или достигает важной вехи развития.

До тех пор, пока у игрока нет необходимого прогресса, блоки и предметы, которые Вы регистрируете в [**Revelationary**](/modifications/sozdanie-kontenta/revelationary) через API или <mark style="color:blue;">**DataPack**</mark>, будут иметь только загадочные имена, а в случае блоков в мире будут выпадать те же дропы, что и блок, под который он замаскирован, что не позволит игроку использовать в самом начале закрытые предметы или ресурсы. Вместо этого вы можете открыть ресурсы по мере прогрессии в проекте.

В данной статье будет рассмотрена работа с данным модом через дапаки. Активация может происходить через любой загрузчик датапаков ([**Kube JS**](/modifications/sozdanie-kontenta/kubejs), **Open Loader**, **Global Datapacks**, **Paxi** и др.).

Файлы с изучениями должны храниться в документах формата **JSON**, поместить их стоит в папки `resources/data/<<mod_id>>/revelations`


# Скрытие контента

Изучения в данном моде представляют собой маскировку блока/предмета под другой блок/предмет до срабатывания определенного триггера-события, после которого маскировка исчезает и игрок получает новые знания. Например, пока игрок не сделает железную кирку, все алмазы будут замаскированы под камень. При этом, если говорить о маскировке предметов, то дополнительно предмет получает неопределенное имя (набор непонятных символов).

Стоит также знать, что замаскированные блоки сохраняют свойства от исходного блока: хитбокс, свет и пр. То есть светящийся камень, замаскированный под обычный камень, будет светиться! Таким образом, одни растения лучше маскировать под другие, а руды – под каменные блоки и т. д.

### Формат создания изучения следующий:

{% code overflow="wrap" %}

```json
{
    Для блоков мы пишем маскируемый блок и блок-маскировку, который мы будем видеть вместо маскируемого.
    "block_states": {
    "маскируемый блок": "маскировка",
    ….
},
```

{% endcode %}

Для предметов:

{% code overflow="wrap" %}

```json
 "items": {
    "маскируемый предмет": "маскировка"
  },
 Триггер – это событие, после которого маскировка исчезает и игроку становится виден и понятен маскируемый предмет/объект. 
 "advancement": "достижение"
}
```

{% endcode %}

## Пример использования

Приведем пример создания изучения. Для загрузки датапаков будем использовать [**KubeJS**](/modifications/sozdanie-kontenta/kubejs).

Структура датапака будет выглядеть следующим образом. `data: saudade -> revelations -> rev1.json`. Внутри документа `rev1.json` напишем параметры изучения. Для следующих изучений просто создайте аналогичный текстовый документ формата **json** с другим именем, например, `rev2.json`.

<div align="left"><figure><img src="/files/0NMSzWIgwEWxuntanhQJ" alt=""><figcaption></figcaption></figure> <figure><img src="/files/I2zWdUJg1auwW20Of92I" alt=""><figcaption></figcaption></figure> <figure><img src="/files/Ug4jUMzCvEdYvhCVVSYT" alt=""><figcaption></figcaption></figure> <figure><img src="/files/4NR4Iaqtw80moi4k65ID" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="/files/Gr1OQwAvyRqEhbB2w5r0" alt=""><figcaption></figcaption></figure></div>

В примере вся трава будет замаскирована под маяки, вся высокая трава – на обсидиан и незеритовые блоки (нижний уровень высокой травы – обсидиан, верхний – незеритовый блок), а все звезды нижнего мира – под порох. При том, порох будет светиться, так как свойство свечение унаследовано у звезды нижнего мира. Событием же, снимающим данную маскировку является выполнение достижения `minecraft:nether/root`.

```json
{
  "block_states": {
    "minecraft:grass": "minecraft:beacon",
    "minecraft:tall_grass": "minecraft:obsidian",
    "minecraft:tall_grass[half=upper]": "minecraft:netherite_block"
  },
  "items": {
    "minecraft:nether_star": "minecraft:gunpowder"
  },
  "advancement": "minecraft:nether/root"
}
```

<div align="left"><figure><img src="/files/ziLQcssusl7Kah3BMaMI" alt=""><figcaption><p>Как видно, звезда нижнего мира выглядит как порох, но имеет нечитаемое имя и свои исходные свойства (свечение)</p></figcaption></figure></div>

<div><figure><img src="/files/q4fhDjvIV0gagcQWTcBu" alt=""><figcaption><p>Трава лишь изменяет внешний вид, но свойства остаются прежними!</p></figcaption></figure> <figure><img src="/files/hWjuHtL3tTo7geyAQ6Jl" alt=""><figcaption></figcaption></figure></div>


# Наименования объектов

Название объекта маскировки отображается в виде набора символов. Данный момент можно отрегулировать и дать маскированному объекту/предмету собственное название. Для этого необходимо в файл изучения добавить дополнительную запись.

Для блоков:

```json
"block_name_replacements": {
    "маскируемый блок": "имя"
}
```

Для предметов:

```json
"item_name_replacements": {
    "маскируемый предмет": "имя"
}
```

### Пример ниже демонстрирует использование данной опции:

```json
{
  "advancement": "minecraft:adventure/root",
  "block_states": {
    "minecraft:grass": "minecraft:beacon"
  },
  "items": {
    "minecraft:nether_star": "minecraft:gunpowder",
    "minecraft:diamond_ore": "minecraft:stone"
  },
  "item_name_replacements": {
    "minecraft:nether_star": "block.minecraft.poppy",
    "minecraft:diamond_ore": "Probably Stone?",
    "minecraft:grass": "block.minecraft.dandelion",
    "minecraft:gold_ore": "Since Gold Ore is not in the items tag above, you should never see this"
  },
  "block_name_replacements": {
    "minecraft:grass": "block.minecraft.dandelion"
  }
}
```


# Квесты

В данном разделе Вы узнаете о том, как создавать квесты для своей сборки. Здесь описаны модификации, позволяющие разработать внутриигровые задания.


# FTB Quests

Мод для Minecraft, добавляющий в игру возможность создавать собственные квесты, назначать награду за их выполнение, вносить сюжетные ветви развития и многое другое.


# Примечания

#### При использовании данной модификации в своём проекте:

* Возрастает интерес к сборке и к её автору.
* Появляется вектор развития в сборке.
* Улучшается понимание модов и механик сборки.

#### Авторы сборок получают  возможность создавать квесты и тем самым:

* Появляется возможность реализовывать новые механики (например, квесты, внутриигровой магазин).
* Открывается простор для организации различных концепций развития.
* Предоставляется возможность объяснения новых для игроков модов и механик.

Статья посвящена работе с FTB Quests для версии Minecraft 1.16 и выше *(хотя многое из рассматриваемого актуально и для предыдущих версий игры).*

Все квесты и необходимые для них файлы хранятся в папке **`.minecraft/config/ftbquests`**.


# Начало работы

Чтобы начать создавать квесты, Вам необходимо прописать следующую команду:

```
/ftbquests editing_mode true
```

Данная команда даст Вам возможность редактировать квесты.

Далее нужно перейти во вкладку, где располагаются квесты. Это можно сделать тремя способами:

1. Открыть инвентарь, в левом верхнем углу, если установлен мод, найти иконку книги и нажать на неё.
2. Взять из инвентаря творческого режима предмет <mark style="color:blue;">**Книга Квестов**</mark> и щелкнуть `ПКМ`, удерживая этот предмет в руке.
3. Зайти в настройки управления и настроить клавишу для открытия квестов. В примере ниже поставлена клавиша `k`

<figure><img src="/files/nkT7ZyPRdTIf659RbO2J" alt=""><figcaption><p>Настройки управления</p></figcaption></figure>

Проделав описанные выше действия, Вы попадете в следующий интерфейс (назовем его **Интерфейс Квестов**):

<figure><img src="/files/sQmJoONYwGoRnpXUBEC9" alt=""><figcaption><p>«Интерфейс Квестов»</p></figcaption></figure>

В верхнем левом углу указывается название сборки (Дефолтное название «Модпак»). Рядом располагается кнопка в виде зеленого плюсика для **добавления новых глав или групп глав**. Затем следует значок в виде канцелярской кнопки, позволяющий закреплять **данное боковое меню открытым**.

В нижнем правом углу находится еще три кнопки, самая важная из которых нижняя (в виде шестеренок). Это **общие настройки квестов**.


# Общие настройки

Нажмите на иконку шестеренок в нижнем правом углу Интерфейса квестов, чтобы открыть следующее меню:

<div align="left"><figure><img src="/files/qS1Qic6D1AFxVCUdNybP" alt=""><figcaption></figcaption></figure></div>

Разберёмся в нём:

* **Редактировать файл** – содержит глобальные настройки квестов.
* **Сбросить прогресс** – сбрасывает продвижение во всех главах сразу.
* **Завершить мгновенно** – мгновенно завершает квесты во всех главах.
* **Таблицы вознаграждений** - позволяет настроить коробки лутов и пр.
* **Сохранить как файл** – даёт возможность сохранить все созданные квесты в виде папки, расположенной в директории Вашей игры: **`.minecraft/local/ftbquests/saved/«Название сохранения»`**.
* **Перезагрузить тему** – перезагружает тему квестов (см. раздел [<mark style="color:blue;">**Дизайн квестов**</mark>](/modifications/quests/ftb-quests/quests-design)).
* **Открыть Wiki** – открывает ссылку на страницу с википедией мода.


# Редактирование файла

Рассмотрим подробнее вкладку «Редактировать файл».

После перехода в этот раздел Вы увидите 3 группы настроек:

1. **Название**: строка для названия сборки.
2. **Иконка**: логотип сборки или связанный по тематике предмет.
3. **Теги**: используются при работе с KubeJS.
4. **Запасные предметы**: специальные предметы, выдаваемые игроку в интерфейсе квестов, в правом верхнем углу, (если данные предметы настроены) по истечении таймера.
5. **Таймер запасных предметов**: это время, которое игроку необходимо прождать, чтобы получить запасные предметы.
6. **С монстров падает коробка с лутом**: позволяет определить, выпадают ли с мобов коробки с лутом.
7. **Отключить ГПИ**: настройка, предоставляющая Вам возможность заблокировать весь графический интерфейс с квестами.
8. **Масштаб сетки**: установка собственного размера сетки.
9. **Lock Message**.
10. **Отключить тост завершения**: даёт настроить отображение уведомлений о завершении (выполнении) квестов.

<div><figure><img src="/files/YU9W4wzdgcnacOcueVlo" alt=""><figcaption></figcaption></figure> <figure><img src="/files/A64xmbDSN1YjDjx7D82X" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="/files/l8zVkZal8xn5gTZf2Eci" alt=""><figcaption></figcaption></figure> <figure><img src="/files/946j93ScoM4f0yX1f53s" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/PehxfY0FcnFNcEV7eUPq" alt=""><figcaption></figcaption></figure>

<div><figure><img src="/files/V460EwxadhJLurvFBMkF" alt=""><figcaption></figcaption></figure> <figure><img src="/files/XGqrhLLLtndPGRINY6OX" alt=""><figcaption></figcaption></figure></div>

#### Модпак > По умолчанию

1. **Награда «Командное вознаграждение» (при установленном FTB Teams)**: предоставляет возможность настроить, будет ли по умолчанию награда выдаваться всей команде игроков или только одному игроку.
2. **Задача «Использ. Предметы»**: определяет, будут ли предметы, необходимые для выполнения квестов, по умолчанию забираться из инвентаря игрока или достаточным будет их наличие в инвентаре.
3. **Награда «Авто.-забрать»**: позволяет определить, будет ли награда забираться автоматически или по клику игрока.
4. **Форма квеста**: делает возможным установку формы квеста по умолчанию.
5. **Квест «Отключить рецепт JEI»**: с его помощью можно настроить отображение рецептов в JEI по умолчанию для всех квестов.

<figure><img src="/files/lYYaBiPcrjqTMsu1FHSD" alt=""><figcaption></figcaption></figure>

#### Модпак > С монстров падает коробка лута с пустым весом

Здесь Вам доступна опция <mark style="color:blue;">**«С монстров падает коробка с лутом»**</mark>, с помощью которой можно установить шанс выпадения коробок *(работает для всех коробок, но для каждой отдельной можно установить свои шансы)*.

1. **Пассивный**: для мирных мобов
2. **Монстр**: для агрессивных мобов
3. **Босс**: для боссов

<figure><img src="/files/M9P3OotDQCMvYp05HCP5" alt=""><figcaption></figcaption></figure>


# Таблицы вознаграждений

Рассмотрим подробнее вкладку «Таблицы вознаграждений».

Чтобы **создать таблицу вознаграждений**, нажмите на зеленый плюсик и введите название таблицы *(желательно устанавливать название, привязанное к типу наград таблицы)*.

После создания таблицы перейдите в её настройки с помощью `ЛКМ`.

<div><figure><img src="/files/Fd8rCdqSlAD6FOkKiMEG" alt=""><figcaption></figcaption></figure> <figure><img src="/files/IFLJ4OkTEwyb6VxpdQba" alt=""><figcaption></figcaption></figure></div>

* Во вкладке <mark style="color:blue;">**«Настройки»**</mark> устанавливаются общие параметры таблицы вознаграждений: название, иконка *(может прогрузиться не сразу, а только после перезахода в мир)*, тэги *(для KubeJS)*, пустой вес *(шанс)*, размер лута по умолчанию *(количество выдаваемых предметов в качестве награды)*, скрытие подсказки и возможность использования названия таблицы.
* Кнопка <mark style="color:blue;">**«Применить»**</mark> используется для сохранения настроек.
* Кнопка <mark style="color:blue;">**«Добавить»**</mark> устанавливает тип содержимого таблицы вознаграждений *(тип награды)*.

<div align="left"><figure><img src="/files/lxqIiFZez6SXUzFA38Tg" alt=""><figcaption></figcaption></figure></div>

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

При этом таблицу вознаграждений можно преобразовать в коробку с лутом. Чтобы это сделать, создайте таблицу вознаграждений, щелкните по ней `ПКМ` и поставьте галочку напротив пункта <mark style="color:blue;">**«Ящик лута»**</mark>:

<figure><img src="/files/0bUMv2htrX3MFnax3TI4" alt=""><figcaption></figcaption></figure>

Как только Вы это сделаете, в настройках Таблицы вознаграждений появятся **новые настройки**:

<figure><img src="/files/ik8I0tijGUF31ahwWOZo" alt=""><figcaption></figcaption></figure>

#### Таблица вознаграждений > item.ftbquests.lootcrate.name

1. **ID**: id коробки с лутом.
2. **Название предмета**: название коробки с лутом.
3. **Цвет**: цвет коробки с лутом (в модели цвета RGB).
4. **Свечение**: наличие свечения.

#### Таблица вознаграждений > item.ftbquests.lootcrate.name > Награда монстра

* Позволяет установить шансы выпадения коробки с лутом с мобов *(пассивных, монстров, боссов).*


# Создание лут-коробки

Рассмотрим принцип создания коробки с лутом.

Сначала создадим таблицу вознаграждений с названием **«Apple Box»** (для примера) и установим `ПКМ` галочку напротив пункта <mark style="color:blue;">**«Ящик лута»**</mark>.

<figure><img src="/files/IhOSg0pKoqhueyJC0kP0" alt=""><figcaption></figcaption></figure>

Добавим в качестве награды предметы: 12 обычных яблок, 3 золотых и 1 зачарованное золотое яблоко.

Для этого нажмите на тип награды **«Предмет»**:

<figure><img src="/files/h2QZnr5fbtT1NCPj5w6G" alt=""><figcaption></figcaption></figure>

Установите в первой вкладке тип предмета, а в третьей *(с листом бумаги)* – количество предметов. Проделайте это действие для всех предметов *(наград)*.

<div align="left"><figure><img src="/files/yli9M9klci5YEwKWxK1E" alt=""><figcaption></figcaption></figure></div>

Теперь установим шансы выпадения предметов (по умолчанию шансы выпадения всех предметов равны). Чтобы это сделать, щелкните ПКМ по предмету и нажмите <mark style="color:blue;">**«Установить вес»**</mark>. Введите шанс выпадения: чем выше число, тем выше шанс выпадения данного предмета. В данном примере шанс выпадения яблок был изменен с 1.0 на 3.0, и тем самым обычные яблоки, на фоне остальных предметов, теперь имеют шанс выпадения 60%.

<div><figure><img src="/files/rKuLuJ84junvZnM3n4sy" alt=""><figcaption></figcaption></figure> <figure><img src="/files/6oP8eYUS0iNvUZixnMov" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/zlbE985Zo50Of3BTgxku" alt=""><figcaption></figcaption></figure>

Настроим саму коробку с лутом. Для этого перейдем в настройки Таблицы вознаграждений и выставим следующие значения (Вы можете установить свои настройки).

Нажмём кнопку <mark style="color:blue;">**«Применить»**</mark>, тем самым сохранив настройки. Получим следующий предмет *(все коробки с лутом можно найти во вкладке мода FTB Quests в творческом режиме)*.

По нажатию `ПКМ` с лут-коробкой в руке Вы будете получать случайным образом одну из настроенных наград.

<figure><img src="/files/7vZCjQlPizBfff5lNyY0" alt=""><figcaption></figcaption></figure>

<div align="left"><figure><img src="/files/iVf3yr8ewE83xuNeW2xq" alt=""><figcaption></figcaption></figure></div>


# Дизайн квестов

Дизайн квестов включает внешний вид интерфейса квестов, самих заданий, текста и пр. Рассмотрим основные способы оформления.

Для большинства из способов Вам понадобится дополнительный мод – глобальный загрузчик ресурсов (например, Open Loader, KubeJS, Paxi, Global Data, Load My Resources! и прочие подобные модификации).

В данном разделе расписана информация о принципах работы со следующими элементами оформления:

1. **Темы**
2. **Изображения**
3. **Дополнительные инструменты дизайна**

Самый глобальный способ изменить дизайн квестов – это использование тем. Чтобы **изменить тему**, Вам понадобится глобальный загрузчик ресурсов. После чего будут необходимы файлы модов FTB Quests и FTB Library.

Перво-наперво обратимся к файлу из модификации **`FTB Quests: ftb-quests.jar\assets\ftbquests\ftb_quests_theme.txt`**. В этом документе находятся общие настройки мода.

#### Содержание документа ftb\_quests\_theme.txt

* **background: ftblibrary:textures/gui/background\_squares.png; color=#DCFFFFFF; tile\_size=64** — Данные строчки отвечают за возможность изменить задний фон. При этом можно изменить как текстуру заднего фона полностью (изменив текстуру background\_squares.png в папке ftblibrary:textures/gui/ через глобальный загрузчик), так и просто цвет и размер сетки (значения color и tile\_size).
* **extra\_quest\_shapes: diamond, pentagon, hexagon, octagon, heart, gear** — Позволяет поменять текстуры форм квестов и даже добавить собственные. Чтобы изменить существующую текстуру, замените в папке **`ftb-quests.jar\assets\ftbquests\textures\shapes\[имя_формы]`** размещенную текстуру на свою. Для добавления новой формы создайте в **`ftb-quests.jar\assets\ftbquests\textures\shapes\`** папку с именем Вашей формы, скопируйте туда файлы из любой другой формы, изменив текстуры на собственные. Затем впишите название папки с именем новой формы в файл **`ftb_quests_theme.txt`**, через запятую после основных форм: **`extra_quest_shapes: diamond, pentagon, hexagon, octagon, heart, gear, new_shape`**.
* **text\_color: #FFFFFF; hover\_text\_color: #FFFFA0; disabled\_text\_color: #999999** — С помощью этих строк Вы можете настроить цвет текста в квестах. Просто поменяйте значение цвета на собственные.

В целом, меняя значения в упомянутом выше тестовом документе, а также текстуры в файлах мода, Вы сможете добиться значительных результатов в визуальной части Ваших квестов.

<figure><img src="/files/KeodYdokiPJVTXGv2OtS" alt=""><figcaption><p>Пример изменения цвета сетки, текста и элементов интерфейса</p></figcaption></figure>

Следующий способом улучшения дизайна можно назвать **работу с изображениями**. Изображения используются в формате заднего фона или в качества элементов дизайна, для лучшего ориентирования в квестах.

Чтобы добавить изображение, необходимо в созданной главе квестов щелкнуть ПКМ в любом месте сетки интерфейса и выбрать в качестве размещаемого элемента <mark style="color:blue;">**«Изображение»**</mark>.

<div align="left"><figure><img src="/files/pLNBOPwDUBxWdugHZs76" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="/files/GR8oCkFFDOEYhmeyuTEz" alt=""><figcaption></figcaption></figure></div>

Чтобы изменить его, щелкните по нему ПКМ и нажмите клавишу <mark style="color:blue;">**«Настроить»**</mark>.

#### Вам будут доступны следующие параметры для настройки изображения:

* **X**: положение изображения по оси X
* **Y**: положение изображения по оси Y
* **Ширина**: ширина изображения
* **Высота**: высота изображения
* **Вращение**: угол поворота изображения
* **Изображение**: сама картинка

Собственные изображения Вы можете добавить через глобальный загрузчик, поместив их в папку **`resources/assets/modpack/any_icon_name.png`**.

<figure><img src="/files/SEUHwz0AH35P5u8O4KQn" alt=""><figcaption></figcaption></figure>

К дополнительным способам изменения дизайна можно отнести, например, использование дополнительных модификаций по типу **Quest Plaques** (позволяет поменять вид уведомлений выполнения заданий). С помощью данного мода можно добиться подобных уведомлений:

<figure><img src="/files/73SZaoHzD3sPYvOiiCNL" alt=""><figcaption></figcaption></figure>


# Главы и группы

Все квесты распределены по главам. Главы могут быть объединены в группы глав.

Чтобы **создать главу**, нажмите на плюсик рядом с названием модапака, выберите пункт <mark style="color:blue;">**«Глава»**</mark> и укажите название главы.

Чтобы **создать группу глав**, нажмите на плюсик рядом с названием модапака, выберите пункт <mark style="color:blue;">**«Chapter Group»**</mark> и укажите название группы глав.

<figure><img src="/files/ym357jSgJk86l77Vd5f0" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bWhSGRTw9LxA3zS3MGaX" alt=""><figcaption><p>При этом и главы, и группы глав можно настроить.</p></figcaption></figure>

Для настройки главы доступны следующие параметры:

* Название главы.
* Иконка главы.
* Тэги для KubeJS.
* Подзаголовок – пояснение к главе (отображается при наведении).
* Видимость главы.
* Форма квестов в главе.
* Тост завершения – уведомления о завершении квеста.

<div align="left"><figure><img src="/files/mQZ7MrB35jQSPcMorA95" alt=""><figcaption><p>Пример настроек (изменено название, подзаголовок, иконка)</p></figcaption></figure></div>


# Создание и настройка квестов

Чтобы **создать квест**, необходимо щелкнуть `ПКМ` по любому месту сетки и выбрать тип задания.

При этом каждый квест может содержать в себе несколько задач.

## Типы задач

* **«Предмет»** – задание на получение/израсходование (квестом) предмета.
* **«Уровни опыта»** – потребление (квестом) определенного количества очков опыта.
* **«Посетить измерение»** –путешествие в определенное измерение.&#x20;
* **«Стат»** – проделать определенное действие из статистики.
* **«Убить существо»** – квест на убийство моба(ов).
* **«Место расположения»** – игроку побывать в определенной точке мира (на заданных координатах).&#x20;
* **«Галочка»** – задание, в котором необходимо просто проставить галочку.
* **«Продвижение»** – выполнение достижения.
* **«Посетить биом»** – посещение заданного биома.
* **«Найти структуру»** - нахождение назначенной в задании структуры.
* **«Этап игры»** - квест, связывающий задания с этапами игры (Game Stages мод).
* **«Энергия Forge»** – потребление определенного количества энергии Forge.

Чтобы расширить количество возможных задач, Вы можете использовать возможности дополнений к FTB Quests, таких как **FTB Money** (создание заданий на потребление определенной суммы денег) и **Quest Additions**, который добавляет следующие типы задач:

* **«Break Block»** - разрушение блока.
* **«Place Block»** - размещение блока.
* **«Use Block»** - использовать блок (например, для таких целей, как размещение Ока Эндера в рамку портала Края, открытие сундука и пр.).
* **«Advanced Entity Kill»** - тип задачи, похожий на убийство моба, но учитывающий nbt мобов и предмет, которым убивается моб.&#x20;
* **«Create structure»** - создание структуры (в формате .nbt).
* **«Reach Day»** - достижение определенного дня.
* **«Timer»** - задание, выполняющееся автоматически по истечении заданного времени.

## Пример создания квеста

Создадим квест на получение предметов. Для этого нажимаем `ПКМ` по сетке квестов и выбираем тип задачи <mark style="color:blue;">**«предмет»**</mark>. Затем назначаем предмет, необходимый для получения игроком, и устанавливаем количество этого предмета *(если Вы захотите добавить еще предметы, то сможете это сделать после)*. Нажимаем <mark style="color:blue;">**«Применить»**</mark>.

**Пример квеста на 16 кирпичей:**

<div><figure><img src="/files/pZlDIwxw46hsIs4uFX2O" alt=""><figcaption></figcaption></figure> <figure><img src="/files/0Rfi56VmZ0qyAUL1UB2T" alt=""><figcaption></figcaption></figure></div>

Чтобы добавить другие предметы, щелкните `ЛКМ` по крестику рядом с добавленными предметами и выберите новые предметы.

<div align="left"><figure><img src="/files/K5vQp7gTi6ksqOOzNapR" alt=""><figcaption></figcaption></figure> <figure><img src="/files/ef8epnSrc8FDxRGFcJgJ" alt=""><figcaption></figcaption></figure></div>


# Настройка квестов

Перейдем к рассмотрению принципа настройки квеста.

Для этого нажмите `ПКМ` по квесту и затем перейдите во вкладку <mark style="color:blue;">**«Настроить»**</mark>.

## Типы параметров

* **Название**: имя задания.
* **Иконка**: иконка квеста.
* **Теги**: теги для KubeJS.
* **Подзаголовок**: краткая информация о квесте, отображающаяся при наведении на задание указателя мыши.
* **Описание**: текст с информацией о задании (советуем добавлять через редактор описания в самом квесте).
* **Форма**: назначаемая форма (значок).
* **Скрыть квест, пока не станут видны зависимости**: опция, позволяющая сделать квест невидимым, пока не будут выполнены предыдущие задания, связанные с данным через зависимости.
* **Размер**: геометрические характеристики квестового значка.
* **X**: расположение задания в сетке по оси X.&#x20;
* **Отключить тост завершения**: опция, отвечающая за включение/отключение уведомлений, связанных с квестом.
* **Y**: расположение задания в сетке по оси Y.
* **Зависимости**: опция, предоставляющая возможность определить квесты, от которых будет зависеть данный (в рамках главы легче использовать редактор зависимостей).
* **Требование зависимости**: определение логики между зависимыми квестами (всё выполнено/один завершен/все начаты/один начат).
* **Скрыть линии зависимости**: настройка скрытия линии зависимости между квестами.
* **Скрыть текст, пока квест не будет выполнен**: опция, позволяющая скрывать описание квеста, пока он не будет завершен.
* **Отключить рецепт JEI**: опция, делающая возможным отключение просмотра рецепта предмета через JEI непосредственно в интерфейсе квеста.

## Пример настройки квеста

<figure><img src="/files/rA7jCooZvAjWy4X6ypSQ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/TC4ZXvx5O6dlyiY32Cg1" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/h2mNs8xgi0QhytcJMacx" alt=""><figcaption></figcaption></figure>


# Зависимости квестов

Зависимости позволяют настроить взаимосвязь между квестами, сделать так, чтобы выполнение одного квеста зависело от другого.

## Создание зависимости

Создайте два или более квестов, чтобы назначить между ними связи.

Для этого щелкните по одному из квестов `CTRL + ЛКМ` *(чтобы выделить его)*, а затем `ПКМ` по другому *(чтобы определить тип зависимости)*. Теперь Вы можете выбрать, будет ли квест зависимым или создаст зависимость.

<figure><img src="/files/fv8Nc2CZPsVU6RjyUq2v" alt=""><figcaption></figcaption></figure>

Как только Вы это сделаете, между квестами появятся линии связи, определяющие зависимость.

<div><figure><img src="/files/ibzdyaYbgQbPpUWfE6lQ" alt=""><figcaption><p>Квест «Камень» зависит от квеста «Кирпич»</p></figcaption></figure> <figure><img src="/files/65Q5z8iLUkRjLt7QVicJ" alt=""><figcaption><p>Квест «Камень» создает зависимость для квсета «Кирпич»</p></figcaption></figure></div>

## Удаление зависимости

Чтобы удалить зависимости, выделите с помощью `CTRL + ЛКМ`один из квестов, находящийся в зависимости, нажмите ПКМ по другому и выберите действие <mark style="color:blue;">**«Удалить выбранное из зависимостей»**</mark> или <mark style="color:blue;">**«Удалить как зависимость от выбранного»**</mark>.

<figure><img src="/files/w2BAIcQ4Yh8PehnksJhZ" alt=""><figcaption></figcaption></figure>


# Описания квестов

## Добавление описания

Чтобы **добавить описание квесту**, зайдите в интерфейс (`ЛКМ` по иконке задания). Затем нажмите на кнопку <mark style="color:blue;">**«Добавить»**</mark> и выберите тип данных описания: текст или изображение.

<figure><img src="/files/9MqdpcxAfSHsl9TPifPL" alt=""><figcaption></figcaption></figure>

При добавлении категории <mark style="color:blue;">**«Text»**</mark> просто введите текстовое описание и нажмите <mark style="color:blue;">**«Применить»**</mark>.

При добавлении <mark style="color:blue;">**«Image»**</mark> определите саму картинку и её размеры. Не забывайте об использовании глобального загрузчика ресурсов (изображения помещайте в папку **`assets/modpack/textures/`** в формате [**`.png`**](#user-content-fn-1)[^1]).

<figure><img src="/files/hkhiwff75hkc7s6x5zcv" alt=""><figcaption></figcaption></figure>

## Удаление описания

Для удаления описания выделите `ПКМ` элемент, который необходимо убрать, и нажмите кнопку <mark style="color:blue;">**«Удалить»**</mark>.

[^1]: PNG — растровый формат хранения графической информации, использующий сжатие без потерь по алгоритму Deflate.


# Награды

## Добавление наград

Чтобы добавить награду в игровое задание, щелкните `ЛКМ` по плюсику в разделе <mark style="color:blue;">**«Награды»**</mark> и выберите тип награды.

<figure><img src="/files/E9a17Uo6tdTHu3EyXKRv" alt=""><figcaption></figcaption></figure>

### Типы наград

* **Предмет** – награда в виде определенного предмета или нескольких предметов.
* **Выбор награды** – возможность выбора награды из списка, сформированного в Таблице Вознаграждений.
* **Случайная награда** – получение случайного предмета из списка, сформированного в Таблице Вознаграждений.
* **Награда в виде лута** – тип награды с получением случайного вознаграждения из списка в формате коробки лута.
* **Команда** – тип награды в виде команды.
* **Опыт** – тип награды в виде единиц опыта.

### Параметры наград

Награды имеют определенные параметры, которые можно настроить, щелкнув `ПКМ` по награде.

* **Авто забрать**: опция, позволяющая определить, будет ли награда получена автоматически или потребует клика ЛКМ со стороны игрока. При этом есть дополнительные характеристики этой опции: автоматическое получение награды, но при этом вознаграждение будет скрыто («Включено, Невидимый»).
* **Награда команде**: получит ли награду один игрок или вся команда *(при совместной игре)*.

<figure><img src="/files/wD9i9X0Tx6JH9WnmUmDl" alt=""><figcaption></figcaption></figure>


# Магазин

Для FTB Quests существует аддон FTB Money, с помощью которого становится возможно создать внутриигровой магазин, использующий специальную валюту.

Чтобы это сделать, откройте интерфейс квестов в режиме редактирования и зайдите в раздел <mark style="color:blue;">**«Shop»**</mark>.

<div align="left"><figure><img src="/files/pKObcYFQBd4N2AnRmY0o" alt=""><figcaption></figcaption></figure></div>

Теперь Вам нужно добавить категорию товаров. Для этого щелкните по плюсику (<mark style="color:blue;">**«Добавить»**</mark>) в интерфейсе <mark style="color:blue;">**Shop**</mark>, введите название раздела, выберите предмет в качестве иконки и подтвердите действие (кнопка <mark style="color:blue;">**«Применить»**</mark>).

<figure><img src="/files/wyAmooTgk3uaEwqOen9i" alt=""><figcaption></figcaption></figure>

Далее перейдите в созданный раздел `ЛКМ`. Чтобы добавить товар, необходимо, находясь в разделе, нажать <mark style="color:blue;">**«Добавить»**</mark>.

<figure><img src="/files/yW2dhR7K10SBRdEDFVPe" alt=""><figcaption></figcaption></figure>

Затем необходимо выбрать предмет, который будет продаваться, а также установить его количество, только после этого Вы можете подтвердить выбор (кнопка <mark style="color:blue;">**«Применить»**</mark>). Перед Вами появится окно, куда Вы сможете вписать число. Это число – цена на данный предмет (во внутриигровой валюте).

<figure><img src="/files/jyW8BHJGZWs1WQZxU9KV" alt=""><figcaption></figcaption></figure>

Кроме магазина, FTB Money позволяет создавать задачу на определенную сумму внутриигровых монет *(тип задачи Money)*, а также выдавать монеты в качестве награды за выполнение квестов *(тип награды Money)*.


# Особые возможности

Аддон «Quest Additions»

**Quest Additions** – это аддон для FTB Quests, добавляющий к моду новые возможности и типы задач.

## Ключевые возможности

* **Повторяемость квестов**: в настройках квестов появится новая опция - **Repeatable**, позволяющая установить, можно ли будет выполнить квест снова. Подобную функцию можно использовать, например, для создания магазина (как альтернатива FTB Money): в качестве типа задачи устанавливается предмет с поднастройкой потребления предмета (он будет играть роль валюты), а в качестве награды – предмет, который игрок будет «покупать».
* **Секретные квесты**: опция <mark style="color:blue;">**Is Secret**</mark>, даёт возможность скрывать квест, пока он не будет выполнен игроком.

<figure><img src="/files/PZx4nvWrqx1fDVSIIpRU" alt=""><figcaption></figcaption></figure>


# Better Questing

Мод, позволяющий добавлять небольшие задачи, которые игроки могут выполнять, пока покоряют мир Minecraft. Вы сможете создать уникальные квесты – задания с наградами в них, тем самым разнообразив свою


# Начало работы

## Подготовка

Для того, чтобы начать работать с данной модификацией, необходимо сперва скачать её. Аддоны скачивайте при необходимости.

1. [Better Questing](https://www.curseforge.com/minecraft/mc-mods/better-questing) — Базовый мод, позволяющий создавать собственные квесты. Имеется удобный редактор.
2. [Quest Book](https://www.curseforge.com/minecraft/mc-mods/better-questing-quest-book) — Мод, добавляющий квестовую книгу и некоторые конфиги.
3. [Standard Expansion](<https://www.curseforge.com/minecraft/mc-mods/better-questing-standard-expansion >) — Мод, содержащий в себе несколько наград, заданий, импортёров и тем, которые помогут Вам начать использовать Better Questing.

В статье рассматривается создание квестов на версию Minecraft 1.12.2.

[Документация по моду на английском](https://github.com/Funwayguy/BetterQuesting/wiki)

## Начало

Вы скачали модификации и теперь готовы создать свой первый квест. Для этого необходимо загрузить мир и прописать следующую команду:

{% code fullWidth="false" %}

```
/bq_admin edit true
```

{% endcode %}

<div align="left" data-full-width="false"><figure><img src="/files/7XeOYGdbbn5CtYoriuOP" alt=""><figcaption></figcaption></figure></div>

### Знакомство с меню

Для того чтобы открыть меню мода необходимо нажать кнопку `` ` `` по умолчанию.

Здесь Вы увидите четыре кнопки:

* **Exit** — Выход из меню.
* **Quests** — Вкладка, в которой мы с Вами в дальнейшем будем создавать квесты. Вернёмся к ней позже.&#x20;
* **Party** — Здесь Вы можете вступить в группу или создать собственную. Работает только в том случае, если Вы играете на сервере.
* **Theme** — Выбор темы.

<figure><img src="/files/TZ7YBPZFySZArkGmabEC" alt=""><figcaption></figcaption></figure>

<div><figure><img src="/files/OfkSSNrEV27mHVOPV2SW" alt=""><figcaption></figcaption></figure> <figure><img src="/files/Vg6netNhzeayBamdy0nk" alt=""><figcaption></figcaption></figure></div>


# Квесты

Раздел, в котором происходит основная работа над кастомными заданиями.

Вам доступны следующие кнопки:

* **Quest Lines** — Просмотр всех линий квестов.
* **Description** — Описание выбранной линии.
* **Claim All** — Взять все награды за выполненные квесты.
* **Zoom to Fit** — Приблизить.
* **Lock Tray** — Блокировать.
* **Edit** — Редактор.
* **Designer** — Дизайн.
* **Back** — Выйти в меню мода.

<figure><img src="/files/oK9HrJ04Hj6MrlTcssA6" alt=""><figcaption></figcaption></figure>

## Редактор квестовых линий

Здесь Вы сможете создавать и редактировать квесты.

Разберём кнопки, расположенные в левой нижней части редактора:

* **Add New** — Добавить новую линию квестов.&#x20;
* **Import** — Загрузить готовые линии квестов.

<figure><img src="/files/b0eISfmyBSQAKbWzY1Ct" alt=""><figcaption></figcaption></figure>

Теперь **создадим нашу первую линию квестов:**

1. Задаём имя линии квестов
2. Придумываем описание линии

<figure><img src="/files/JZAvPCw1S9OR7edPbNJh" alt=""><figcaption></figcaption></figure>

Разберём кнопки, расположенные в правой части редактора:

* **Icon** — Выбор иконки линии квестов.&#x20;
* **Show** — Настройка отображения линии.
* **Add/Remove Quests** — Кнопка, позволяющая добавлять или удалять квесты.&#x20;
* **Designer** — Интерфейс, в котором Вы можете создавать квесты, настраивать зависимости и управлять их детальными настройками.

<figure><img src="/files/pIsRPPOoV5yejWcO1fzu" alt=""><figcaption></figcaption></figure>


# Конструктор квестов

Подробный разбор кнопок с интерфейсом под названием <mark style="color:blue;">**Designer**</mark>. Здесь Вы сможете создать свои первые квесты и настроить зависимости между ними.

* **Grid Snap** — Изменение размера сетки конструктора.&#x20;
* **Edit Raw** — Скрытые настройки, позволяющие редактировать json-файл.&#x20;
* **Open** — Открыть квест для дальнейшего редактирования.&#x20;
* **New Quest** — Создать новый пустой квест.&#x20;
* **Grab** — Переместить квест.&#x20;
* **Link** — Связать квесты.&#x20;
* **Copy** — Скопировать квест.&#x20;
* **Scale Icon** — Изменить масштаб значка квеста.&#x20;
* **Delete Quest** — Удалить квест.
* **Remove Quest —** Удалить квест из линии. Он остаётся доступным в базе данных.
* **Manual Complete** **—** Завершить квест.
* **Reset Quest** — Сбросить статус квеста.&#x20;
* **Select Icon** — Изменить иконку квеста.&#x20;
* **Edit Icon Frame** — Изменить рамку квеста.

{% embed url="<https://youtu.be/Cv4GvFqL6IY>" %}




---

[Next Page](/llms-full.txt/1)

