我们本次使用NBT标签来实现一个生物传送工具:
演示效果 演示效果 演示效果
Q:什么是NBT标签?
A:NBT标签代表着物体的许多特性。玩家可以利用NBT标签存储生物(品种、是否无敌)、物品(伤害加成、耐久)、方块(是否点燃、是否充能)的许多信息。
1.在Java包中新建一个util包,里面新建一个NBT工具类NBTHelper
:
NBTHelper.java
package net.joy187.joyggd.utils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
public class NBTHelper {
//查看物品是否含有名为keyName的nbt
public static boolean hasNbt(ItemStack itemStack, String keyName) {
return !itemStack.isEmpty() && itemStack.getNbt() != null && itemStack.getNbt().contains(keyName);
}
private static void initCompoundNBT(ItemStack itemStack) {
if (itemStack.getNbt() == null) {
itemStack.setNbt(new NbtCompound());
}
}
//得到物品一个名为keyName的nbt
public static NbtCompound getNbt(ItemStack stack, String keyName) {
initCompoundNBT(stack);
if (!stack.getNbt().contains(keyName)) {
putNbt(stack, keyName, new NbtCompound());
}
return stack.getNbt().getCompound(keyName);
}
public static void putNbt(ItemStack stack, String keyName, NbtCompound compound) {
initCompoundNBT(stack);
stack.getNbt().put(keyName, compound);
}
public static void removeNbt(ItemStack stack, String keyName) {
if (stack.getNbt() != null) {
stack.getNbt().remove(keyName);
}
}
}
2.之后我们新建一个物品,并用NBT存储一些信息:
ItemCounter.java
package net.joy187.joyggd.items;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import net.joy187.joyggd.config.ModConfigs;
import net.joy187.joyggd.init.ItemInit;
import net.joy187.joyggd.utils.NBTHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
public class ItemCounter extends Item {
public ItemCounter(Settings settings) {
super(settings);
}
//右键使用物品
@Override
public TypedActionResult<ItemStack> use(World level, PlayerEntity playerIn, Hand hand) {
ItemStack itemstack = playerIn.getMainHandStack();
//如果使用后物品没有字段为"used"的nbt标签,就新建一个nbt
if(!NBTHelper.hasNbt(itemstack,"used"))
{
NbtCompound counter = new NbtCompound();
//在新建的nbt中将玩家的坐标x,y,z分别保留2位小数存入nbt标签中,同时增加一个标签"used"并标记为"1"
counter.putString("x",String.format("%.2f", playerIn.getX()));
counter.putString("y",String.format("%.2f", playerIn.getY()));
counter.putString("z",String.format("%.2f", playerIn.getZ()));
counter.putString("used","1");
//将nbt标签与该物品绑定
itemstack.setNbt(counter);
}
return TypedActionResult.success(itemstack);
}
//对着一个生物右键
@Override
public ActionResult useOnEntity(ItemStack stack, PlayerEntity playerIn, LivingEntity entity, Hand hand) {
ItemStack itemstack = playerIn.getMainHandStack();
//如果说该物品为我们的传送物品并且有"used"这个标签
if(itemstack.getItem() == ItemInit.COUNTER)
{
if(NBTHelper.hasNbt(itemstack,"used"))
{
//就把该生物传送到该物品所记录的那个坐标去
entity.teleport(Double.parseDouble(itemstack.getNbt().getString("x")),
Double.parseDouble(itemstack.getNbt().getString("y")),
Double.parseDouble(itemstack.getNbt().getString("z")));
//传送过后就把"used"这个标签给移除掉,方便下次使用
itemstack.getNbt().remove("used");
}
}
return ActionResult.SUCCESS;
}
//物品是否闪烁附魔效果
@Override
public boolean hasGlint(ItemStack itemstack) {
return NBTHelper.hasNbt(itemstack,"used");
}
//添加物品信息
@Override
public void appendTooltip(ItemStack stack, World worldIn, List<Text> tooltip, TooltipContext flagIn) {
}
}
在ItemInit中添加物品注册语句:
ItemInit.java
public static final Item COUNTER = registerItem("counter",
new ItemCounter(new FabricItemSettings().group(ModMain.ITEMTAB).maxCount(1)));
3.在资源包中添加物品的名称、贴图、模型
物品名称
en_us.json
"item.joyggd.counter":"C",
物品模型
counter.json
{
"parent":"minecraft:item/generated",
"textures":{
"layer0":"joyggd:item/drool"
}
}