User Tools

Site Tools


ru:tutorial:fluids

Создание жидкостей

Введение

Здесь мы рассмотрим создание жидкости. Если вы планируете создать несколько жидкостей, рекомендуется создать абстрактный базовый класс жидкостей, в котором вы зададите необходимые значения по умолчанию, которые будут общими для его подклассов. Мы также сделаем так, чтобы жидкость генерировалась в мире, как озера.

Создание абстрактной жидкости

Ванильные жидкости используют net.minecraft.fluid.FlowableFluid, сделаем так же.

  1. public abstract class TutorialFluid extends FlowableFluid {
  2. /**
  3. * @вернём, является ли данная жидкость экземпляром этой жидкости
  4. */
  5. @Override
  6. public boolean matchesType(Fluid fluid) {
  7. return fluid == getStill() || fluid == getFlowing();
  8. }
  9.  
  10. /**
  11. * @вернём, является ли жидкость бесконечной, как вода
  12. */
  13. @Override
  14. protected boolean isInfinite() {
  15. return false;
  16. }
  17.  
  18. /**
  19. * Выполняйте действия, когда жидкость поступает в следующий блок. Вода ссылается
  20. * на таблицу добычи блока. Лава воспроизводит звук "block.lava.extinguish".
  21. */
  22. @Override
  23. protected void beforeBreakingBlock(WorldAccess world, BlockPos pos, BlockState state) {
  24. final BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
  25. Block.dropStacks(state, world, pos, blockEntity);
  26. }
  27.  
  28. /**
  29. * Лава возвращает значение true, если ее FluidState превышает определенную высоту и
  30. * Жидкость - это Вода.
  31. *
  32. * @вернём, может ли данная жидкость перетекать в этот FluidState
  33. */
  34. @Override
  35. protected boolean canBeReplacedWith(FluidState fluidState, BlockView blockView, BlockPos blockPos, Fluid fluid, Direction direction) {
  36. return false;
  37. }
  38.  
  39. /**
  40. * На каком расстоянии проверять попадания в близлежащие отверстия?
  41. * Вода возвращает 4. Лава возвращает 2 в Верхнем мире и 4 в Нижнем мире.
  42. */
  43. @Override
  44. protected int getFlowSpeed(WorldView worldView) {
  45. return 4;
  46. }
  47.  
  48. /**
  49. * Вода возвращает 1. Лава возвращает 2 в Верхнем мире и 1 в Нижнем мире.
  50. */
  51. @Override
  52. protected int getLevelDecreasePerBlock(WorldView worldView) {
  53. return 1;
  54. }
  55.  
  56. /**
  57. * Вода возвращает 5. Лава возвращает 30 в Верхнем мире и 10 в Нижнем мире.
  58. */
  59. @Override
  60. public int getTickRate(WorldView worldView) {
  61. return 5;
  62. }
  63.  
  64. /**
  65. * Вода и лава возвращают 100.0F.
  66. */
  67. @Override
  68. protected float getBlastResistance() {
  69. return 100.0F;
  70. }
  71. }

Реализация

Теперь давайте создадим настоящую жидкость, которая будет иметь неподвижные и текучие варианты. В этом уроке мы будем называть его Acid(Кислота). Недостающие ссылки будут заполнены в ближайшее время.

  1. public abstract class AcidFluid extends TutorialFluid {
  2. @Override
  3. public Fluid getStill() {
  4. return VASH_STILL_FLUID_ZDES;
  5. }
  6.  
  7. @Override
  8. public Fluid getFlowing() {
  9. return VASH_FLOWING_FLUID_ZDES;
  10. }
  11.  
  12. @Override
  13. public Item getBucketItem() {
  14. return VASH_BUCKET_ITEM_ZDES;
  15. }
  16.  
  17. @Override
  18. protected BlockState toBlockState(FluidState fluidState) {
  19. return VASH_FLUID_BLOCK_ZDES.getDefaultState().with(Properties.LEVEL_15, getBlockStateLevel(fluidState));
  20. }
  21.  
  22. public static class Flowing extends AcidFluid {
  23. @Override
  24. protected void appendProperties(StateManager.Builder<Fluid, FluidState> builder) {
  25. super.appendProperties(builder);
  26. builder.add(LEVEL);
  27. }
  28.  
  29. @Override
  30. public int getLevel(FluidState fluidState) {
  31. return fluidState.get(LEVEL);
  32. }
  33.  
  34. @Override
  35. public boolean isStill(FluidState fluidState) {
  36. return false;
  37. }
  38. }
  39.  
  40. public static class Still extends AcidFluid {
  41. @Override
  42. public int getLevel(FluidState fluidState) {
  43. return 8;
  44. }
  45.  
  46. @Override
  47. public boolean isStill(FluidState fluidState) {
  48. return true;
  49. }
  50. }
  51. }

Далее мы создадим статические экземпляры неподвижных и текущих вариантов кислоты, а также ведро кислоты. В вашем ModInitializer:

  1. public static FlowableFluid STILL_ACID;
  2. public static FlowableFluid FLOWING_ACID;
  3. public static Item ACID_BUCKET;
  4.  
  5. @Override
  6. public void onInitialize() {
  7. STILL_ACID = Registry.register(Registry.field_11154, new Identifier(MOD_ID, "acid"), new AcidFluid.Still());
  8. FLOWING_ACID = Registry.register(Registry.field_11154, new Identifier(MOD_ID, "flowing_acid"), new AcidFluid.Flowing());
  9. ACID_BUCKET = Registry.register(Registry.field_11142, new Identifier(MOD_ID, "acid_bucket"),
  10. new BucketItem(STILL_ACID, new Item.Settings().recipeRemainder(Items.BUCKET).maxCount(1)));
  11.  
  12. // ...
  13. }
  14.  
  15. // ...

