在Minecraft1.12.2中,添加了类似于1.14版甜浆果的植物方块的笔记(样例代码)
我在Minecraft 1.12.2中添加了类似于1.14版本中的甜浆果的植物方块(示例代码)的备忘录。
创建一个可以通过右键点击收获的灌木。
环境
- Forge MDK: forge-1.12.2-14.23.5.2768
前提 (Qian2ti2)
-
- 追加したブロックやアイテムの登録用クラスやプロキシクラスを用意してある
(僕はあゆたきさんのチュートリアルの通りにやりました)
テクスチャのドット絵を用意してある
参考自Vanilla代码。
备考:新操作仅仅是将变量赋值给了原始值,没有进行任何其他操作。
-
- 1.12.2の
ItemFood.class
ItemSeed.class
BlockCrops.class
BlockCarrots.class
apple.json
acacia_sapling.json
carrots.json
1.14.4の
SweetBerryBushBlock.class
最基本的必需代码
我想添加梅树(收获此MOD的梅子)。
备注:请准备好注册用的类。
文件的放置
パッケージ名とかはバニラのマネっ子してます
主要的源码文件位于src/main/java目录下。
-
- FFFMItems.java(アイテムの登録用クラス)
oguro.fffm.init
FFFMBlocks.java(ブロックの登録用クラス)
oguro.fffm.init
BlockFruitTree.java(果物の木の特性を決めるクラス)
oguro.fffm.block
BlockApricotTree.java(あんずの木独自の性質を決めるクラス)
oguro.fffm.block
ItemFruit.java(果物の特性を決めるクラス)
oguro.fffm.item
ItemApricot.java(あんず独自の性質を決めるクラス)
oguro.fffm.item
ItemSapling.java(果物の木の苗の性質を決めるクラス)
oguro.fffm.item
ItemApricotSapling.java(あんずの苗独自の性質を決めるクラス)
oguro.fffm.item
src/main/resources(モデル)
備考: コマンドを使わないとインベントリに表示されることはないのでBlockApricotTreeのインベントリでの見た目のjsonを用意していないがlogにエラー出まくって鬱陶しいので適当でいいから用意したほうがいいかも(見た目が読み込めないだけなので大丈夫)
-
- apricot.json(あんずの見た目)
assets.fffm.models.item
apricot_tree_sapling.json(あんずの苗の見た目)
assets.fffm.models.item
apricot_tree(あんずの木のブロックはメタデータが違う複数のブロックだから、それぞれの見た目を記述したjsonはどれか指定するファイル)
assets.fffm.blockstates
apricot_tree_stage0.json
apricot_tree_stage1.json
apricot_tree_stage2.json
apricot_tree_stage3.json (あんずの木のそれぞれ成長段階ごとの見た目)
assets.fffm.models.block
主要的资源(纹理)
-
- apricot.png(あんずのテクスチャ)
assets.fffm.textures.items
apricot_tree_sapling.png(あんずの苗のテクスチャ)
assets.fffm.textures.items
apricot_tree_stage0.png
apricot_tree_stage1.png
apricot_tree_stage2.png
apricot_tree_stage3.png(あんずの木のテクスチャ)
assets.fffm.textures.blocks
课程源代码
FFFMItems.java
package oguro.fffm.init;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import oguro.fffm.FFFMRef;
import oguro.fffm.item.ItemApricot;
import oguro.fffm.item.ItemApricotTreeSapling;
import oguro.fffm.item.ItemSapling;
public class FFFMItems
{
//アイテムを宣言する
public static ItemSapling APRICOT_TREE_SAPLING;
public static ItemFood APRICOT;
//アイテムのインスタンスを生成する
public static void init()
{
APRICOT_TREE_SAPLING = (ItemSapling) new ItemApricotTreeSapling(FFFMBlocks.APRICOT_TREE).setRegistryName("apricot_tree_sapling")
.setUnlocalizedName("apricot_tree_sapling");
APRICOT = (ItemFood) new ItemApricot().setRegistryName("apricot")
.setUnlocalizedName("apricot");
}
//アイテムを登録する
public static void register()
{
registerItem(APRICOT_TREE_SAPLING);
registerItem(APRICOT);
}
public static void registerItem(Item item)
{
RegistrationHandler.ITEMS.add(item);
}
//アイテムの描画を登録する
public static void registerRenders()
{
registerRender(APRICOT_TREE_SAPLING);
registerRender(APRICOT);
}
private static void registerRender(Item item)
{
ModelLoader.setCustomModelResourceLocation(item, 0,
new ModelResourceLocation(item.getRegistryName(),"inventory"));
}
//内部クラスでアイテムを登録する
@Mod.EventBusSubscriber(modid = FFFMRef.MODID)
public static class RegistrationHandler
{
public static final List<Item> ITEMS = new LinkedList<>();
@SubscribeEvent
public static void registerItems(final RegistryEvent.Register<Item> event)
{
FFFMItems.init();
FFFMItems.register();
ITEMS.stream().forEach(item -> event.getRegistry().register(item));
}
}
}
FFFMBlocks.java可以进行改写为:方方方方模块.java
package oguro.fffm.init;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import oguro.fffm.FFFMRef;
import oguro.fffm.block.BlockApricotTree;
import oguro.fffm.block.BlockFruitTree;
public class FFFMBlocks
{
//登録するブロックを宣言
public static BlockFruitTree APRICOT_TREE;
//ブロックのインスタンスを生成
public static void init()
{
APRICOT_TREE = (BlockFruitTree) new BlockApricotTree().setRegistryName("apricot_tree")
.setUnlocalizedName("apricot_tree");
}
//ブロックを登録する
public static void register()
{
registerBlock(APRICOT_TREE);
}
//ブロックの登録
public static void registerBlock(Block block)
{
registerBlock(block, new ItemBlock(block));
}
//アイテムブロックの登録
public static void registerBlock(Block block, ItemBlock item)
{
RegistrationHandler.BLOCKS.add(block);
item.setRegistryName(block.getRegistryName());
FFFMItems.RegistrationHandler.ITEMS.add(item);
}
//アイテムブロックの描画を登録する
public static void registerRenders()
{
registerRender(APRICOT_TREE);
}
@SideOnly(Side.CLIENT)
private static void registerRender(Block block)
{
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0,
new ModelResourceLocation(block.getRegistryName(),"inventory"));
}
//内部クラスでブロックを登録する
@Mod.EventBusSubscriber(modid = FFFMRef.MODID)
public static class RegistrationHandler {
public static final List<Block> BLOCKS = new LinkedList<>();
@SubscribeEvent
public static void registerItems(final RegistryEvent.Register<Block> event) {
FFFMBlocks.init();
FFFMBlocks.register();
BLOCKS.stream().forEach(block -> event.getRegistry().register(block));
}
}
}
BlockFruitTree.java 代码块
package oguro.fffm.block;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.IGrowable;
import net.minecraft.block.SoundType;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import oguro.fffm.init.FFFMItems;
//BlockCropsを改造しつつ1.14.4のSweetBerryBushBlockから果物入手あたりの処理をパクってきた。
//新しいフルーツを追加するときは、このクラスを継承してドロップするアイテムなどの変数を書き換えることにする。
public class BlockFruitTree
extends BlockBush
implements IGrowable
{
//作物の成長段階を作る。ここでは0から3の4段階。
public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 3);
protected BlockFruitTree()
{
this.setDefaultState(this.blockState.getBaseState().withProperty(this.getAgeProperty(), Integer.valueOf(0)));
this.setTickRandomly(true);
this.setCreativeTab((CreativeTabs)null);
this.setHardness(0.0F);
this.setSoundType(SoundType.PLANT);
this.disableStats();
}
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
return FULL_BLOCK_AABB;
}
//成長に関する記述
protected boolean canSustainBush(IBlockState state)
{
//設置可能(作付け可能)なブロック
//BlockFruitTreeでは「耕地(FARMLAND)」、「草ブロック(GRASS)」、「土(DIRT)」の上に植えられるようにした。
return state.getBlock() == Blocks.FARMLAND ||
state.getBlock() == Blocks.GRASS ||
state.getBlock() == Blocks.DIRT;
}
protected PropertyInteger getAgeProperty()
{
return AGE;
}
public int getMaxAge()
{
//最大成長段階は今回は3
return 3;
}
protected int getAge(IBlockState state)
{
return ((Integer)state.getValue(this.getAgeProperty())).intValue();
}
public IBlockState withAge(int age)
{
return this.getDefaultState().withProperty(this.getAgeProperty(), Integer.valueOf(age));
}
public boolean isMaxAge(IBlockState state)
{
return ((Integer)state.getValue(this.getAgeProperty())).intValue() >= this.getMaxAge();
}
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
super.updateTick(worldIn, pos, state, rand);
if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light
if (worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
int i = this.getAge(state);
if (i < this.getMaxAge())
{
float f = getGrowthChance(this, worldIn, pos);
if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt((int)(25.0F / f) + 1) == 0))
{
worldIn.setBlockState(pos, this.withAge(i + 1), 2);
net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos));
}
}
}
}
public void grow(World worldIn, BlockPos pos, IBlockState state)
{
int i = this.getAge(state) + this.getBonemealAgeIncrease(worldIn);
int j = this.getMaxAge();
if (i > j)
{
i = j;
}
worldIn.setBlockState(pos, this.withAge(i), 2);
}
protected int getBonemealAgeIncrease(World worldIn)
{
return MathHelper.getInt(worldIn.rand, 2, 5);
}
protected static float getGrowthChance(Block blockIn, World worldIn, BlockPos pos)
{
float f = 4.0F;
BlockPos blockpos = pos.down();
for (int i = -1; i <= 1; ++i)
{
for (int j = -1; j <= 1; ++j)
{
float f1 = 0.0F;
IBlockState iblockstate = worldIn.getBlockState(blockpos.add(i, 0, j));
if (iblockstate.getBlock().canSustainPlant(iblockstate, worldIn, blockpos.add(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)blockIn))
{
f1 = 4.0F;
if (iblockstate.getBlock().isFertile(worldIn, blockpos.add(i, 0, j)))
{
f1 = 5.2F;
}
}
if (i != 0 || j != 0)
{
f1 /= 6.0F;
}
f += f1;
}
}
BlockPos blockpos1 = pos.north();
BlockPos blockpos2 = pos.south();
BlockPos blockpos3 = pos.west();
BlockPos blockpos4 = pos.east();
boolean flag = blockIn == worldIn.getBlockState(blockpos3).getBlock() || blockIn == worldIn.getBlockState(blockpos4).getBlock();
boolean flag1 = blockIn == worldIn.getBlockState(blockpos1).getBlock() || blockIn == worldIn.getBlockState(blockpos2).getBlock();
if (flag && flag1)
{
f /= 2.0F;
}
else
{
boolean flag2 = blockIn == worldIn.getBlockState(blockpos3.north()).getBlock() || blockIn == worldIn.getBlockState(blockpos4.north()).getBlock() || blockIn == worldIn.getBlockState(blockpos4.south()).getBlock() || blockIn == worldIn.getBlockState(blockpos3.south()).getBlock();
if (flag2)
{
f /= 4.8F;
}
}
return f;
}
//破壊したときに落とす「苗アイテム」の設定
//このクラスはどの果樹からも直接呼び出されない予定なのでとりあえずあんずの苗にしておく。
protected Item getSapling()
{
return FFFMItems.APRICOT_TREE_SAPLING;
}
//破壊したときに落とす「果物」とその個数の設定
//このクラスはどの果樹からも直接呼び出されない予定なのでとりあえずあんずを2個にしておく。
protected Item getFruit()
{
return Items.APRICOT;
}
protected int getHowManyPickUp()
{
return 2;
}
//ドロップするようにする
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
return this.getSapling();
}
public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
{
return new ItemStack(this.getSapling());
}
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
int i = this.getAge(state);
boolean flag = i == 3;
if (!flag && playerIn.getHeldItem(hand).getItem() == Items.DYE) {
return false;
}
//age=2(準最大成長)のときに収穫する処理
else if (i == 2)
{
//収穫できる個数
//getHowManyPickUpで設定した収穫個数だけ収穫できる設定にしてある。
int j = getHowManyPickUp();
spawnAsEntity(worldIn, pos, new ItemStack(getFruit(), j + (flag ? 1 : 0)));
//収穫時に鳴らす音
//新しい音を追加せずに「額縁からアイテムを剥ぎ取る音」にした。
worldIn.playSound((EntityPlayer)null, pos, SoundEvents.ENTITY_ITEMFRAME_REMOVE_ITEM, SoundCategory.BLOCKS, 1.0F, 0.8F + worldIn.rand.nextFloat() * 0.4F);
worldIn.setBlockState(pos, this.withAge(Integer.valueOf(0)), 2);
return true;
}
//age=3(最大成長)のときに収穫する処理
else if (i == 3)
{
//収穫できる個数
//getHowManyPickUpで設定した収穫個数の2倍を収穫できる設定にしてある。
int j = getHowManyPickUp() * 2;
spawnAsEntity(worldIn, pos, new ItemStack(getFruit(), j + (flag ? 1 : 0)));
//収穫時に鳴らす音
//新しい音を追加せずに「額縁からアイテムを剥ぎ取る音」にした。
worldIn.playSound((EntityPlayer)null, pos, SoundEvents.ENTITY_ITEMFRAME_REMOVE_ITEM, SoundCategory.BLOCKS, 1.0F, 0.8F + worldIn.rand.nextFloat() * 0.4F);
worldIn.setBlockState(pos, this.withAge(Integer.valueOf(0)), 2);
return true;
}
//age=2に満たないときは「収穫しない処理
else
{
return super.onBlockActivated(worldIn, pos, state, playerIn, hand, facing, hitX, hitY, hitZ);
}
}
//IGrowableに関する記述
@Override
public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient)
{
return !this.isMaxAge(state);
}
@Override
public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
return true;
}
@Override
public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
this.grow(worldIn, pos, state);
}
//成長段階ごとのブロックをメタデータの異なるブロックとして管理
public IBlockState getStateFromMeta(int meta)
{
return this.withAge(meta);
}
public int getMetaFromState(IBlockState state)
{
return this.getAge(state);
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {AGE});
}
}
挡住杏树.java
package oguro.fffm.block;
import net.minecraft.item.Item;
import oguro.fffm.init.FFFMItems;
public class BlockApricotTree
extends BlockFruitTree
{
//苗アイテムを設定
protected Item getSapling()
{
return FFFMItems.APRICOT_TREE_SAPLING;
}
//果物アイテムを設定
protected Item getFruit()
{
return FFFMItems.APRICOT;
}
//収穫できる個数を設定
protected int getHowManyPickUp()
{
return 2;
}
}
ItemFruit.java
package oguro.fffm.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import oguro.fffm.creativetab.FFFMCreativeTabs;
public class ItemFruit
extends ItemFood
{
//満腹度回復量
protected static int getHealAmount()
{
return 5;
}
//オオカミが食べるかどうか
protected static boolean canWolfEat()
{
return false;
}
//食べるのにかかる時間
protected int getEatTime()
{
return 32;
}
//食べるときのアニメーション
//デフォルトでEAT
public EnumAction getItemUseAction(ItemStack stack)
{
return EnumAction.EAT;
}
//満腹でも食べられるか
//デフォルトでいいえ
protected boolean canEatAlways()
{
return false;
}
public ItemFruit()
{
super(getHealAmount(), canWolfEat());
this.setCreativeTab(FFFMCreativeTabs.FFFM_FRUIT);
}
public int getMaxItemUseDuration(ItemStack stack)
{
return getEatTime();
}
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
{
ItemStack itemstack = playerIn.getHeldItem(handIn);
if (playerIn.canEat(canEatAlways()))
{
playerIn.setActiveHand(handIn);
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack);
}
else
{
return new ActionResult<ItemStack>(EnumActionResult.FAIL, itemstack);
}
}
}
项目杏子.java
package oguro.fffm.item;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import oguro.fffm.creativetab.FFFMCreativeTabs;
public class ItemFruit
extends ItemFood
{
//満腹度回復量
protected static int getHealAmount()
{
return 5;
}
//オオカミが食べるかどうか
protected static boolean canWolfEat()
{
return false;
}
//食べるのにかかる時間
protected int getEatTime()
{
return 32;
}
//食べるときのアニメーション
//デフォルトでEAT
public EnumAction getItemUseAction(ItemStack stack)
{
return EnumAction.EAT;
}
//満腹でも食べられるか
//デフォルトでいいえ
protected boolean canEatAlways()
{
return false;
}
public ItemFruit()
{
super(getHealAmount(), canWolfEat());
this.setCreativeTab(FFFMCreativeTabs.FFFM_FRUIT);
}
public int getMaxItemUseDuration(ItemStack stack)
{
return getEatTime();
}
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
{
ItemStack itemstack = playerIn.getHeldItem(handIn);
if (playerIn.canEat(canEatAlways()))
{
playerIn.setActiveHand(handIn);
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack);
}
else
{
return new ActionResult<ItemStack>(EnumActionResult.FAIL, itemstack);
}
}
}
物品苗木.java
package oguro.fffm.item;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import oguro.fffm.block.BlockFruitTree;
import oguro.fffm.creativetab.FFFMCreativeTabs;
import oguro.fffm.init.FFFMBlocks;
//バニラのItemSeedを引っ張ってきたっぽい(覚えてない)。
//新しいフルーツを追加するときは、このクラスを継承して植える果樹などの変数を書き換えることにする。
public class ItemSapling
extends Item
implements IPlantable
{
private final BlockFruitTree crops;
protected Block getTree()
{
//植える果樹
//このクラスはどの果樹からも直接呼び出されない予定なのでとりあえずあんずの木にしておく。
return FFFMBlocks.APRICOT_TREE;
}
public ItemSapling(BlockFruitTree fruit_tree)
{
this.crops = (BlockFruitTree) this.getTree();
//クリエイティブタブ
//私は新しく「FFFM_SAPLING」というクリエイティブタブを作ってそこに入れた。
//バニラのクリエイティブタブをそのまま使うならthis.setCreativeTab(CreativeTabs.FOOD);とか
this.setCreativeTab(FFFMCreativeTabs.FFFM_SAPLINGS);
}
public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
ItemStack itemstack = player.getHeldItem(hand);
net.minecraft.block.state.IBlockState state = worldIn.getBlockState(pos);
if (facing == EnumFacing.UP && player.canPlayerEdit(pos.offset(facing), facing, itemstack) && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, (IPlantable) this) && worldIn.isAirBlock(pos.up()))
{
worldIn.setBlockState(pos.up(), this.crops.getDefaultState());
if (player instanceof EntityPlayerMP)
{
CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos.up(), itemstack);
}
itemstack.shrink(1);
return EnumActionResult.SUCCESS;
}
else
{
return EnumActionResult.FAIL;
}
}
@Override
public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos)
{
return net.minecraftforge.common.EnumPlantType.Plains;
}
@Override
public net.minecraft.block.state.IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos)
{
return this.crops.getDefaultState();
}
}
项目杏树幼苗.java
package oguro.fffm.item;
import net.minecraft.block.Block;
import oguro.fffm.block.BlockFruitTree;
import oguro.fffm.init.FFFMBlocks;
public class ItemApricotTreeSapling extends ItemSapling {
public ItemApricotTreeSapling(BlockFruitTree fruit_tree) {
super(fruit_tree);
}
//植える果樹
@Override
protected Block getTree()
{
return FFFMBlocks.APRICOT_TREE;
}
}
json的源代码
如果在JSON和类的碰撞检测上做一些调整,也许可以将高度变为2个块。
杏子.json .json)
{
"parent": "item/generated",
"textures": {
"layer0": "fffm:items/apricot"
}
}
杏树苗.json
{
"parent": "item/generated",
"textures": {
"layer0": "fffm:blocks/apricot_tree_sapling"
}
}
杏树.json
{
"variants": {
"age=0": { "model": "fffm:apricot_tree_stage0" },
"age=1": { "model": "fffm:apricot_tree_stage1" },
"age=2": { "model": "fffm:apricot_tree_stage2" },
"age=3": { "model": "fffm:apricot_tree_stage3" }
}
}
杏树阶段◯.json
请帮我修改◯里面的数字
{
"parent": "block/cross",
"textures": {
"cross": "fffm:blocks/apricot_tree_stage◯"
}
}