MineCraft 1.20.1 Module Development-(1)-Add the right-click to launch the withered skull and the additional floating effect of the attack to the Sapphire Sword

MineCraft 1.20.1 Module Development-(1)-Add right-click to launch withered skulls and attack additional floating effects for the Sapphire Sword

The following are all developed by Forge, written in JAVA, the IDE is IDEA, and the version is 1.20.1

function:
1. Realize that the sapphire sword (custom weapon) can be right-clicked to release the withered skull, which costs one point of durability and has a cooling time of 2 seconds.
2. Implement left-click attacks to add a 2s floating effect to the enemy

It can be implemented by imitating the erformRangedAttack function~~ and ShieldItem (implementing the cooling time)~~ in the WitherBoss class

First, let’s take a look at how to launch wither skeletons in the WitherBoss (Wither) class. You can enter WitherBoss and press ctrl to click to jump.

Similarly, we can use it in the right-click use method in the custom sword class by overriding the use method in the Item class. accomplish.

Specific steps:

  • In order to achieve the cooling time effect, you can view the coolDown related information in Player ->pPlayer.getCooldowns().addCooldown(this, 40);

  • In order to achieve the effect of launching skulls, first you need to get the target location. You can get the viewing angle through pPlayer.getLookAngle(). getLookAngle can Obtaining the angle of looking at the location is probably a vector in a three-dimensional coordinate system with xz as the plane and y as the vertical axis. Simply multiply the distance and the position to get the target position. Specifically You can look at the source code and use mathematics to solve it. Secondly is to summon the withered skeleton, which essentially generates an Entity object, so you only need to imitate the implementation in the WitherBoss class.Finally, you need to generate sound effects and reduce durability. For details, see the source code below.

Source code SapphireSword class

import xxx omitted

public class SapphireSword extends SwordItem implements Vanishable{<!-- -->

    public SapphireSword(Tier pTier, int pAttackDamageModifier, float pAttackSpeedModifier, Properties pProperties) {<!-- -->
        super(pTier, pAttackDamageModifier, pAttackSpeedModifier, pProperties);
    }

    @Override
    public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> pTooltipComponents, TooltipFlag pIsAdvanced) {<!-- -->
        pTooltipComponents.add(
                Component.literal("right click").withStyle(ChatFormatting.RESET).withStyle(ChatFormatting.LIGHT_PURPLE)
                        .append(Component.literal("Launch withered skull").withStyle(ChatFormatting.RESET)
                                .withStyle(ChatFormatting.DARK_GRAY).withStyle(ChatFormatting.BOLD)));
        pTooltipComponents.add(Component.literal("Cooling time 2s, consumption 1 durability")
                .withStyle(ChatFormatting.RESET).withStyle(ChatFormatting.AQUA));
        super.appendHoverText(pStack, pLevel, pTooltipComponents, pIsAdvanced);
    }


    //Right-click to release the withered skeleton. It costs one point of durability to use and the cooling time is 2s.
    // Can imitate the performRangedAttack function and ShieldItem (implementation of cooling time) in the WitherBoss class
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {<!-- -->
        if (!pLevel.isClientSide) {<!-- -->

            //Set cooling time
            pPlayer.getCooldowns().addCooldown(this, 40);

            pLevel.levelEvent((Player) null, 1024, pPlayer.blockPosition().above(2), 0);
            //Specify distance
            int distance = 20;
            //Get the target location
            //getLookAngle can get the angle of looking at the location, which is probably a vector in a three-dimensional coordinate system with xz as the plane and y as the vertical axis. It is directly multiplied by the distance and then added to the position.
            //The target position can be obtained. For details, you can look at the source code and use mathematics to solve it.
            double targetX = pPlayer.position().x + pPlayer.getLookAngle().x * distance;
            double targetz = pPlayer.position().z + pPlayer.getLookAngle().z * distance;
            double targety = pPlayer.position().y + pPlayer.getLookAngle().y * distance;
            //Get the position one grid in front of the eye (starting location)
            double eyePositionx = pPlayer.getEyePosition().x + pPlayer.getLookAngle().x * 1;
            double eyePositiony = pPlayer.getEyePosition().y + pPlayer.getLookAngle().y * 1;
            double eyePositionz = pPlayer.getEyePosition().z + pPlayer.getLookAngle().z * 1;
            //Offset
            double d3 = targetX - eyePositionx;
            double d4 = targety - eyePositiony;
            double d5 = targetz - eyePositionz;
            WitherSkull witherskull = new WitherSkull(pLevel, pPlayer, d3, d4, d5);
            witherskull.setOwner(pPlayer);

            witherskull.setPosRaw(eyePositionx, eyePositiony, eyePositionz);
            pLevel.addFreshEntity(witherskull);
            //Play sound
            pLevel.playSound((Player) null, pPlayer.getX(), pPlayer.getY(), pPlayer.getZ(), SoundEvents.WITHER_SHOOT,
                    SoundSource.PLAYERS, 1.0F, 1.0F);

            //Reduce durability
            ItemStack handItem;
            InteractionHand hand;
            if (pPlayer.getItemInHand(InteractionHand.MAIN_HAND).getItem() == ModItems.SAPPHIRE_SWORD.get()) {<!-- -->
                handItem = pPlayer.getItemInHand(InteractionHand.MAIN_HAND);
                hand = InteractionHand.MAIN_HAND;
            } else {<!-- -->
                handItem = pPlayer.getItemInHand(InteractionHand.OFF_HAND);
                hand = InteractionHand.OFF_HAND;
            }
            handItem.hurtAndBreak(1, pPlayer
                    , player1 -> player1.broadcastBreakEvent(hand));
        }

        return InteractionResultHolder.pass(pPlayer.getItemInHand(pUsedHand));
    }

    //Achieve additional floating effects for attacks
    @Override
    public boolean hurtEnemy(ItemStack pStack, LivingEntity pTarget, LivingEntity pAttacker) {<!-- -->
        pTarget.addEffect(new MobEffectInstance(MobEffects.LEVITATION,40));
        return super.hurtEnemy(pStack, pTarget, pAttacker);
    }
}


Implement function two: add floating effect
Just override the hurtEnemy method

 //Achieve additional floating effects for attacks
    @Override
    public boolean hurtEnemy(ItemStack pStack, LivingEntity pTarget, LivingEntity pAttacker) {<!-- -->
        pTarget.addEffect(new MobEffectInstance(MobEffects.LEVITATION,40));
        return super.hurtEnemy(pStack, pTarget, pAttacker);
    }
  • After completing the function editing, inject it into the ModItem class (no need to be the same, just like registering a normal item),

In-game display: