【春Modを作ろう】ちらし寿司を追加しよう

【寿司職人になろう】オリジナルのアイテムを追加しよう

springmodディレクトリにModBlocks.javaを作成し、以下をコピー。

package mark.sushi.sushimod;

import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
package mark.spring.springmod;

import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.item.BlockItem;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;

public class ModBlocks {

  private static Block registerBlock(String name, Block block) {
    Block registeredBlock = Registry.register(Registries.BLOCK, new Identifier(Springmod.MOD_ID, name), block);

    // ブロックアイテムの登録
    Registry.register(Registries.ITEM, new Identifier(Springmod.MOD_ID, name),
        new BlockItem(registeredBlock, new FabricItemSettings()));
    return registeredBlock;
  }

  public static void registerModBlocks() {
    Springmod.LOGGER.info("Registering Mod Blocks for " + Springmod.MOD_ID);
  }
}

アイテムの追加のため以下のコードを追加(黄色の部分)

public class ModBlocks {


  public static final Block CHIRASHI_SUSHI = registerBlock("chirashi_sushi",new CustomCakeBlock(FabricBlockSettings.copyOf(Blocks.CAKE).strength(0.5F).nonOpaque()));

  private static Block registerBlock(String name, Block block) {
    Block registeredBlock = Registry.register(Registries.BLOCK, new Identifier(Springmod.MOD_ID, name), block);

    // ブロックアイテムの登録
    Registry.register(Registries.ITEM, new Identifier(Springmod.MOD_ID, name),
        new BlockItem(registeredBlock, new FabricItemSettings()));
    return registeredBlock;
  }

  public static void registerModBlocks() {
    Springmod.LOGGER.info("Registering Mod Blocks for " + Springmod.MOD_ID);
  }
}

Springmod.javaを編集(黄色の部分)

package mark.spring.springmod;

import net.fabricmc.api.ModInitializer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Springmod implements ModInitializer {
	public static final String MOD_ID = "springmod";

	public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

	@Override
	public void onInitialize() {
		ModItems.registerModItems();
		ModItemGroup.registerItemGroups();
		ModBlocks.registerModBlocks();

		LOGGER.info("Hello Fabric world!");
	}
}

ModItemGroup.javaを編集(黄色の部分)

package mark.sushi.sushimod;

import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
package mark.spring.springmod;

import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

public class ModItemGroup {
  public static final ItemGroup SPRING_GROUP = Registry.register(Registries.ITEM_GROUP,
      new Identifier(Springmod.MOD_ID, "spring"),
      FabricItemGroup.builder().displayName(Text.translatable("itemgroup.spring"))
          .icon(() -> new ItemStack(ModItems.ODANGO)).entries((displayContext, entries) -> {
            entries.add(ModItems.ODANGO);
            entries.add(ModBlocks.CHIRASHI_SUSHI);


          }).build());


  public static void registerItemGroups() {
    Springmod.LOGGER.info("Registering Item Groups for " + Springmod.MOD_ID);
  }
}

springmodディレクトリにCustomCakeBlock.javaを作成し、以下をコピー。

package mark.spring.springmod;

import net.minecraft.block.*;
import net.minecraft.entity.ai.pathing.NavigationType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.tag.ItemTags;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.stat.Stats;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.IntProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.state.property.Property;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import net.minecraft.world.event.GameEvent;

public class CustomCakeBlock extends CakeBlock {
  public static final int MAX_BITES = 6;
  public static final IntProperty BITES;
  public static final int DEFAULT_COMPARATOR_OUTPUT;
  protected static final float field_31047 = 1.0F;
  protected static final float field_31048 = 2.0F;
  protected static final VoxelShape[] BITES_TO_SHAPE;

  public CustomCakeBlock(AbstractBlock.Settings settings) {
    super(settings);
    this.setDefaultState((BlockState)((BlockState)this.stateManager.getDefaultState()).with(BITES, 0));
  }

