Создание модификаций с помощью ModLoader (Beta 1.7.3)

## Подготовка

Вам нужно скачать следующее:

Инструмент |
Скачать
|

JDK | Скачать |

RetroMCP-Java | Скачать (Github) |

ModLoader (MCBeta 1.7.3) | Скачать (GitHub) |

ModLoaderMP Client (MCBeta 1.7.3) | Скачать (Mediafire) |

ModLoaderMP Server (MCBeta 1.7.3) | Скачать (Mediafire) |

Sublime Text или Notepad++ | Скачать (SublimeText) / Скачать (NP++) |


### Подготовка RetroMCP

**RetroMCP** — переписанный, кроссплатформенный Mod Coder Pack (MCP).

Убедитесь что в ваш провайдер не заблокировал добрую часть интернета. Если RetroMCP что-то не сможет скачать то декомпиляция вылетит с ошибкой.

- Переместите скачанный jar файл RetroMCP в новую папку и откройте его.
**Желательно чтобы путь к папке с MCP не содержал символов Кириллицы** - Если вы всё сделали правильно, перед вами откроется Командная строка или Power Shell. Иначе jar либо не откроется, либо выдаст ошибку.
- Введите
**setup**, дождитесь пока MCP создаст все нужные папки и затем впишите**b1.7.3**. - В создавшемся рабочем пространстве найдите папку
**jars**и перейдите в неё. Откройте архиватором (**7-Zip**или**WinRar**) файл**minecraft.jar**, удалите из него папку**META-INF**и распакуйте в него ModLoader. - После распаковки ModLoader, распакуйте ModLoaderMP Client в jar и закройте архиватор.
- Затем повторите такие-же действия с
**minecraft_server.jar**, только не нужно распаковывать сам ModLoader, а вместо ModLoaderMP**Client**нужно распаковать**Server**. - Откройте RetroMCP, если вы его закрыли ранее и введите
**decompile**. Через пару секунд (или минут :^)) исходный код Minecraft и его сервера появится в папке**(Папка MCP)/src**.

## Создание мода

### Главный класс

