====== 创建流体 ====== ===== 概述 ===== 在这里,我们将介绍自定义流体的创建。如果计划创建多个流体,建议创建一个抽象的基本流体类,在其中设置必要的默认值,这些默认值将在其子类中共享。我们还将使其像湖泊一样在世界中生成。 ===== 创建抽象流体 ===== 原版流体继承了 '''',我们也应如此。 public abstract class TutorialFluid extends class_3609 { /** * @return 给定的流体是否为该流体的实例? */ @Override public boolean method_15780(class_3611 fluid) { return fluid == getStill() || fluid == getFlowing(); } /** * @return 流体是否可以像无限刷水的方法一样无限生成?在原版,这取决于游戏规则。 */ @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 BlockEntity blockEntity = state.getBlock().hasBlockEntity() ? world.getBlockEntity(pos) : null; Block.dropStacks(state, world, pos, blockEntity); } /** * 熔岩在其 FluidState 高于指定的高度且该流体为水时返回 true。 * * @return 给定的流体能否流入它的 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; } } ===== 实现 ===== 现在让我们制作一个拥有静止和流动两个变种的实际流体。在此教程中,我们将其称为“酸”。缺失的引用稍后补全。 public abstract class AcidFluid extends TutorialFluid { @Override public class_3611 method_15751() { return YOUR_STILL_FLUID_HERE; } @Override public class_3611 method_15750() { return YOUR_FLOWING_FLUID_HERE; } @Override public class_1792 method_15774() { return YOUR_BUCKET_ITEM_HERE; } @Override protected class_2680 method_15790(class_3610 fluidState) { return YOUR_FLUID_BLOCK_HERE.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_7923.field_41173, new class_2960("tutorial", "acid"), new AcidFluid.Still()); FLOWING_ACID = class_2378.method_10230(class_7923.field_41173, new class_2960("tutorial", "flowing_acid"), new AcidFluid.Flowing()); ACID_BUCKET = class_2378.method_10230(class_7923.field_41178, new class_2960("tutorial", "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'' 文件,并在其中写入流体 id: { "replace": false, "values": [ "tutorial:acid", "tutorial:flowing_acid" ] } ==== 制作一个流体方块 ==== 接下来,我们需要在世界中创建表示酸的方块。'''' 是我们需要使用的类,但由于其构造器受保护,我们不能直接构造它。一种解决方法是制作子类或者匿名子类。这里我们展示后一种方式。在您的 ''ModInitializer'' 中: public static class_2248 ACID; @Override public void onInitialize() { ACID = class_2378.method_10230(class_7923.field_41175, new class_2960("tutorial", "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 将流体状态的 LEVEL_1_8 转换为流体方块使用的 LEVEL_15 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''。这里,我们重用水的纹理,并仅仅改变用于其上的颜色。为确保纹理渲染为半透明的,你可以使用 Fabric 的 ''BlockRenderLayerMap''(参见 [[blockappearance]])。 @Environment(EnvType.CLIENT) 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); //if you want to use custom textures they needs to be registered. //In this example this is unnecessary because the vanilla water textures are already registered. //To register your custom textures use this method. //ClientSpriteRegistryCallback.event(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> { // registry.register(new Identifier("tutorial:block/custom_fluid_still")); // registry.register(new Identifier("tutorial: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''))作为一个模板。 ===== 在世界中生成 ===== 为使得酸湖在世界中生成,你可以在你的''ModInitializer''中创建一个''net.minecraft.world.gen.feature.LakeFeature'',然后将其添加到你需要让它生成的生物群系中: // ... 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))) ); // ... } // ...