在之前的教程里,我们很简单的创建了一个item——物品,这个物品可以是食物,可以是药水,也可以是武器和工具,甚至是没有用的物品,那仅仅是这样还不行,我还要给他加一些自定义功能,比如武器右键可以释放技能,吃下食物可以获得自定义效果,药水也是,当然上一期的药水效果还不够“自定义”,因此这期教程先从武器说起,如何实现自定义的武器?本期的武器需要有以下功能:“下界合金剑放到高炉里烧成咱们的自定义武器,自定义武器拥有击退和火焰附加附魔,右键释放技能——发射自定义火球,这个火球和别的火球不一样,他不会破坏方块,而且由火球引燃的实体不会停止燃烧
一.新建一个武器类
首先要实现一个完全自定义的武器,需要单独写一个类,这个类继承SwordItem,也就是剑的物品,然后使用注解@Override重写父类的方法,然后再用注册表注册该物品即可,和之前的是一样的,下面上代码:
public class FlameSwordItem extends SwordItem {
public FlameSwordItem() {
super(Tiers.NETHERITE, 10, -2.4F,
new Properties()
.durability(2031)
.rarity(Rarity.EPIC)
.fireResistant()
);
}
// 确保物品可被附魔
@Override
public boolean isEnchantable(@NotNull ItemStack stack) {
return true;
}
// 设置附魔等级系数
@Override
public int getEnchantmentValue() {
return 30; // 30级附魔能力
}
// 显示附魔光效
@Override
public boolean isFoil(ItemStack stack) {
return true;
}
// 物品描述
@Override
public void appendHoverText(ItemStack stack, @Nullable Level level,
List<Component> tooltip, TooltipFlag flag) {
tooltip.add(Component.translatable("tooltip.flame_sword.desc")
.withStyle(ChatFormatting.GOLD));
super.appendHoverText(stack, level, tooltip, flag);
}
public static void applyDefaultEnchantments(ItemStack stack) {
stack.enchant(Enchantments.KNOCKBACK, 2);
stack.enchant(Enchantments.FIRE_ASPECT, 3);
}
@Override
public void onCraftedBy(@NotNull ItemStack stack, @NotNull Level level, @NotNull Player player) {
if (!EnchantmentHelper.getEnchantments(stack).containsKey(Enchantments.KNOCKBACK)&&stack.getItem() instanceof FlameSwordItem) {
applyDefaultEnchantments(stack);
}
}
@Override
public @NotNull InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
if (world.isClientSide || player.getCooldowns().isOnCooldown(this)) {
return InteractionResultHolder.fail(stack);
}
// 射线追踪参数计算
Vec3 eyePos = player.getEyePosition(1.0F);
Vec3 viewVec = player.getViewVector(1.0F);
Vec3 endVec = eyePos.add(viewVec.x * 32D, viewVec.y * 32D, viewVec.z * 32D);
AABB aabb = player.getBoundingBox().expandTowards(viewVec.scale(32D)).inflate(1.0D);
// 获取目标实体
EntityHitResult entityResult = ProjectileUtil.getEntityHitResult(
world, player, eyePos, endVec, aabb,
entity -> entity instanceof LivingEntity && entity != player
);
if (entityResult != null) {
Entity target = entityResult.getEntity();
if (target instanceof LivingEntity) {
CustomFireball fireball = getCustomFireball(world, player);
Vec3 look = player.getLookAngle();
fireball.setPos(eyePos.add(look));
fireball.xPower = look.x * 0.5D;
fireball.yPower = look.y * 0.5D;
fireball.zPower = look.z * 0.5D;
world.addFreshEntity(fireball);
ServerLevel serverLevel = (ServerLevel) world;
// 添加冷却和粒子效果
player.getCooldowns().addCooldown(this, 60);
serverLevel.sendParticles(ParticleTypes.FLAME,
player.getX(), player.getY() + 1.0D, player.getZ(),
20, 0, 0, 0, 0.1D);
return InteractionResultHolder.success(stack);
}
}
return InteractionResultHolder.pass(stack);
}
private static @NotNull CustomFireball getCustomFireball(Level world, Player player) {
CustomFireball fireball = new CustomFireball(
world,
player,
player.getLookAngle().x * 0.1,
player.getLookAngle().y * 0.1,
player.getLookAngle().z * 0.1
);
// 设置火球初始位置
fireball.setPos(
player.getX() + player.getLookAngle().x,
player.getEyeY(),
player.getZ() + player.getLookAngle().z
);
return fireball;
}
}
解释:
这段代码定义了一个名为<