  @Override
  public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
    return BITES_TO_SHAPE[(Integer)state.get(BITES)];
  }

  @Override
  public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
    ItemStack itemStack = player.getStackInHand(hand);
    Item item = itemStack.getItem();
    if (itemStack.isIn(ItemTags.CANDLES) && (Integer)state.get(BITES) == 0) {
      Block block = Block.getBlockFromItem(item);
      if (block instanceof CandleBlock) {
        if (!player.isCreative()) {
          itemStack.decrement(1);
        }

        world.playSound((PlayerEntity)null, pos, SoundEvents.BLOCK_CAKE_ADD_CANDLE, SoundCategory.BLOCKS, 1.0F, 1.0F);
        world.setBlockState(pos, CandleCakeBlock.getCandleCakeFromCandle(block));
        world.emitGameEvent(player, GameEvent.BLOCK_CHANGE, pos);
        player.incrementStat(Stats.USED.getOrCreateStat(item));
        return ActionResult.SUCCESS;
      }
    }

    if (world.isClient) {
      if (tryEat(world, pos, state, player).isAccepted()) {
        return ActionResult.SUCCESS;
      }

      if (itemStack.isEmpty()) {
        return ActionResult.CONSUME;
      }
    }

    return tryEat(world, pos, state, player);
  }

  protected static ActionResult tryEat(WorldAccess world, BlockPos pos, BlockState state, PlayerEntity player) {
    if (!player.canConsume(false)) {
      return ActionResult.PASS;
    } else {
      player.incrementStat(Stats.EAT_CAKE_SLICE);
      player.getHungerManager().add(2, 0.1F);
      int i = (Integer)state.get(BITES);
      world.emitGameEvent(player, GameEvent.EAT, pos);
      if (i < 6) {
        world.setBlockState(pos, (BlockState)state.with(BITES, i + 1), 3);
      } else {
        world.removeBlock(pos, false);
        world.emitGameEvent(player, GameEvent.BLOCK_DESTROY, pos);
      }

      return ActionResult.SUCCESS;
    }
  }

  @Override
  public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
    return direction == Direction.DOWN && !state.canPlaceAt(world, pos) ? Blocks.AIR.getDefaultState() : super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
  }
  @Override
  public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
    return world.getBlockState(pos.down()).isSolid();
  }
  @Override
  protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
    builder.add(new Property[]{BITES});
  }
  @Override
  public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
    return getComparatorOutput((Integer)state.get(BITES));
  }

  public static int getComparatorOutput(int bites) {
    return (7 - bites) * 2;
  }
  @Override
  public boolean hasComparatorOutput(BlockState state) {
    return true;
  }
  @Override
  public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
    return false;
  }

  static {
    BITES = Properties.BITES;
    DEFAULT_COMPARATOR_OUTPUT = getComparatorOutput(0);
    BITES_TO_SHAPE = new VoxelShape[]{Block.createCuboidShape((double)1.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)3.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)5.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)7.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)9.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)11.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F), Block.createCuboidShape((double)13.0F, (double)0.0F, (double)1.0F, (double)15.0F, (double)8.0F, (double)15.0F)};
  }
}

テクスチャーを追加しよう

1-2 : ディレクトリを作成しよう!
sushimod/texturesディレクトリをクリック
blockディレクトリを作成

blockディレクトリに以下ファイル名でダウンロードしたテクスチャをアップロードしよう!
・chirashi_sushi_bottom.png
・chirashi_sushi_inner.png
・chirashi_sushi_side.png
・chirashi_sushi_top.png

2-1 : モデルファイルの作成
sushimod/modelsディレクトリをクリック
blockディレクトリを作成

models/blockディレクトリにファイル作成をクリックしてchirashi_sushi.jsonを作成し以下のように編集。

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side"
  },
  "elements": [
  {   "from": [ 1, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#side" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

同じディレクトリでファイル作成をクリックして、食べた回数に応じて見た目が変わる6種類分のモデルファイルを作成し以下のように編集:

・chirashi_sushi_slice_1.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 3, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

・chirashi_sushi_slice_2.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
{
  "textures": {
{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 5, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

・chirashi_sushi_slice_3.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 7, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

・chirashi_sushi_slice_4.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 9, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

・chirashi_sushi_slice_5.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 11, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

・chirashi_sushi_slice_6.json

{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
{
  "textures": {
  "particle": "springmod:block/chirashi_sushi_side",
  "bottom": "springmod:block/chirashi_sushi_bottom",
  "top": "springmod:block/chirashi_sushi_top",
  "side": "springmod:block/chirashi_sushi_side",
  "inside": "springmod:block/chirashi_sushi_inner"
  },
  "elements": [
  {   "from": [ 13, 0, 1 ],
    "to": [ 15, 8, 15 ],
    "faces": {
    "down":  { "texture": "#bottom", "cullface": "down" },
    "up":  { "texture": "#top" },
    "north": { "texture": "#side" },
    "south": { "texture": "#side" },
    "west":  { "texture": "#inside" },
    "east":  { "texture": "#side" }
    }
  }
  ]
}

3-1 : モデルファイルの作成
models/itemディレクトリにファイル作成をクリックしてchirashi_sushi.jsonを作成し以下のように編集。

{
  "parent": "minecraft:item/generated",
  "textures": {
  "layer0": "springmod:item/chirashi_sushi"
  }
}

textures/itemディレクトリにchirashi_sushi.pngというファイル名でダウンロードしたテクスチャをアップロードしよう!

4-1 : ディレクトリの作成
assets/springmodディレクトリをクリック
blockstatesディレクトリを作成

作成したblockstatesディレクトリにファイル作成をクリックしてchirashi_sushi.jsonを作成し以下のように編集。

{
{
  "variants": {
  "bites=0": {
    "model": "springmod:block/chirashi_sushi"
  },
  "bites=1": {
    "model": "springmod:block/chirashi_sushi_slice_1"
  },
  "bites=2": {
    "model": "springmod:block/chirashi_sushi_slice_2"
  },
  "bites=3": {
    "model": "springmod:block/chirashi_sushi_slice_3"
  },
  "bites=4": {
    "model": "springmod:block/chirashi_sushi_slice_4"
  },
  "bites=5": {
    "model": "springmod:block/chirashi_sushi_slice_5"
  },
  "bites=6": {
    "model": "springmod:block/chirashi_sushi_slice_6"
  }
  }
}
タイトルとURLをコピーしました