- Версия(и) Minecraft
- 1.6.x and 1.7.x
Учебное пособие - Как создать простую многоблочную структуру
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Minecraft Версия: Протестировано в 1.6.x и 1.7.x (используйте
Многоблочные структуры - хороший способ сделать улучшенные блоки без добавления множества рецептов, которые могут сделать рецепт создания этого блока дороже. Итак, как же создать собственную Многоблочную структуру? В этом учебном пособии вы узнаете, как создать базовую Многоблочную структуру 3x3x3 с полым центром с использованием системы "Master-Slave".
Это учебное пособие предполагает, что у вас есть базовые знания о том, как создать базовый мод, создать TileEntities и работать с данными NBT. Если вы этого не знаете, я рекомендую читать/смотреть учебные пособия Wuppy, они являются отличным источником информации, а также учебниками, которые я использовал, когда я впервые начал заниматься моддингом.
Обратите внимание, что существует несколько способов создания многоблочных структур, и этот метод может быть не лучшим. Также обратите внимание, что способ, которым мы будем создавать многоблочную структуру, сделает его похожим на те, что есть в RailCraft, в котором все данные хранятся в нижнем центральном блоке структуры, поэтому имейте это в виду, если вы не хотите, чтобы ваша структура работала так.
Шаг 1: Создайте базовый TileEntity
Для того, чтобы начать работу, нам будет нужен в основной TileEntity, который я буду называть
Нам также понадобятся несколько переменных, два логических типа данных для tile, чтобы увидеть, есть ли у него master и/или если он является хозяином структуры и тремя целыми числами для координат master для ведомых устройств. Обязательно добавьте геттеры и сеттеры для каждого из них и сохраните их в Tile’s NBT данных.
Шаг 2: Проверьте и сформируйте Многоблочную структуру
Следующим шагом является создание способа проверки правильности сформирования структуры. Самый простой способ - сделать три цикла
Нам также нужен способ рассказать всем тем tiles, что у них теперь есть master и где он находится. Вам также нужно будет сообщить нижнему центральному блоку, что это master. Этот метод будет использовать master только после того, как он обнаружит, что структура сформирована.
Шаг 3: Сброс блоков
Теперь нам нужны методы настройки, чтобы проверить, не является ли структура недействительной, и сбросить все части. Главный блок может повторно использовать метод
Нам также нужен метод, который master должен использовать, если
Шаг 4: Собираем все вместе
Теперь, когда у нас есть все части, которые нам нужны, все, что осталось, это его запустить. Нам в основном нужно, чтобы каждый блок постоянно проверял, сформирована ли структура до тех пор, пока она не будет сформирована. Как только это случиться, мы хотим, чтобы он проверял, когда происходит смена блока, в котором master проверяет, сформирована ли структура, и блоки структуры проверяют, существует ли master.
Во-первых, убедитесь, что наши tile проверяют структуру, и убедитесь, что работает только основной блок. Все это будет помещено в метод
Теперь нужно запросить у главного блока структуры проверку, что структура всё ещё собрана, или у компонентов многоблока, что главный блок структуры всё ещё на месте, что мы делаем в классе блока в методе
Окончательный код
И вот я подошёл к концу. Не слишком сложно, когда вы смотрите на него. Опять же, возможно, это не лучший способ сделать многоблочную структуру, но он работает. Помните, что master должен быть единственным, кто выполняет работу и сохраняет данные NBT, поэтому помните, что когда вы пишете свой код (я добавил комментарии для мест, где он должен быть помещен для элемента основного tile entity). Если я что-нибудь упустил или если вы не понимаете, оставьте комментарий или свяжитесь со мной.
Поскольку у некоторых людей возникли проблемы с пониманием этого без примера, я сделал примерный мод, основанный на этом учебнике. Вы можете посмотреть на него здесь: Lomeli12/MultiBlock-Tutorial
Minecraft Версия: Протестировано в 1.6.x и 1.7.x (используйте
getTileEntity
вместо getBlockTileEntity
в 1.7.x)Многоблочные структуры - хороший способ сделать улучшенные блоки без добавления множества рецептов, которые могут сделать рецепт создания этого блока дороже. Итак, как же создать собственную Многоблочную структуру? В этом учебном пособии вы узнаете, как создать базовую Многоблочную структуру 3x3x3 с полым центром с использованием системы "Master-Slave".
Это учебное пособие предполагает, что у вас есть базовые знания о том, как создать базовый мод, создать TileEntities и работать с данными NBT. Если вы этого не знаете, я рекомендую читать/смотреть учебные пособия Wuppy, они являются отличным источником информации, а также учебниками, которые я использовал, когда я впервые начал заниматься моддингом.
Обратите внимание, что существует несколько способов создания многоблочных структур, и этот метод может быть не лучшим. Также обратите внимание, что способ, которым мы будем создавать многоблочную структуру, сделает его похожим на те, что есть в RailCraft, в котором все данные хранятся в нижнем центральном блоке структуры, поэтому имейте это в виду, если вы не хотите, чтобы ваша структура работала так.
Шаг 1: Создайте базовый TileEntity
Для того, чтобы начать работу, нам будет нужен в основной TileEntity, который я буду называть
TileMultiBlock
для этого учебного пособия. Я не буду рассказывать, для чего каждый метод, но просто обратите внимание, что это будет нашей отправной точкой.Нам также понадобятся несколько переменных, два логических типа данных для tile, чтобы увидеть, есть ли у него master и/или если он является хозяином структуры и тремя целыми числами для координат master для ведомых устройств. Обязательно добавьте геттеры и сеттеры для каждого из них и сохраните их в Tile’s NBT данных.
Java:
package net.lomeli.tutorial;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
public class TileMultiBlock extends TileEntity {
private boolean hasMaster, isMaster;
private int masterX, masterY, masterZ;
@Override
public void updateEntity() {
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
data.setInteger("masterX", masterX);
data.setInteger("masterY", masterY);
data.setInteger("masterZ", masterZ);
data.setBoolean("hasMaster", hasMaster);
data.setBoolean("isMaster", isMaster);
if (hasMaster() && isMaster()) {
// Любые другие значения должны СОХРАНЯТЬСЯ ТОЛЬКО ДЛЯ МАСТЕРА
}
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
masterX = data.getInteger("masterX");
masterY = data.getInteger("masterY");
masterZ = data.getInteger("masterZ");
hasMaster = data.getBoolean("hasMaster");
isMaster = data.getBoolean("isMaster");
if (hasMaster() && isMaster()) {
// Любые другие значения должны быть ПРОЧИТАНЫ ТОЛЬКО МАСТЕРОМ
}
}
public boolean hasMaster() {
return hasMaster;
}
public boolean isMaster() {
return isMaster;
}
public int getMasterX() {
return masterX;
}
public int getMasterY() {
return masterY;
}
public int getMasterZ() {
return masterZ;
}
public void setHasMaster(boolean bool) {
hasMaster = bool;
}
public void setIsMaster(boolean bool) {
isMaster = bool;
}
public void setMasterCoords(int x, int y, int z) {
masterX = x;
masterY = y;
masterZ = z;
}
}
Шаг 2: Проверьте и сформируйте Многоблочную структуру
Следующим шагом является создание способа проверки правильности сформирования структуры. Самый простой способ - сделать три цикла
for
(для координат x, y и z) и проверить, есть ли TileEntity в каждой координате и считать ее, если это экземпляр TileMultiBlock
. Затем подсчитываем их, чтобы увидеть, присутствует ли подходящее количество TileEntities и проверяем, свободен ли центр.
Java:
public boolean checkMultiBlockForm() {
int i = 0;
// Сканировать область 3x3x3, начиная с нижнего левого угла
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
// Удостоверьтесь, что tile не является нулевым, и является экземпляром одного и того же Tile и еще не является частью многоблочной структуры
if (tile != null && (tile instanceof TileMultiBlock)) {
if (this.isMaster()) {
if (((TileMultiBlock)tile).hasMaster())
i++;
} else if (!((TileMultiBlock)tile).hasMaster())
i++;
}
}
// Проверяем наличие 26 блоков ((3 * 3 * 3) - 1) и проверяем, что центральный блок пуст
return i > 25 && worldObj.isAirBlock(xCoord, yCoord + 1, zCoord);
}
Java:
public void setupStructure() {
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
// Проверка: является ли блок, нижним центральным блоком
boolean master = (x == xCoord && y == yCoord && z == zCoord);
if (tile != null && (tile instanceof TileMultiBlock)) {
((TileMultiBlock) tile).setMasterCoords(xCoord, yCoord, zCoord);
((TileMultiBlock) tile).setHasMaster(true);
((TileMultiBlock) tile).setIsMaster(master);
}
}
}
Шаг 3: Сброс блоков
Теперь нам нужны методы настройки, чтобы проверить, не является ли структура недействительной, и сбросить все части. Главный блок может повторно использовать метод
checkMultiBlockForm
для проверки структуры, но блоки из которой состоит структура также должны постоянно проверяться, что master все еще существует, если master сначала сломался, и для их сброса, если он больше не существует.
Java:
// Метод сброса, который должен запускаться, когда master ушел, или сообщает им
public void reset() {
masterX = 0;
masterY = 0;
masterZ = 0;
hasMaster = false;
isMaster = false;
}
public boolean checkForMaster() {
TileEntity tile = worldObj.getBlockTileEntity(masterX, masterY, masterZ);
return (tile != null && (tile instanceof TileMultiBlock));
}
checkMultiBlockForm
возвращает false
. Так как у нас уже есть метод сброса, мы можем просто сделать клон setupStructure
, который сбрасывает вещи вместо этого.
Java:
public void resetStructure() {
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
if (tile != null && (tile instanceof TileMultiBlock))
((TileMultiBlock) tile).reset();
}
}
Шаг 4: Собираем все вместе
Теперь, когда у нас есть все части, которые нам нужны, все, что осталось, это его запустить. Нам в основном нужно, чтобы каждый блок постоянно проверял, сформирована ли структура до тех пор, пока она не будет сформирована. Как только это случиться, мы хотим, чтобы он проверял, когда происходит смена блока, в котором master проверяет, сформирована ли структура, и блоки структуры проверяют, существует ли master.
Во-первых, убедитесь, что наши tile проверяют структуру, и убедитесь, что работает только основной блок. Все это будет помещено в метод
updateEntity
.
Java:
@Override
public void updateEntity() {
super.updateEntity();
if (!worldObj.isRemote) {
if (hasMaster()) {
if (isMaster()) {
// Вставьте вещи, которые вы хотите, чтобы мультиблок выполнил здесь!
}
} else {
// Постоянно проверяйте, сформирована ли структура до ее появления.
if (checkMultiBlockForm())
setupStructure();
}
}
}
onNeighborBlockChange
.
Java:
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
TileEntity tile = world.getTileEntity(x, y, z);
if (tile != null && tile instanceof TileMultiBlock) {
TileMultiBlock multiBlock = (TileMultiBlock) tile;
if (multiBlock.hasMaster()) {
if (multiBlock.isMaster()) {
if (!multiBlock.checkMultiBlockForm())
multiBlock.resetStructure();
} else {
if (!multiBlock.checkForMaster())
multiBlock.reset();
}
}
}
super.onNeighborBlockChange(world, x, y, z, block);
}
Окончательный код
Java:
package net.lomeli.tutorial;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
public class TileMultiBlock extends TileEntity {
private boolean hasMaster, isMaster;
private int masterX, masterY, masterZ;
@Override
public void updateEntity() {
super.updateEntity();
if (!worldObj.isRemote) {
if (hasMaster()) {
if (isMaster()) {
// Вставьте вещи, которые вы хотите, чтобы мультиблок выполнил здесь!
}
} else {
// Постоянно проверяйте, сформирована ли структура до ее появления.
if (checkMultiBlockForm())
setupStructure();
}
}
}
/** Убедитесь, что структура правильно сформирована*/
public boolean checkMultiBlockForm() {
int i = 0;
// Сканировать область 3x3x3, начиная с нижнего левого угла
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
// Удостоверьтесь, что tile не является нулевым, и является экземпляром одного и того же Tile и еще не является частью многоблочной структуры
if (tile != null && (tile instanceof TileMultiBlock)) {
if (this.isMaster()) {
if (((TileMultiBlock)tile).hasMaster())
i++;
} else if (!((TileMultiBlock)tile).hasMaster())
i++;
}
}
// Проверить наличие 26 блоков ((3 * 3 * 3) - 1) и убедитесь, что центральный блок пуст
return i > 25 && worldObj.isAirBlock(xCoord, yCoord + 1, zCoord);
}
/** Настройка всех блоков в структуре*/
public void setupStructure() {
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
// Проверять: является ли блок, нижним центральным блоком
boolean master = (x == xCoord && y == yCoord && z == zCoord);
if (tile != null && (tile instanceof TileMultiBlock)) {
((TileMultiBlock) tile).setMasterCoords(xCoord, yCoord, zCoord);
((TileMultiBlock) tile).setHasMaster(true);
((TileMultiBlock) tile).setIsMaster(master);
}
}
}
/** Сбросить метод, который будет запускаться, когда master ушел или сообщает им */
public void reset() {
masterX = 0;
masterY = 0;
masterZ = 0;
hasMaster = false;
isMaster = false;
}
/** Убедитесь, что master существует */
public boolean checkForMaster() {
TileEntity tile = worldObj.getBlockTileEntity(masterX, masterY, masterZ);
return (tile != null && (tile instanceof TileMultiBlock));
}
/** Сбросить все части структуры */
public void resetStructure() {
for (int x = xCoord - 1; x < xCoord + 2; x++)
for (int y = yCoord; y < yCoord + 3; y++)
for (int z = zCoord - 1; z < zCoord + 2; z++) {
TileEntity tile = worldObj.getBlockTileEntity(x, y, z);
if (tile != null && (tile instanceof TileMultiBlock))
((TileMultiBlock) tile).reset();
}
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
data.setInteger("masterX", masterX);
data.setInteger("masterY", masterY);
data.setInteger("masterZ", masterZ);
data.setBoolean("hasMaster", hasMaster);
data.setBoolean("isMaster", isMaster);
if (hasMaster() && isMaster()) {
// Любые другие значения должны СОХРАНЯТЬСЯ ТОЛЬКО ДЛЯ МАСТЕРА
}
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
masterX = data.getInteger("masterX");
masterY = data.getInteger("masterY");
masterZ = data.getInteger("masterZ");
hasMaster = data.getBoolean("hasMaster");
isMaster = data.getBoolean("isMaster");
if (hasMaster() && isMaster()) {
// Любые другие значения должны быть ПРОЧИТАНЫ ТОЛЬКО МАСТЕРОМ
}
}
public boolean hasMaster() {
return hasMaster;
}
public boolean isMaster() {
return isMaster;
}
public int getMasterX() {
return masterX;
}
public int getMasterY() {
return masterY;
}
public int getMasterZ() {
return masterZ;
}
public void setHasMaster(boolean bool) {
hasMaster = bool;
}
public void setIsMaster(boolean bool) {
isMaster = bool;
}
public void setMasterCoords(int x, int y, int z) {
masterX = x;
masterY = y;
masterZ = z;
}
}
Java:
package net.lomeli.tutorial;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class BlockMultiBlock extends BlockContainer {
public BlockMultiBlock(Material material) {
super(material);
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile != null && tile instanceof TileMultiBlock) {
TileMultiBlock multiBlock = (TileMultiBlock) tile;
if (multiBlock.hasMaster()) {
if (multiBlock.isMaster()) {
if (!multiBlock.checkMultiBlockForm())
multiBlock.resetStructure();
} else {
if (!multiBlock.checkForMaster()) {
multiBlock.reset();
world.markBlockForUpdate(x, y, z);
}
}
}
}
super.onNeighborBlockChange(world, x, y, z, block);
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return TileMultiBlock();
}
}
Поскольку у некоторых людей возникли проблемы с пониманием этого без примера, я сделал примерный мод, основанный на этом учебнике. Вы можете посмотреть на него здесь: Lomeli12/MultiBlock-Tutorial