+0

Crea LÍQUIDOS o Fluidos en Minecraft



Vamos a aprender cómo crear un fluido dentro de Minecraft.

¿Cómo crear un fluido?

Crear un fluido en Minecraft es algo complejo, pero si seguimos unos pasos básicos será algo sencillo.

Crear fluido

Para crear el fluido necesitaremos crear una clase el cual contendrá todas las propiedades de nuestro fluido. Esta clase la llamaremos ModFluid y deberá extender FlowableFluid.

package dev.polv.cursofabric.fluid;  
  
import net.minecraft.block.Block;  
import net.minecraft.block.BlockState;  
import net.minecraft.block.entity.BlockEntity;  
import net.minecraft.fluid.FlowableFluid;  
import net.minecraft.fluid.Fluid;  
import net.minecraft.fluid.FluidState;  
import net.minecraft.util.math.BlockPos;  
import net.minecraft.util.math.Direction;  
import net.minecraft.world.BlockView;  
import net.minecraft.world.World;  
import net.minecraft.world.WorldAccess;  
import net.minecraft.world.WorldView;  
  
public abstract class ModFluid extends FlowableFluid {  
    /**  
     * @return whether the given fluid an instance of this fluid  
     */    @Override  
    public boolean matchesType(Fluid fluid) {  
        return fluid == getStill() || fluid == getFlowing();  
    }  
  
    /**  
     * @return whether the fluid is infinite (which means can be infinitely created like water). In vanilla, it depends on the game rule.  
     */    @Override  
    protected boolean isInfinite(World world) {  
        return false;  
    }  
  
    /**  
     * Perform actions when the fluid flows into a replaceable block. Water drops     * the block's loot table. Lava plays the "block.lava.extinguish" sound.     */    @Override  
    protected void beforeBreakingBlock(WorldAccess world, BlockPos pos, BlockState state) {  
        final BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;  
        Block.dropStacks(state, world, pos, blockEntity);  
    }  
  
    /**  
     * Lava returns true if it's FluidState is above a certain height and the     * Fluid is Water.     *     * @return whether the given Fluid can flow into this FluidState  
     */    @Override  
    protected boolean canBeReplacedWith(FluidState fluidState, BlockView blockView, BlockPos blockPos, Fluid fluid, Direction direction) {  
        return false;  
    }  
  
    /**  
     * Possibly related to the distance checks for flowing into nearby holes?     * Water returns 4. Lava returns 2 in the Overworld and 4 in the Nether.     */    @Override  
    protected int getFlowSpeed(WorldView worldView) {  
        return 4;  
    }  
  
    /**  
     * Water returns 1. Lava returns 2 in the Overworld and 1 in the Nether.     */    @Override  
    protected int getLevelDecreasePerBlock(WorldView worldView) {  
        return 1;  
    }  
  
    /**  
     * Water returns 5. Lava returns 30 in the Overworld and 10 in the Nether.     */    @Override  
    public int getTickRate(WorldView worldView) {  
        return 5;  
    }  
  
    /**  
     * Water and Lava both return 100.0F.     */    @Override  
    protected float getBlastResistance() {  
        return 100.0F;  
    }  
}

Ejemplo de https://fabricmc.net/wiki/tutorial:fluids

Cuando tengamos este ModFluidBase, crearemos nuestro fluido. Este lo haremos creando la clase UraniumFluid que extenderá la clase que acabamos de crear.

package dev.polv.cursofabric.fluid;  
  
import net.minecraft.block.BlockState;  
import net.minecraft.fluid.Fluid;  
import net.minecraft.fluid.FluidState;  
import net.minecraft.item.Item;  
import net.minecraft.state.StateManager;  
import net.minecraft.state.property.Properties;  
  
public abstract class UraniumFluid extends ModFluid {  
  
    @Override  
    public Fluid getStill() {  
        return ModFluids.URANIUM_FLUID.staticFluid();  
    }  
  
    @Override  
    public Fluid getFlowing() {  
        return ModFluids.URANIUM_FLUID.flowingFluid();  
    }  
  
    @Override  
    public Item getBucketItem() {  
        return ModFluids.URANIUM_FLUID.fluidBucket();  
    }  
  
    @Override  
    protected BlockState toBlockState(FluidState fluidState) {  
        return ModFluids.URANIUM_FLUID_BLOCK.getDefaultState().with(Properties.LEVEL_15, getBlockStateLevel(fluidState));  
    }  
  
    public static class Flowing extends UraniumFluid {  
        @Override  
        protected void appendProperties(StateManager.Builder<Fluid, FluidState> builder) {  
            super.appendProperties(builder);  
            builder.add(LEVEL);  
        }  
  
        @Override  
        public int getLevel(FluidState fluidState) {  
            return fluidState.get(LEVEL);  
        }  
  
        @Override  
        public boolean isStill(FluidState fluidState) {  
            return false;  
        }  
    }  
  
    public static class Still extends UraniumFluid {  
        @Override  
        public int getLevel(FluidState fluidState) {  
            return 8;  
        }  
  
        @Override  
        public boolean isStill(FluidState fluidState) {  
            return true;  
        }  
    }  
  
}

Ejemplo de https://fabricmc.net/wiki/tutorial:fluids

Ade

En esta clase lo que hemos hecho es crear dos variantes de nuestro fluido, uno que será quieto, el cual estará estático, y otro que será capaz de extenderse.

Podemos observar métodos dentro de estas clases que hemos extendido para poder implementar funcionalidad personalizada, como hacer daño al jugador cuando esté dentro o hacerlo caminar más lento.

Ahora crearemos la clase ModFluids en plural para registrar nuestros fluidos.

private static RegisteredFluid registeredFluid(String fluidId, Fluid staticFluid, Fluid flowingFluid) {  
    Fluid registeredStaticFluid = Registry.register(Registries.FLUID, new Identifier(CursoFabric.MODID, "static_" + fluidId), staticFluid);  
    Fluid registeredFlowingFluid = Registry.register(Registries.FLUID, new Identifier(CursoFabric.MODID, "flowing_" + fluidId), flowingFluid);  
    BucketItem bucketItem = Registry.register(Registries.ITEM, new Identifier(CursoFabric.MODID, fluidId + "_bucket"), new BucketItem(registeredFlowingFluid, new Item.Settings().maxCount(1)));  
  
    return new RegisteredFluid(registeredStaticFluid, registeredFlowingFluid, bucketItem);  
}  
  
public static void registerFluids() {  
    CursoFabric.LOGGER.info("Registrando fluidos...");  
}
public static final RegisteredFluid URANIUM_FLUID = registeredFluid(  
        "uranium",  
        new UraniumFluid.Still(),  
        new UraniumFluid.Flowing()  
);

Además deberemos añadir la textura del cubo del líquido.

Link de las texturas aquí

Si quisiéramos que nuestro fluido se comportara como el agua o como la lava, podríamos añadirle un tag desde nuestro FluidTagProvider.

Creando bloques de fluido

Muy bien, por ahora tenemos el fluido creado, pero ahora necesitamos crear el bloque el cual representará el fluido dentro del mundo.

Para ello, dentro de nuestra clase ModBlocks, crearemos un nuevo bloque el cual se encargará de esto.

public static final FluidBlock URANIUM_FLUID_BLOCK = registeredFluidBlock(  
        "uranium",  
        URANIUM_FLUID.staticFluid()  
);
 
private static FluidBlock registeredFluidBlock(String fluidId, Fluid staticFluid) {  
    FluidBlock fluidBlock = Registry.register(Registries.BLOCK, new Identifier(CursoFabric.MODID, fluidId + "_liquid"), new FluidBlock((FlowableFluid) staticFluid, FabricBlockSettings.copy(Blocks.WATER)));  
  
    return fluidBlock;  
}

Y por último queda añadir los ítems y bloques que hemos creado dentro de nuestro fluido.

Renderizando el fluido

Ahora tocará registrar en el cliente el renderizado del fluido. Para ello podemos usar unas nuevas texturas o coger la textura del agua y cambiarle el color. Para hacer este tutorial más sencillo usaremos la textura del agua.

@Override  
public void onInitializeClient() {  
    FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.URANIUM_FLUID.staticFluid(), ModFluids.URANIUM_FLUID.flowingFluid(), new SimpleFluidRenderHandler(  
          new Identifier("minecraft:block/water_still"),  
          new Identifier("minecraft:block/water_flow"),  
          0x00ff00  
    ));  
  
    BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), ModFluids.URANIUM_FLUID.staticFluid(), ModFluids.URANIUM_FLUID.flowingFluid());  
}

Y listo, así tendremos nuestro fluido creado.