Чтобы ваша жидкость вела себя больше как вода или лава, вы должны добавить ее в соответствующий тег жидкости: для воды создайте файл data /minecraft/tags/fluids/water.json и запишите туда идентификаторы ваших жидкостей:

  1. {
  2. "replace": false,
  3. "values":
  4. [
  5. "your_mod_id:acid",
  6. "your_mod_id:flowing_acid"
  7. ]
  8. }

Создание блока жидкости

Далее нам нужно создать блок, который будет представлять кислоту в мире. net.minecraft.block.FluidBlock - это класс, который нам нужно использовать, но поскольку его конструктор защищен, мы не можем создать его напрямую. Некоторые способы его использования заключаются в создании подкласса или анонимного подкласса. Здесь мы покажем последнее. В вашем ModInitializer:

  1. public static Block ACID;
  2.  
  3. @Override
  4. public void onInitialize() {
  5. ACID = Registry.register(Registry.field_11146, new Identifier(MOD_ID, "acid"), new FluidBlock(STILL_ACID, FabricBlockSettings.copy(Blocks.WATER)){});
  6.  
  7. // ...
  8. }

Теперь, когда у нас есть эти статические объекты, мы можем вернуться к AcidFluid и заполнить переопределенные методы:

  1. public abstract class AcidFluid extends TutorialFluid {
  2. @Override
  3. public Fluid getStill() {
  4. return TutorialMod.STILL_ACID;
  5. }
  6.  
  7. @Override
  8. public Fluid getFlowing() {
  9. return TutorialMod.FLOWING_ACID;
  10. }
  11.  
  12. @Override
  13. public Item getBucketItem() {
  14. return TutorialMod.ACID_BUCKET;
  15. }
  16.  
  17. @Override
  18. protected BlockState toBlockState(FluidState fluidState) {
  19. // getBlockStateLevel converts the LEVEL_1_8 of the fluid state to the LEVEL_15 the fluid block uses
  20. return TutorialMod.ACID.getDefaultState().with(Properties.LEVEL_15, getBlockStateLevel(fluidState));
  21. }
  22.  
  23. public static class Flowing extends AcidFluid {
  24. @Override
  25. protected void appendProperties(StateManager.Builder<Fluid, FluidState> builder) {
  26. super.appendProperties(builder);
  27. builder.add(LEVEL);
  28. }
  29.  
  30. @Override
  31. public int getLevel(FluidState fluidState) {
  32. return fluidState.get(LEVEL);
  33. }
  34.  
  35. @Override
  36. public boolean isStill(FluidState fluidState) {
  37. return false;
  38. }
  39. }
  40.  
  41. public static class Still extends AcidFluid {
  42. @Override
  43. public int getLevel(FluidState fluidState) {
  44. return 8;
  45. }
  46.  
  47. @Override
  48. public boolean isStill(FluidState fluidState) {
  49. return true;
  50. }
  51. }
  52. }

Настройка рендеринга

Чтобы ваши жидкости имели текстуру или были окрашены в определенный цвет, вам нужно будет зарегистрировать для них FluidRenderHandler. Здесь мы будем повторно использовать текстуры воды и просто изменим цвет оттенка, примененный к ним. Чтобы убедиться, что текстуры отображаются как полупрозрачные, вы можете использовать BlockRenderLayerMap Fabric'а.

  1. public class TutorialModClient implements ClientModInitializer {
  2.  
  3. @Override
  4. public void onInitializeClient() {
  5. FluidRenderHandlerRegistry.INSTANCE.register(TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID, new SimpleFluidRenderHandler(
  6. new Identifier("minecraft:block/water_still"),
  7. new Identifier("minecraft:block/water_flow"),
  8. 0x4CC248
  9. ));
  10.  
  11. BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID);
  12.  
  13. //если вы хотите использовать свои текстуры, они должны быть зарегистрированы.
  14. //В этом примере в этом нет необходимости, поскольку текстуры ванильной воды уже зарегистрированы.
  15. //Чтобы зарегистрировать свои пользовательские текстуры, используйте этот метод:
  16. //ClientSpriteRegistryCallback.event(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> {
  17. // registry.register(new Identifier("modid:block/custom_fluid_still"));
  18. // registry.register(new Identifier("modid:block/custom_fluid_flowing"));
  19. //});
  20.  
  21. // ...
  22. }
  23. }

Если вы хотите использовать свои собственные текучие текстуры, вы можете обратиться к ванильным ресурсам 1) as a template.

Генерация в мире

Чтобы заставить озера кислоты генерироваться в мире, вы можете создать net.minecraft.world.gen.feature.LakeFeature в вашем ModInitializer а затем добавить его в биомы, в которых вы хотите, чтобы он генерировался:

  1. public static LakeFeature ACID_LAKE;
  2.  
  3. @Override
  4. public void onInitialize() {
  5. ACID_LAKE = Registry.register(Registry.FEATURE, new Identifier(MOD_ID, "acid_lake"), new LakeFeature(SingleStateFeatureConfig::deserialize));
  6.  
  7. // генерация в болотах, похожих на водные озера, но с вероятностью 40 (чем выше число, тем ниже вероятность генерации)
  8. Biomes.SWAMP.addFeature(
  9. GenerationStep.Feature.LOCAL_MODIFICATIONS,
  10. ACID_LAKE.configure(new SingleStateFeatureConfig(ACID.getDefaultState()))
  11. .createDecoratedFeature(Decorator.WATER_LAKE.configure(new ChanceDecoratorConfig(40)))
  12. );
  13. }
1)
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
ru/tutorial/fluids.txt · Last modified: 2022/02/25 20:19 by 127.0.0.1