Главный класс клиентского мода должен находиться в папке **(MCP)/src/minecraft/net/minecraft/src/**.

Создаём класс, *обязательно* называем его mod_**###**.java. **###** нужно заменить на имя вашего мода без пробелов. Я буду использовать идентификатор **testmod**.

Код главного класса:

```
package net.minecraft.src;
public class mod_### extends BaseMod
{
public mod_###()
{
ModLoader.SetInGameHook(this, true, false);
}
public String Version()
{
return "1.0"; // Версия мода, не рекомендую добавлять кириллические символы и "-".
}
}
```

```
package net.minecraft.src;
```

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

```
extends BaseMod
```

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

```
public mod_###()
```

— конструкор класса нашего мода, в нём в будущем мы будем регистрировать Блоки, Предметы, Броню и так далее.

```
ModLoader.SetInGameHook(this, true, false);
```

— «инициализатор» мода. С помощью него ModLoader знает что указанный класс — это мод и загружает его.

**this** — BaseMod, путь к классу мода. У нас это **this**, так как мы работаем с нашим модом который наследует класс BaseMod.

**true** — включает или отключает (если значение **false**) мод.

**false** — этап на котором загружается мод. Если значение — **true**, запуск будет только один раз за каждый тик, если **false** — один раз в каждом кадре.

### Создание блока

Есть два метода регистрации блоков:

**Первый**— без создания специального класса для блока.**Второй**— с созданием класса блока.

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

#### Первый способ

Добавляем после определения класса:

```
public static Block testblock;
```

Здесь мы создаём основу для блока, **testblock** — это идентификатор нашего блока. Он будет использоваться для регистрации, установки имени и текстуры.

Дальше, в конструктор нашего главного класса добавляем:

```
testblock = new Block(100, 0, Material.rock).setStepSound(Block.soundStoneFootstep).setBlockName("testblock").setHardness(1.0F).setResistance(10F);
testblock.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/assets/myblock.png");
ModLoader.RegisterBlock(testblock);
ModLoader.AddName(testblock, "TESTEFICATE");
```

#### Добавляем блок

**new Block(100, 0, Material.rock)…**

**100** — ID блока который мы добавляем. До выхода снапшота 13w02a все текстуры хранились в файлах «/terrain.png» и «/gui/items.png». Максимальное количество текстур в них — **256** (*16*16*).

Зачем-то список ID блоков был ограничен до 256, хотя слотов для предметов доступно 32000. Если ID вашего блока пересечётся с ID блока другого мода — то… В общем, ничего хорошего.

**0** — Индекс текстуры в файле «/terrain.png», мы не будем это использовать, так что оставляем 0. 0 — камень.

**Material.rock** — Материал для блока. Каждый из доступных материалов имеет свои особенности и свойства. Вот список всех доступных материалов:

Материал |
Блок |
Особенности
|

air | Воздух | Нет особенностей
|

grassMaterial | Трава | Нет особенностей
|

ground | Земля | Нет особенностей
|

wood | Дерево | Воспламеняется
|

stone | Камень | Ничего не вырастет (в коде стоит флаг
.setNoHarvest()) |

iron | Железо | Ничего не вырастет
|

water | Вода | Не полный блок
|

lava | Лава | Не полный блок
|

leaves | Листва | Воспламеняется, Полупрозначный, Не полный блок (Запрет спавна сущностей)
|

plants | Растения | Не полный блок
|

sponge | Губка | Имеет такой-же цвет как у шерсти.
|

cloth | Шерсть | Воспламеняется
|

fire | Огонь | Не полный блок, не отображается на карте
|

sand | Песок | Нет особенностей
|

circuits | Факела, кнопки, рельсы, лестницы | Не отображается на карте, Имеет техническое назначение
|

glass | Стекло | Полупрозрачный
|

tnt | Динамит | Воспламеняется, Полупрозначный (
?) |

field_4262_q | ? |
Не используется
|

ice | Лёд | Полупрозрачный
|

snow | Снежный ковёр | Не полный блок, Ничего не вырастет, Полупрозрачный, «Ковровый»
|

builtSnow | Блок снега | Ничего не выростет
|

cactus | Кактус | Полупрозрачный, Не полный блок
|

pumpkin | Тыква | Не полный блок (
?) |

portal | Портал в незер | Не отображается на карте, Не замедляет движение при прохождении
|

cakeMaterial | Торт | Не отображается на карте, Не полный блок
|

field_31068_A | Паутина | Ничего не вырастет, Не полный блок
|

field_31067_B | Поршень | Имеет техническое назначение
|


**.setStepSound(Block.**— звук который воспроизводится при хождении по блоку*?*);нужно заменить на 1 из существующих.**?**

В Бете 1.7.3 существует 9 видов звука хождения:

Звук |
Блок(-и)
|

soundPowderFootstep | Звук хождения по красному камню. |

soundWoodFootstep | Звук хождения по дереву. |

soundGravelFootstep | Звук хождения по гравию. |

soundGrassFootstep | Звук хождения по траве. |

soundStoneFootstep | Звук хождения по камню и остальным блокам для которых не установлен уникальный звук. |

soundMetalFootstep | Звук хождения по золоту, алмазам, рельсам, железной двери и спаунеру. |

soundGlassFootstep | Звук хождения по льду, светокамню и порталу в незер. |

soundClothFootstep | Звук хождения по шерсти, снегу, кактусу и торту. |

soundSandFootstep | Звук хождения по песку и песку душ. |


**.setBlockName(«testblock»)**— Имя блока, использвуется для получения имени из файла локализации. В нашем случае мы будем устанавливать имя блока после регистрации, так что можно не именять.

**.setHardness(**— Упругость блока при ломании.*1.0F*)— уровень упругости, например у камня —**1.0F**.**«1.5F»**нужно добавлять обязательно, иначе будут ошибки при компиляции.**F**

**.setResistance(**— Взрывоустойчивость блока, чем выше, тем меньше шанс уничтожения блока взрывом. У обсидиана, к примеру —*10F*), динамит уничтожить его не может.**6000F**

###### Дополнительные флаги

**.setLightOpacity(**— Уровень поглащения света блоком (*?*)*требуется уточнить*)

**.setLightValue(**— Уровень света издаваемый блоком. Установленное значение «*?*F)» умножается на**?***15*.

**.setBlockBounds(x, y, z, x1, y1, z1)**— Границы блока, об этом поговорим позже.

#### Текстура блока

**testblock.blockIndexInTexture = ModLoader.addOverride(«/terrain.png», «/assets/myblock.png»);**— Здесь мы говорим ModLoader`у что требуется перезаписать текстуру «/terrain.png» файлом «/assets/myblock.png».**blockIndexInTexture**— индекс текстуры в файле «/terrain.png», у нас это*0*. «/assets/myblock.png» — это текстура 16x16, как в новой версии. Папка «/assets/» должна находиться внутри**minecraft.jar**, но вы можете изменить «/assets/» на любую папку которую захотите.

##### Регистрируем блок

**ModLoader.RegisterBlock(**— Регистрируем блок,*testblock*);— идентификатор блока который мы указали раннее.**testblock**

**ModLoader.AddName(**— Тут как обычно,*testblock*, «*TESTEFICATE*»);— идентификатор блока, а «**testblock***TESTEFICATE*» это имя блока отображаемое в игре.



#### Второй способ

Второй способ добалвениы блока не сильно отличается от первого, за исключением того что придётся заменить *new Block(…* на *new Block $$$(…*, где

**$$$**— любое нужное вам имя.

Заходим в **(MCP)/src/minecraft/net/minecraft/src/** и создаём в нём Block$$$.java

Я буду использовать вместо **$$$** — MyBLK. Создаю класс BlockMyBLK.java

Открываем и пишем:

```
package net.minecraft.src;
import java.util.Random;
public class BlockMyBLK extends Block
{
protected BlockMyBLK(int id, int texind, Material mat)
{
super(id, texind, mat);
blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/assets/test.png");
}
public int idDropped(int i, Random random)
{
return mod_testmod.myblk.blockID;
}
public int quantityDropped(Random random)
{
return 1;
}
}
```

Теперь разбираемся.

```
import java.util.Random;
```

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

```
extends Block
```

— мы наследуем класс Block, это нужно для правильной работы и так далее.

```
super(id, texind, mat);
```

— мы обращаемся в класс Block и отправляем ему ID блока, индекс текстуры и материал блока.

```
blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/assets/test.png");
```

— нам проще будет задавать текстуру для блока внутри класса, так как это в будущем пригодится для создания блока с разными текстурами.

```
public int idDropped(int i, Random random)
```

— что будет выпадать из блока. Если в **return** вставить **0**, то ничего не выпадет. В нашем случае из блока падает этот же самый блок.

Если вам нужно чтобы из блока падал предмет, например алмаз, тогда замените **mod_testmod.testblock.blockID** на **Item.diamond.shiftedIndex**.

```
public int quantityDropped(Random random)
```

— количество выпадаемого из блока.

##### Регистрируем блок

В начале класса как и раньше добавляем:

```
public static Block myblk;
```

В конструктор класса добавляем:

```
myblk = new BlockMyBLK(101, 0, Material.glass).setStepSound(Block.soundStoneFootstep).setBlockName("myblock").setHardness(0.5F).setResistance(2F);
ModLoader.RegisterBlock(myblk);
ModLoader.AddName(myblk, "CLASSBLOCK");
```

Заменяем **Block(100…** на **BlockMyBLK(101…**.

**100** на **101** мы заменили потому что для каждого блока нужен свой ID. Если вы не будете его изменять то у вас будут ошибки и вылеты. Также, я заменил материал с камня на стекло, для примера.

#### Создание своего материала для блока

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

Всего существует пять видов материала:

Название |
Назначение
|

Material | Материал для блока |

MaterialLiquid | Материал для жидкости |

MaterialLogic | Материал для блоков с особанными свойствами |

MaterialPortal | Материал для портала |

MaterialTransparent | Материал для блока с прозрачной текстурой |


И так, как же выглядит код для материала:

```
public static final Material [имя материала] = new [класс материала](MapColor.[цвет на карте])
```

**[имя материала]** — любое имя для нового маатериала, главное как обычно без кириллических символов и пробелов.

**[класс материала]** — нужный вам класс для материала, берите из исходников или из таблицы выше.

**[цвет на карте]** — цвет которым будет обозначен блок на карте.
Всего существует 14 вариантов цвета:

Код |
Цвет |
Особенности
|

airColor | Нет | Не отображается на карте |

grassColor | #7FB238 | Нет |

sandColor | #F7E9A3 | Нет |

clothColor | #A7A7A7 | Нет |

tntColor | #FF0000 | Нет |

iceColor | #A0A0FF | Нет |

ironColor | #A7A7A7 | Нет |

foliageColor | #007C00 | Нет |

snowColor | #FFFFFF | Нет |

clayColor | #A4A8B8 | Нет |

dirtColor | #B76A2F | Нет |

stoneColor | #707070 | Нет |

waterColor | #4040FF | Нет |

woodColor | #685332 | Нет |


Ещё, для материалов требуются свои флаги. Всего есть 5 флагов для материала. Они нужны для более тонкой настройки материала и установки свойств блоку из этого самого материала.

Флаг |
Функции
|

setIsTranslucent() | Делает текстуру блока прозрачной |

setNoHarvest() | Запрещает сбор блока некорректным инструментом |

setBurning() | Включает воспламеняемость у материала |

setIsGroundCover() | . Используется только в материале снежного ковра.
? |

setNoPushMobility() | Включает не полную проходимость через блок |

setImmovableMobility() | Включает полную проходимость через блок |


Для создания обычного материала можно не добавячть каких-либо флагов, а вот для создания материала жидкости код будет выглядеть так:

```
public static final Material [имя материала] = new MaterialLiquid(MapColor.[цвет на карте]).setNoPushMobility();
```

Для блока с прозрачной текстурой код выглядит так:

```
public static final Material [имя материала] = new Material(MapColor.[цвет на карте]).setIsTranslucent();
```

А для полностью прозрачного блока так:

```
public static final Material [имя материала] = new MaterialTransparent(MapColor.[цвет на карте]);
```

#### Создание своих звуков для блока

Допустим у нас есть блок для которого обычные звуки не подойдут, мы для решения этой проблемы в тело главного класса добавляем:

```
public static final StepSound [имя вашего звука] = new StepSound("[идетификатор]", [громкость]F, [тон звука]F);
```

**[имя вашего звука]** — текст в ковычках сам про себя говорит, это самое имя мы будем ичпользовать в аргументе **.setStepSound()** для блоков.
**«[идентификатор]»** — имя вашего звука в папке **(Папка Minecraft)/resources/sound/step/**.
**[громкость]F** — громкость ваших звуков. (Пример: *1.0F*)
**[тон звука]F** — высота звука, заполняется также как и громкость.

Нужные звуки нужно назвать также как и *идентификатор*, но в конце почле названия добавить число, от 1. Например, идентификатор звука **copper**, тогда в папке **(Папка Minecraft)/resources/step/** будут лежать звуки **copper1.ogg**, **copper2.ogg** и т. д.



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

Тут как и с блоком существует **два** способа. С классом и без.

#### Первый способ

В тело главного класса добавляем:

```
public static Item myitem;
```

##### Регистрируем предмет

В конструктор:

```
myitem = new Item(1000).setItemName("myitem").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/myitem.png"));
ModLoader.AddName(myitem, "My Super Item");
```

**new Item(1000)…** — Создаём предмет, **1000** это ID предмета, в Minecraft Beta 1.7.3 доступно всего 32000 ID для предметов. Я выберу 1000.

**.setItemName(«myitem»)…** — Имя предмета, опять же используется для получения строчки из файла локализации, у нас будет перезаписано.

**.setIconIndex( …);** — Устанавливаем иконку для предмета. В

*…*у нас будет:

**ModLoader.addOverride(«/gui/items.png», «/assets/myitem.png»)**— Здесь мы перезаписываем «/gui/items.png» файлом с текстурой предмета, а именно: «/assets/myitem.png».

**ModLoader.AddName(myitem, «My Super Item»)** — **myitem** — идентификатор нашего предмета, а **«My Super Item»** — имя отображаемое в игре. В общем, всё также как и при создании блока.

#### Второй способ

Создаём в **(MCP)/src/minecraft/net/minecraft/src/** класс нашего предмета. Item$$$.java, где **$$$** — любое имя, я буду использовать SuperItem.

Открываем наш файл и пишем:

```
package net.minecraft.src;
public class ItemSuperItem extends Item
{
protected ItemSuperItem(int id)
{
super(id);
setMaxStackSize(8);
}
}
```

Разбираемся…
```
extends Item
```

— наследуем класс Item.
```
super(id);
```

— с помощью этого будем обращаться к классу Item, отсылая ему ID предмета.
```
setMaxStackSize(8);
```

— максимальное количество предметов в 1 слоту. Я поставил 8, для примера.
Также существуют и такие флаги:

**setMaxDamage(I);**— устанавливаем прочность для предмета.**I**— прочность.**setHasSubtypes(BOOL);**— имеет ли предмет подтипы (*когда берётся его ID и добавляется 1, 2 и так далее*). Требует добавления другого конструктора.**BOOL**—*true*или*false*.**setFull3D();**— устанавливает тип отрисовки предмета. К «полностью 3D» предметам относятся: Инструменты (и Мотыга), Мечи и Удочка.

##### Регистрируем предмет

В тело главного класса вписываем, как обычно:

```
public static Item superitem;
```

В конструктор вписываем тоже самое что и в первом способе, только заменим идентификатор на **superitem**, **Item** на **ItemSuperItem** и ID с **1000** увеличим до **1001**.

```
superitem = new ItemSuperItem(1001).setItemName("superitem").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/superitem.png"));
ModLoader.AddName(superitem, "My Super Item Ever");
```

#### Создание еды

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

В тело главного класса:

```
public static Item sweetBerries;
```

##### Регистрируем еду

В конструктор главного класса:

```
sweetBerries = new ItemFood(1020, 2, false).setItemName("sweetBerries").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/food_sweetBerries.png"));
ModLoader.AddName(sweetBerries, "Sweet Berries");
```

Самое интересное, в чём же тут различия.

**new ItemFood(1020, 2, false)…**

**1020** уже как должно быть ясно — ID предмета.

**2** — количество жизей которое восстанавливает еда.

**false** — аргумент, отвечающий за пригодность этой еды для Собак. В нашем случае тут: **false** — это означает что собакам этот вид еды не нравится. Если значение будет **true**, тогда собаки будут есть эту еду за милую душу.

**ПРИМЕЧАНИЕ**

Если вы захотите сделать еду складываемой, то добавьте **.setMaxStackSize(I)** после **.setIconIndex**, где **I** — там число. Но будьте осторожны! Складываемая еда в старых версиях * не имеет* задержки при упортеблении. Это даёт преимущество игроку с которым вы будете драться, а также, например, позволяет выплыть из лавы, если вы будете постоянно употреблять эту еду.

#### Создание пластинки

Различий также никаких нет, вместо **Item** пишем **ItemRecord**, меняем ID и так далее.

В тело главного класса пишем это:

```
public static Item record@@@;
```

**@@@** меняем на имя вашей пластинки.

##### Регистрируем пластинку

В конструктор главного класса:

```
record@@@ = new ItemRecord(2100, "%%%").setItemName("record").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/record_%%%.png"));
```

**new ItemRecord(2100, «%%%»)…**

**2100** — ID,

**«%%%»** — имя трека на пластинке. OGG файл с музыкой должен находится в **(Папка Minecraft)/resources/streaming/%%%.ogg**.

**.setItemName(«record»)…** — Мы устанавливаем пластинке имя **record**, в файле локализации **record** (*item.record.name*) установлен как *Music Disc*. Вы также можете добавить своё имя для пластинки. Для этого после установки значения для **record@@@** впишите:

ModLoader.AddName(record@@@, "Music Disc - Songs");

Вместо **Songs** подставьте своё значение.

**ПРИМЕЧАНИЕ**

Все пластинки будут подписаны от имени **C418**.

#### Создание брони

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

В тело главного класса добавляем:

```
public static Item steelHelmet;
public static Item steelChestplate;
public static Item steelLeggings;
public static Item steelBoots;
```

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

##### Регистрация брони

В папку **«/armor/»** внутри **minecraft.jar** кладём 2 текстуры, **[Тип брони]_1.png** и **[Тип брони]_2.png**.
В файле **_1** находятся текстуры Нагрудника и Шлема, а в файле **_2** текстуры Понож и Ботинок.

В конструктор главного класса вписываем:

```
steelHelmet = new ItemArmor(3000, 0, ModLoader.AddArmor("steel"), 0).setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/steel_helmet.png")).setItemName("steelHelmet");
steelChestplate = new ItemArmor(3001, 0, ModLoader.AddArmor("steel"), 1).setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/steel_chestplate.png")).setItemName("steelChestplate");
steelLeggings = new ItemArmor(3002, 0, ModLoader.AddArmor("steel"), 2).setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/steel_leggings.png")).setItemName("steelLeggings");
steelBoots = new ItemArmor(3003, 0, ModLoader.AddArmor("steel"), 3).setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/steel_boots.png")).setItemName("steelBoots");
ModLoader.AddName(steelHelmet, "Steel Helmet");
ModLoader.AddName(steelChestplate, "Steel Chestplate");
ModLoader.AddName(steelLeggings, "Steel Leggings");
ModLoader.AddName(steelBoots, "Steel Boots");
```

**new ItemArmor(300#, 0, 0, %)**

**300(0-3)** — ID

**0** — Уровень брони, чем выше тем прочнее броня.

**ModLoader.AddArmor(«steel»)** — Это идентификатор нашей брони. Он используется потому что нам нужно регистрировать новые текстуры для брони. ModLoader присваивает числовое значение к тому что вы ввели в скобках. В Minecraft уже есть массив с текстурами брони, если мы будем использовать его то нам придётся заменять оригинальные текстуры, а это не интересно.

**%** — Тип предмета.

**0** — Шлем.

**1** — Нагрудник.

**2** — Поножи.

**3** — Ботинки.

Прочность брони вычисляется по формуле **[Тип брони] * 3 << [Уровень брони]**. **<<** — оператор битового сдвига влево.

Предмет |
Прочность (По типу брони)
|

Шлем | 11 |

Нагрудник | 16 |

Поножи | 15 |

Ботинки | 13 |


Вот таблица значений в Minecraft Beta 1.7.3:

Тип |
ID (В коде) |
ID (В игре) |
Уровень брони |
Идентификатор |
Тип предмета
|

Кожаный шлем | 42 | 298 | 0 | 0 | 0 |

Кожаный нагрудник | 43 | 299 | 0 | 0 | 1 |

Кожаные поножи | 44 | 300 | 0 | 0 | 2 |

Кожаные ботинки | 45 | 301 | 0 | 0 | 3 |

Кольчужный шлем | 46 | 302 | 1 | 1 | 0 |

Кольчужный нагрудник | 47 | 303 | 1 | 1 | 1 |

Кольчужные поножи | 48 | 304 | 1 | 1 | 2 |

Кольчужные ботинки | 49 | 305 | 1 | 1 | 3 |

Железный шлем | 50 | 306 | 2 | 2 | 0 |

Железный нагрудник | 51 | 307 | 2 | 2 | 1 |

Железные поножи | 52 | 308 | 2 | 2 | 2 |

Железные ботинки | 53 | 309 | 2 | 2 | 3 |

Алмазный шлем | 54 | 310 | 3 | 3 | 0 |

Алмазный нагрудник | 55 | 311 | 3 | 3 | 1 |

Алмазные поножи | 56 | 312 | 3 | 3 | 2 |

Алмазные ботинки | 57 | 313 | 3 | 3 | 3 |

Золотой шлем | 58 | 314 | 1 | 4 | 0 |

Золотой нагрудник | 59 | 315 | 1 | 4 | 1 |

Золотые поножи | 60 | 316 | 1 | 4 | 2 |

Золотые ботинки | 61 | 317 | 1 | 4 | 3 |


**ПРИМЕЧАНИЕ**

В Minecraft железная броня называется «[Элемент брони]steel».

#### Создание инструментов и оружия

Для всех инструментов существует таблица материалов:

Материал |
Уровень добычи |
Прочность (Все предметы) |
Эффективность на правильном материале |
Урон по сущности
|

WOOD | 0 | 59 | 2.0F | 0 |

STONE | 1 | 131 | 4.0F | 1 |

IRON | 2 | 250 | 5.0F | 2 |

EMERALD | 3 | 1561 | 8.0F | 3 |

GOLD | 0 | 32 | 12.0F | 0 |


**EMERALD** — Материал алмазных инструментов

##### Создание меча

В тело гл. класса как обычно добавляем:

```
public static Item obsidianSword;
```

Я буду добавлять обсидиановые инструменты. Замените obsidian на любое другое название, если хотите конечно.

```
obsidianSword = new ItemSword(3800, EnumToolMaterial.EMERALD).setItemName("obsidianSword").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/obsidian_sword.png"));
ModLoader.AddName(obsidianSword, "Obsidian Sword");
```

**new ItemSword(3800, EnumToolMaterial.EMERALD)…**

**3800**— ID.**EnumToolMaterial.EMERALD**— Материал меча, в моём случае это, так как материала лучше пока что нет.**EMERALD**

##### Создание инструментов (Кирка, Топор, Лопата, Мотыги)

Тело:

```
public static Item obsidianPickaxe;
public static Item obsidianAxe;
public static Item obsidianSpade;
public static Item obsidianHoe;
```

Конструктор:

```
obsidianPickaxe = new ItemPickaxe(3801, EnumToolMaterial.EMERALD).setItemName("obsidianPickaxe").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/obsidian_pickaxe.png")); // Кирка
obsidianPickaxe = new ItemPickaxe(3802, EnumToolMaterial.EMERALD).setItemName("obsidianPickaxe").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/obsidian_axe.png")); // Топор
obsidianPickaxe = new ItemPickaxe(3803, EnumToolMaterial.EMERALD).setItemName("obsidianPickaxe").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/obsidian_spade.png")); // Лопата
obsidianPickaxe = new ItemPickaxe(3804, EnumToolMaterial.EMERALD).setItemName("obsidianPickaxe").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/obsidian_hoe.png")); // Мотыга
ModLoader.AddName(obsidianPickaxe, "Obsidian Pickaxe");
ModLoader.AddName(obsidianAxe, "Obsidian Axe");
ModLoader.AddName(obsidianSpade, "Obsidian Shovel");
ModLoader.AddName(obsidianHoe, "Obsidian Hoe");
```

##### Создание ножниц и ведра

При создании ножниц или удочки нельзя указать ничего интересного, поэтому сделаем сурер-ножницы из дерева с 3000 прочности.

###### Ножницы

Тело гл. класса:

```
public static Item woodenShears;
```

Конструктор гл. класса:

```
woodenShears = (ItemShears)(new ItemShears()).setItemName("woodenShears").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/woodenshears.png")).setMaxDamage(2999);
ModLoader.AddName(woodenShears, "Wooden Shears");
```

Значение **.setMaxDamage** установлено на 2999 потому что в старых версиях предмет с прочностью *0* считался исправным, так что по логике 0+2999=3000.

###### Ведро

Тело:

```
public static Item bucketDirt;
```

Конструктор:

```
bucketDirt = new ItemBucket(3555, Block.dirt.blockID).setItemName("bucketDirt").setIconIndex(ModLoader.addOverride("/gui/items.png", "/assets/bucketdirt.png")).setContainerItem(Item.bucketEmpty);
ModLoader.AddName(bucketDirt, "Dirt Bucket");
```

**new ItemBucket(3555, Block.dirt.blockID)…**

**3555** — ID.

**Block.dirt.blockID** — ID блока который содержется в этом ведре. Можно зменить на любой блок из игры, или соданный в моде.

**.setContainerItem(Item.bucketEmpty)**— Предмет на который будет заменено ведро при «выливании». Если вы создали до этого пустое ведро, то замените**Item.bucketEmpty**на**mod_[имя вашего мода].[идентификатор предмета-ведра]**.



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

Существует возможность создать всего 3 вида рецептов, а именно: **Обычный крафт**, **Бесформенный крафт** и **Выплавка**.

#### Создание обычного крафта

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

Теперь, как это будет выглядеть в коде:

```
ModLoader.AddRecipe(new ItemStack(Block.stone, 1), new Object[] { "I ", " S ", " I", 'I', Block.blockSteel, 'S', Item.stick });
```

**new ItemStack(Block.stone, 1)** — результат получившегося.

**Block.stone** — результат крафта.

**1** — количество получившегося.

**new Object[] {…}** — массив создания.
Массив создания представляет собой сетку крафта, разложеную на символы в скобках.

```
"I "
" S "
" I"
```

Ингредиенты | Рецепты крафта |
---|---|

Железный блок + Палка |


Также рецепт можно создать в сетке 2x2. Для этого достаточно сократить количество символов и убрать 1 пару скковычек.

```
"I "
" S"
```

Ингредиенты | Рецепты крафта |
---|---|

Палка + Железный блок |


'**I', Block.blockSteel** — обозначение первого символа крафта. В моём случае * I* — это железный блок.

'**S', Item.stick** — также как и в первом случае это обозначение символа. Тут у нас * S* — палка.

Никто также не запрещает использовать свои предметы и блоки, требуется вместо условного **Block.blockSteel** или **Item.stick** подставить идентификатор своего предмета/блока.

#### Создание бесформенного крафта

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

```
ModLoader.AddShapelessRecipe(new ItemStack(Block.bedrock, 4), new Object[] { Item.diamond, 1, Block.obsidian, 1, Block.stone, 1 });
```

Ингредиенты | Рецепты крафта |
---|---|

Алмаз + Камень + Обсидиан |


```
Item.diamond, 1,
Block.obsidian, 1,
Block.stone, 1
```

Здесь мы через `,`

указываем ингредиенты и их количество.

##### Использование красителей в рецепте

Для использование красителей в рецепте нам нужно в массив рецепта вместо ID нашего предмета вставить специальный конструктор:

```
new ItemStack(Item.dyePowder, 1, %)
```

Где **%** там число от 0 до 15. Это число — метадата предмета. Все цвета можно найти в этой таблице:

ID |
Цвет
|

0 | Чёрный |

1 | Красный |

2 | Зелёный |

3 | Коричневый |

4 | Синий |

5 | Фиолетовый |

6 | Циановый |

7 | Светло-серый |

8 | Серый |

9 | Розовый |

10 | Лаймовый |

11 | Жёлтый |

12 | Голубой |

13 | Пурпурный |

14 | Оранжевый |

15 | Белый |


Если вы хотите использовать шерсть вместо красителя тогда таблица цвета будет перевёрнутой, тоесть 0-белый, 1-оранжевый и т. д.

#### Создание рецепта выплавки

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

```
ModLoader.addSmelting(Block.dirt.blockID, new ItemStack(Block.blockGold, 3));
```

Ингредиенты | Процесс |
---|---|

Земля |


Ну а вот и главные отличия, нам не нужно создавать Object массив для создания самого рецепта.

**Block.dirt.blockID** — ID блока который будет использован для получения результата. Если в вашем рецепте используется предмет, а не блок, то нужно заменить **.blockID** на **.shiftedIndex**.

**new ItemStack(Block.blockGold, 3)** — конструктор продукта рецепта. **Block.blockGold** — идентификатор блока который будет получен в результате, а **3** — количество этого самого результата.