- Версия(и) Minecraft
- 1.11-1.12
В этом туториале мы научимся создавать и генерировать руды во всевозможных мирах и всевозможными способами.
Создадим в пакете domain.autor.modid.world.generate класс GenerateOre со следующим содержимым:
Блок руды
Для создания руды будет удобнее наследовать его класс не от обычного блока, а от блока руды. Зачем? Ну во первых не нужно будет указывать материал (по умолчанию камень, а также доступны некоторые дополнительные фишки. Таким образом выглядит класс блока руды:
Код:
public class BlockTestOre extends BlockOre {
public BlockTestOre() {
this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS); //Вкладка в креативе
this.setHardness(2.0F); //Прочность блока, сейчас как у ванильных руд
this.setHarvestLevel("pickaxe", 1); //Инструмент и его уровень (0 - дерево, 3 - алмазы)
this.setLightLevel(7.0F); //Светимость (если нужно)
this.setRegistryName("life_ore"); //Регистрируемое имя
this.setResistance(17.0F); //Взрывоустойчивость блока, сейчас как у ванильных руд
this.setUnlocalizedName("tutorial.test_ore"); //Ключ локализации
}
//Следующий метод для корректной работы света
@Override
public boolean isFullCube(IBlockState state) { //Будет ли блок полным
return true; //Да
}
//Далее пойдут фишки, которые не обязательны
public Item getItemDropped(IBlockState state, Random rand, int fortune) { //получение текущего дропа с блока
return this == BlocksInit.TEST_ORE ? ItemsInit.TEST_ITEM : Item.getItemFromBlock(this); //Возвращаем предмет, который будет дропатся
}
public int quantityDroppedWithBonus(int fortune, Random random) { //Зависимость дропа в зависимости от чар "Фортуна" на инструменте
if (fortune > 0 && Item.getItemFromBlock(this) != this.getItemDropped((IBlockState)this.getBlockState().getValidStates().iterator().next(), random, fortune)) { //Выполнить метод, если уровень чар от 1-го уровня на нашем блоке
int i = random.nextInt(fortune + 2) - 1; //2 - максимальна прибавка к дропу (минимум 1, максимум 3 предмета с блока)
if (i < 0) {
i = 0;
}
return this.quantityDropped(random) * (i + 1);
}
else {
return this.quantityDropped(random); //Возвращаем рандомное количество дропа
}
}
@Override
public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { //Дроп опыта при добыче блока (если нужно)
Random rand = world instanceof World ? ((World)world).rand : new Random();
if (this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this)) {
int i = 0;
if (this == BlocksInit.TEST_ORE) {
i = MathHelper.getInt(rand, 0, 2); //Количество опыта (от 0 до 2)
}
return i;
}
return 0;
}
}
Генератор
Чтобы генерировать руду надо естественно сам генератор.Создадим в пакете domain.autor.modid.world.generate класс GenerateOre со следующим содержимым:
Код:
public class GenerateOre implements IWorldGenerator {
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
switch(world.provider.getDimension()) { //Получение ID измерения
case -1: //Нэзер
break;
case 0: //Обычний мир
runGenerator(BlocksInit.TEST_ORE.getDefaultState(), 1, 8, 0, 16, BlockMatcher.forBlock(Blocks.STONE), world, random, chunkX, chunkZ); //Вызов генератора с заданными параметрами
break;
case 1: //Край
break;
case x: //Мир из другого мода (х заменить на нужный ID измерения)
break;
/*
BlocksInit.TEST_ORE.getDefaultState() - генерируемый блок
1 - максимальное количество блоков в месторождении, можно задать вариацию записью 1 + random.nextInt(4) для генерации от 1-го до 5-ти блоков в месторождении
8 - количество месторождений на чанк
0 - минимальная высота генерации
16 - максимальная высота генерации
BlockMatcher.forBlock(Blocks.STONE) - блок, который можно заменить на руду
*/
}
}
private void runGenerator(IBlockState blockToGen, int blockAmount, int chancesToSpawn, int minHeight, int maxHeight, Predicate<IBlockState> blockToReplace, World world, Random rand, int chunk_X, int chunk_Z){ //Объявление генератора
if (minHeight < 0 || maxHeight > 256 || minHeight > maxHeight) //Проверка на правильность координаты Y
throw new IllegalArgumentException("Illegal Height Arguments for WorldGenerator"); //Если неправильно то будет ошибка в консоли
WorldGenMinable generator = new WorldGenMinable(blockToGen, blockAmount, blockToReplace); //Новый экземпляр генератора
int heightdiff = maxHeight - minHeight + 1;
for (int i = 0; i < chancesToSpawn; i++){ //Запуск генератора в каждом чанке с заданным параметрами
int x = chunk_X * 16 +rand.nextInt(16);
int y = minHeight + rand.nextInt(heightdiff);
int z = chunk_Z * 16 + rand.nextInt(16);
generator.generate(world, rand, new BlockPos(x, y, z));
}
}
}
Регистрация
Как и блок. генератор нужно зарегистрировать в игре, для чего в CommonProxy в методе init добавим данную строчку:
Код:
GameRegistry.registerWorldGenerator(new GenerateOres(), 0); //Класс генератора и его ID (для каждого генератора нужен уникальный ID)