Привет всем! Мы добавили блок, но интереснее было бы увидеть его в деле. Так что сегодня мы добавим своего рода хук для отслеживания события генерации мира. В нём и пропишем генерацию своего блока. Эти знания нам ещё пригодятся при создании своих руд. Так что погнали!
Создание особенности (Feature)
Создадим файл для получения события загрузки биомов. В этом же файле пропишем свои особенности (features) для генерации биомов. Features это: пещеры, озёра, трава, цветы, деревья, пещеры, руды, другие виды камня и т.д. Аналогично мы сможем потом добавить ещё свои деревья, структуры и многое другое. Но пока ограничимся блоками.
Я назову файл ModFeatures.java, и добавлю в папку world. В классе пишем такую конструкцию:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Mod.EventBusSubscriber public class ModFeatures { public static void registerFeatures() { } @SubscribeEvent public static void generateFeatures(final BiomeLoadingEvent event) { registerFeatures(); } } |
Смотрите. Мы добавили прослушивание событий, и объявили функцию, которая будет срабатывать при загрузке биомов. Таким образом мы можем что-то подкинуть к ванильным биомам, дополнив их генерацию.
Объявляем переменную настроенной фичи:
1 |
public static ConfiguredFeature<?, ?> FORTIFIED_STONE_GEN; |
А его инициализацию пропишем в registerFeatures:
1 2 3 4 5 6 7 8 9 10 |
FORTIFIED_STONE_GEN = Feature.ORE.configured( new OreConfiguration( OreConfiguration.Predicates.NATURAL_STONE, ModBlocks.FORTIFIED_STONE.get().defaultBlockState(), 5)) .rangeUniform(VerticalAnchor.aboveBottom(10), VerticalAnchor.belowTop(10)) .squared() .count(3); Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, "fortified_stone_gen"), FORTIFIED_STONE_GEN); |
Выглядит… страшновато… Да. Итак. Объяснить бы ещё хоть то, что сам точно понял 🤣. Итак. Мы обращаемся к feature ore. Т.е. особенность – руда. Это как готовый к размещению элемент, который просто нужно немного дополнительно настроить. Все руды в игре работают аналогично. Кстати, подобная логика работает и с другими структурами. Например: деревья.
Если простыми словами, то именно там находится логика размещения руды, определения места и т.д. А нам нужно только указать свои параметры для размещаемых блоков.
Это мы делаем при помощи OreConfiguration. Первым параметром идут блоки (OreConfiguration.Predicates.NATURAL_STONE – все камни), которые можно заменять нашей «рудой». У меня указаны те, что имеют тег натурально генерируемого камня. Второй – наш блок, который и нужно размещать, вернее его block state. А последнее, целое число – возможное количество блоков в жиле.
После этого уже самой конфигурируемой ORE мы можем указать высоту для генерации:
1 2 |
.rangeUniform(VerticalAnchor.aboveBottom(10), VerticalAnchor.belowTop(10)) |
У меня указан промежуток от 10 блоков от низа мира, до 10 блоков от верха.
.squared() — Отвечает за форму жилы, как я понял. Надеюсь, что верно понял, тут я немного поплыл, так как все имена переменных и функций были в формате: func_227228_a_.
А count(3) определяет количество жил в чанке.
Таким образом мы можем отрегулировать какие блоки заменять, сколько жил, насколько большие жилы и на какой высоте. Всё что нужно.
Ой. И была там ещё регистрация:
1 |
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, "fortified_stone_gen"), FORTIFIED_STONE_GEN); |
Тут ничего нового, регистрирует объект по его типу, и задаём имя ресурсов.
Теперь надо внести правки в GSMod.java
Дополняем файл мода
Нам нужно зарегистрировать новую feature. Для этого добавляем функцию setup, где и будем вызвана регистрация. А саму функцию setup повесим на EventBus.
Теперь при загрузке мода feature должна быть зарегистрирована.
Вариант мне не особо понравился, если честно. Мне кажется, должно быть более компактное решение, что-то вроде предметов и блоков. И если оно есть, а вы о нем знаете – сообщите пожалуйста. Пока оставим так)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public GSMod() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener(this::setup); ITEMS.register(bus); BLOCKS.register(bus); MinecraftForge.EVENT_BUS.register(this); } private void setup(final FMLCommonSetupEvent event) { ModFeatures.registerFeatures(); } |
И назад в ModFeatures, где в функции generateFeatures нужно прописать добавление новой особенности в биомы. По логике надо бы сделать проверку на то, какой это биом, из какого измерения. Но камень тоже есть не везде, так что пока просто напишем так:
1 2 3 4 |
@SubscribeEvent public static void generateFeatures(final BiomeLoadingEvent event) { event.getGeneration().getFeatures(GenerationStep.Decoration.UNDERGROUND_ORES).add(() -> FORTIFIED_STONE_GEN); } |
Т.е. через event мы обращаемся к генерации, от неё переходим к особенностям (features), где добавляем к подземным рудам (UNDERGROUND_ORES) нашу новую (не совсем руда, но не суть).
Так, кстати, можно ещё и дополнить спавн мобов, и добавить не только блоки, но и деревья и структуры. Так что ещё не раз сюда обратимся, я думаю.
А теперь можно проверять. Только для теста лучше сделайте по 50 блоков в жиле, и жил побольше. Чтобы долго искать не пришлось.
И этом пока всё!
Список всех уроков: Создание модов для Minecraft 1.15-1.17 [Forge/Fabric]
Исходный код проекта на Github