このシリーズのまとめはこちら:
umagame.hatenablog.jp
どうも。
はじめに
今回は液体を作ります。泥です。
前回:
umagame.hatenablog.jp
液体を作る
液体登録用クラス
まず、アイテムやブロックと同じように、initに液体を登録するクラスを作ります。
ソースコードの中に、まだ作っていないFluidMudというクラスがあるのでエラーが出ますが気にせずに。
package com.umagame.dirtmod.init;
import com.umagame.dirtmod.fluid.FluidMud;
import com.umagame.dirtmod.main.DirtMod;
import net.minecraft.fluid.Fluid;
import net.minecraft.tags.FluidTags;
import net.minecraft.tags.Tag;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.registries.ObjectHolder;
@ObjectHolder(DirtMod.MOD_ID)
public class DirtModFluids {
public static final FluidMud.Flowing FLOWING_MUD = null;
public static final FluidMud.Source MUD = null;
public static class Tags {
public static final Tag<Fluid> MUD = new FluidTags.Wrapper(new ResourceLocation(DirtMod.MOD_ID, "mud"));
}
@Mod.EventBusSubscriber(modid = DirtMod.MOD_ID, bus = Bus.MOD)
public static class Register {
@SubscribeEvent
public static void registerFluids(final RegistryEvent.Register<Fluid> event) {
final Fluid[] fluids = {
new FluidMud.Flowing().setRegistryName(DirtMod.MOD_ID, "flowing_mud"),
new FluidMud.Source().setRegistryName(DirtMod.MOD_ID, "mud")
};
event.getRegistry().registerAll(fluids);
}
}
}
3つIDを入力するところがあるので忘れないように。
液体のクラス
液体のクラスをfluidパッケージに作ります。
液体の場合は複雑で、いつものようにクラスを継承してメソッドの戻り値を設定する...だけではできないので、とりあえずコピペしてください。
package com.umagame.dirtmod.fluid;
import com.umagame.dirtmod.init.DirtModBlocks;
import com.umagame.dirtmod.init.DirtModFluids;
import com.umagame.dirtmod.item.ItemMudBucket;
import com.umagame.dirtmod.main.DirtMod;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FlowingFluidBlock;
import net.minecraft.fluid.FlowingFluid;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.IFluidState;
import net.minecraft.item.Item;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraftforge.fluids.FluidAttributes;
public abstract class FluidMud extends FlowingFluid{
@Override
public Fluid getFlowingFluid() {
return DirtModFluids.FLOWING_MUD;
}
@Override
public Fluid getStillFluid() {
return DirtModFluids.MUD;
}
@Override
protected boolean canSourcesMultiply() {
return true;
}
@Override
protected void beforeReplacingBlock(IWorld worldIn, BlockPos pos, BlockState state) {
@SuppressWarnings("deprecation")
TileEntity tileentity = state.getBlock().hasTileEntity() ? worldIn.getTileEntity(pos) : null;
Block.spawnDrops(state, worldIn.getWorld(), pos, tileentity);
}
@Override
protected int getSlopeFindDistance(IWorldReader worldIn) {
return 4;
}
@Override
protected int getLevelDecreasePerBlock(IWorldReader worldIn) {
return 1;
}
@Override
public Item getFilledBucket() {
return new ItemMudBucket();
}
@Override
protected boolean func_215665_a(IFluidState p_215665_1_, IBlockReader p_215665_2_, BlockPos p_215665_3_,
Fluid p_215665_4_, Direction p_215665_5_) {
return p_215665_5_ == Direction.DOWN && !p_215665_4_.isIn(DirtModFluids.Tags.MUD);
}
@Override
public int getTickRate(IWorldReader p_205569_1_) {
return 5;
}
@Override
protected float getExplosionResistance() {
return 100.0F;
}
@Override
protected BlockState getBlockState(IFluidState state) {
return DirtModBlocks.MUD.getDefaultState().with(FlowingFluidBlock.LEVEL, Integer.valueOf(getLevelFromState(state)));
}
@Override
public boolean isEquivalentTo(Fluid fluidIn) {
return fluidIn == DirtModFluids.MUD || fluidIn == DirtModFluids.FLOWING_MUD;
}
@Override
protected FluidAttributes createAttributes() {
return FluidAttributes.builder(new ResourceLocation(DirtMod.MOD_ID, "block/mud_still"), new ResourceLocation(DirtMod.MOD_ID, "block/mud_flow"))
.translationKey("block.dirtmod.mud")
.build(this);
}
public static class Flowing extends FluidMud {
@Override
protected void fillStateContainer(Builder<Fluid, IFluidState> builder) {
super.fillStateContainer(builder);
builder.add(LEVEL_1_8);
}
@Override
public boolean isSource(IFluidState state) {
return false;
}
@Override
public int getLevel(IFluidState state) {
return state.get(FluidMud.LEVEL_1_8);
}
}
public static class Source extends FluidMud {
@Override
public boolean isSource(IFluidState state) {
return true;
}
@Override
public int getLevel(IFluidState p_207192_1_) {
return 8;
}
}
}
少し解説すると、
- getFlowingFluidとgetStillFluidで液体を指定
- canSourcesMultiplyで無限水源になるかどうかを指定
- getFilledBucketで液体の入ったバケツのアイテムを指定(後ほど作ります)
- createAttributesで、IDの指定が必要なので忘れずに
- FlowingとSourceクラスで、それぞれのisSourceとgetLevelの値を分けています
- 他のメソッドは、液体自体の設定です(今回は水と同じ挙動をするようにしています。)
これでさっきの登録用クラスのエラーがなくなったかと思います。
液体ブロックの追加
液体のブロックとしてのクラスも必要になるので、blockに新しくクラスを作ります。
FlowingFluidBlockを継承して、superの中に登録用クラスの液体と、Propertiesを設定します。
IDの設定も必要なので忘れずに。
package com.umagame.dirtmod.block;
import com.umagame.dirtmod.init.DirtModFluids;
import com.umagame.dirtmod.main.DirtMod;
import net.minecraft.block.FlowingFluidBlock;
import net.minecraft.block.material.Material;
public class BlockMud extends FlowingFluidBlock{
public BlockMud() {
super(() -> DirtModFluids.MUD, Properties.create(Material.WATER).doesNotBlockMovement().hardnessAndResistance(100.0F).noDrops());
this.setRegistryName(DirtMod.MOD_ID, "mud");
}
}
ちなみに、私の場合superの行で謎のエラーが出ました。
その時はonEntityCollisionというメソッドをオーバーライドしたらなぜか直ったのですが、普通にEclipseを再起動しても大丈夫かと思います。
あと、ブロック登録用クラスで登録しておいてください。
ブロック登録についてはこちら:
umagame.hatenablog.jp
液体バケツの追加
itemに、液体の入ったバケツのクラスを作ります。
BucketItemを継承して作ります。
package com.umagame.dirtmod.item;
import com.umagame.dirtmod.init.DirtModFluids;
import com.umagame.dirtmod.main.DirtMod;
import net.minecraft.item.BucketItem;
public class ItemMudBucket extends BucketItem{
public ItemMudBucket() {
super(() -> DirtModFluids.MUD,new Properties().group(DirtMod.DIRTMOD_TAB));
this.setRegistryName("mud_bucket");
}
}
登録も忘れずに。
アイテム登録についてはこちら:
umagame.hatenablog.jp
とりあえずこれで起動してみます。
テクスチャのない液体が追加されていることが分かります。
ですが、この液体を触れても当たり判定がなく、泳ぐことができません。
これは修正が必要です。
修正・テクスチャ
少し調べたところ、タグというものをいじればいいっぽいです。
src/main/resources/data/minecraft/tags/fluidsに、water.jsonというファイルを作り、
このように記述します。
{
"replace": false,
"values": [
"minecraft:water",
"minecraft:flowing_water",
"dirtmod:mud",
"dirtmod:flowing_mud"
]
}
こうすることにより、追加した液体で泳ぐことができるようになります。
この場合追加した液体にwaterというタグをつけていることになるので、おそらく液体登録用クラスの中に作ったタグの意味はなくなります。(めんどくさいのでこのままでやります)
テクスチャの設定は、バニラの水を参考にして作ります。
textures/blockにpngとmcmetaファイルを追加して、(mcmetaの中身はバニラの水のものと同じです)
models/blockにmud.jsonを作ってこのように入力し、
{
"textures": {
"particle": "block/mud_still"
}
}
blockstatesにmud.jsonを作ってこのように入力します。
{
"variants": {
"": { "model": "block/mud" }
}
}
これで起動すると、テクスチャが反映され、泳げるようになります。
バケツのテクスチャは過去記事を参考にして設定してください。
さいごに
今回はここまでです。
不具合等あればご報告お願いします。
次回は未定です。