====== Создание жидкостей ====== ===== Введение ===== Здесь мы рассмотрим создание жидкости. Если вы планируете создать несколько жидкостей, рекомендуется создать абстрактный базовый класс жидкостей, в котором вы зададите необходимые значения по умолчанию, которые будут общими для его подклассов. Мы также сделаем так, чтобы жидкость генерировалась в мире, как озера. ===== Создание абстрактной жидкости ===== Ванильные жидкости используют '''', сделаем так же. public abstract class TutorialFluid extends class_3609 { /** * @вернём, является ли данная жидкость экземпляром этой жидкости */ @Override public boolean method_15780(class_3611 fluid) { return fluid == method_15751() || fluid == method_15750(); } /** * @вернём, является ли жидкость бесконечной, как вода */ @Override protected boolean method_15737() { return false; } /** * Выполняйте действия, когда жидкость поступает в следующий блок. Вода ссылается * на таблицу добычи блока. Лава воспроизводит звук "block.lava.extinguish". */ @Override protected void method_15730(class_1936 world, class_2338 pos, class_2680 state) { final class_2586 blockEntity = state.method_31709() ? world.method_8321(pos) : null; class_2248.method_9610(state, world, pos, blockEntity); } /** * Лава возвращает значение true, если ее FluidState превышает определенную высоту и * Жидкость - это Вода. * * @вернём, может ли данная жидкость перетекать в этот FluidState */ @Override protected boolean method_15777(class_3610 fluidState, class_1922 blockView, class_2338 blockPos, class_3611 fluid, class_2350 direction) { return false; } /** * На каком расстоянии проверять попадания в близлежащие отверстия? * Вода возвращает 4. Лава возвращает 2 в Верхнем мире и 4 в Нижнем мире. */ @Override protected int method_15733(class_4538 worldView) { return 4; } /** * Вода возвращает 1. Лава возвращает 2 в Верхнем мире и 1 в Нижнем мире. */ @Override protected int method_15739(class_4538 worldView) { return 1; } /** * Вода возвращает 5. Лава возвращает 30 в Верхнем мире и 10 в Нижнем мире. */ @Override public int method_15789(class_4538 worldView) { return 5; } /** * Вода и лава возвращают 100.0F. */ @Override protected float method_15784() { return 100.0F; } } ===== Реализация ===== Теперь давайте создадим настоящую жидкость, которая будет иметь неподвижные и текучие варианты. В этом уроке мы будем называть его Acid(Кислота). Недостающие ссылки будут заполнены в ближайшее время. public abstract class AcidFluid extends TutorialFluid { @Override public class_3611 method_15751() { return VASH_STILL_FLUID_ZDES; } @Override public class_3611 method_15750() { return VASH_FLOWING_FLUID_ZDES; } @Override public class_1792 method_15774() { return VASH_BUCKET_ITEM_ZDES; } @Override protected class_2680 method_15790(class_3610 fluidState) { return VASH_FLUID_BLOCK_ZDES.method_9564().method_11657(class_2741.field_12538, method_15741(fluidState)); } public static class Flowing extends AcidFluid { @Override protected void method_15775(class_2689.class_2690 builder) { super.method_15775(builder); builder.method_11667(field_15900); } @Override public int method_15779(class_3610 fluidState) { return fluidState.method_11654(field_15900); } @Override public boolean method_15793(class_3610 fluidState) { return false; } } public static class Still extends AcidFluid { @Override public int method_15779(class_3610 fluidState) { return 8; } @Override public boolean method_15793(class_3610 fluidState) { return true; } } } Далее мы создадим статические экземпляры неподвижных и текущих вариантов кислоты, а также ведро кислоты. В вашем ''ModInitializer'': public static class_3609 STILL_ACID; public static class_3609 FLOWING_ACID; public static class_1792 ACID_BUCKET; @Override public void onInitialize() { STILL_ACID = class_2378.method_10230(class_2378.field_11154, new class_2960(MOD_ID, "acid"), new AcidFluid.Still()); FLOWING_ACID = class_2378.method_10230(class_2378.field_11154, new class_2960(MOD_ID, "flowing_acid"), new AcidFluid.Flowing()); ACID_BUCKET = class_2378.method_10230(class_2378.field_11142, new class_2960(MOD_ID, "acid_bucket"), new class_1755(STILL_ACID, new class_1792.class_1793().method_7896(class_1802.field_8550).method_7889(1))); // ... } // ... Чтобы ваша жидкость вела себя больше как вода или лава, вы должны добавить ее в соответствующий тег жидкости: для воды создайте файл ''data /minecraft/tags/fluids/water.json'' и запишите туда идентификаторы ваших жидкостей: { "replace": false, "values": [ "your_mod_id:acid", "your_mod_id:flowing_acid" ] } ===== Создание блока жидкости ===== Далее нам нужно создать блок, который будет представлять кислоту в мире. '''' - это класс, который нам нужно использовать, но поскольку его конструктор защищен, мы не можем создать его напрямую. Некоторые способы его использования заключаются в создании подкласса или анонимного подкласса. Здесь мы покажем последнее. В вашем ''ModInitializer'': public static class_2248 ACID; @Override public void onInitialize() { ACID = class_2378.method_10230(class_2378.field_11146, new class_2960(MOD_ID, "acid"), new class_2404(STILL_ACID, FabricBlockSettings.method_9630(class_2246.field_10382)){}); // ... } Теперь, когда у нас есть эти статические объекты, мы можем вернуться к ''AcidFluid'' и заполнить переопределенные методы: public abstract class AcidFluid extends TutorialFluid { @Override public class_3611 method_15751() { return TutorialMod.STILL_ACID; } @Override public class_3611 method_15750() { return TutorialMod.FLOWING_ACID; } @Override public class_1792 method_15774() { return TutorialMod.ACID_BUCKET; } @Override protected class_2680 method_15790(class_3610 fluidState) { // method_15741 converts the LEVEL_1_8 of the fluid state to the LEVEL_15 the fluid block uses return TutorialMod.ACID.method_9564().method_11657(class_2741.field_12538, method_15741(fluidState)); } public static class Flowing extends AcidFluid { @Override protected void method_15775(class_2689.class_2690 builder) { super.method_15775(builder); builder.method_11667(field_15900); } @Override public int method_15779(class_3610 fluidState) { return fluidState.method_11654(field_15900); } @Override public boolean method_15793(class_3610 fluidState) { return false; } } public static class Still extends AcidFluid { @Override public int method_15779(class_3610 fluidState) { return 8; } @Override public boolean method_15793(class_3610 fluidState) { return true; } } } ===== Настройка рендеринга ===== Чтобы ваши жидкости имели текстуру или были окрашены в определенный цвет, вам нужно будет зарегистрировать для них ''FluidRenderHandler''. Здесь мы будем повторно использовать текстуры воды и просто изменим цвет оттенка, примененный к ним. Чтобы убедиться, что текстуры отображаются как полупрозрачные, вы можете использовать ''BlockRenderLayerMap'' Fabric'а. public class TutorialModClient implements ClientModInitializer { @Override public void onInitializeClient() { FluidRenderHandlerRegistry.INSTANCE.register(TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID, new SimpleFluidRenderHandler( new class_2960("minecraft:block/water_still"), new class_2960("minecraft:block/water_flow"), 0x4CC248 )); BlockRenderLayerMap.INSTANCE.putFluids(class_1921.method_23583(), TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID); //если вы хотите использовать свои текстуры, они должны быть зарегистрированы. //В этом примере в этом нет необходимости, поскольку текстуры ванильной воды уже зарегистрированы. //Чтобы зарегистрировать свои пользовательские текстуры, используйте этот метод: //ClientSpriteRegistryCallback.event(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> { // registry.register(new Identifier("modid:block/custom_fluid_still")); // registry.register(new Identifier("modid:block/custom_fluid_flowing")); //}); // ... } } Если вы хотите использовать свои собственные текучие текстуры, вы можете обратиться к ванильным ресурсам ((''assets/minecraft/blockstates/water.json''\\ ''assets/minecraft/models/block/water.json''\\ ''assets/minecraft/textures/block/water_still.png''\\ ''assets/minecraft/textures/block/water_still.png.mcmeta''\\ ''assets/minecraft/textures/block/water_flow.png''\\ ''assets/minecraft/textures/block/water_flow.png.mcmeta'')) as a template. ===== Генерация в мире ===== Чтобы заставить озера кислоты генерироваться в мире, вы можете создать '''' в вашем ''ModInitializer'' а затем добавить его в биомы, в которых вы хотите, чтобы он генерировался: public static LakeFeature ACID_LAKE; @Override public void onInitialize() { ACID_LAKE = Registry.register(Registry.FEATURE, new Identifier(MOD_ID, "acid_lake"), new LakeFeature(SingleStateFeatureConfig::deserialize)); // генерация в болотах, похожих на водные озера, но с вероятностью 40 (чем выше число, тем ниже вероятность генерации) Biomes.SWAMP.addFeature( GenerationStep.Feature.LOCAL_MODIFICATIONS, ACID_LAKE.configure(new SingleStateFeatureConfig(ACID.getDefaultState())) .createDecoratedFeature(Decorator.WATER_LAKE.configure(new ChanceDecoratorConfig(40))) ); }