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 anEntity
object, so you only need to imitate the implementation in theWitherBoss
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: