diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLungeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLungeEvent.java new file mode 100644 index 000000000000..45ba8972fc3e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLungeEvent.java @@ -0,0 +1,69 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a living entity tries to lunge with a spear + */ +@NullMarked +public class EntityLungeEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private int lungePower; + private boolean cancelled; + + @ApiStatus.Internal + public EntityLungeEvent(final LivingEntity entity, int lungePower) { + super(entity); + this.lungePower = lungePower; + } + + /** + * Gets the lunge power, which when initially passed, matches the enchantment level of the item, but can be higher. + * + * @return the lunge power + */ + public int getLungePower() { + return lungePower; + } + + /** + * Sets the lunge power. This commonly matches the enchantment level of the item, and can be set higher. + *
+ * If set higher than 3, the power of the lunge will continue to scale like normal, as if the max enchantment + * level is higher. + * @param lungePower the new lunge power + */ + public void setLungePower(final int lungePower) { + this.lungePower = lungePower; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * Set whether to cancel the lunge. If cancelled, the living entity will not lunge forward. + * @param cancel {@code true} if you wish to cancel this event + */ + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/item/enchantment/Enchantment.java.patch b/paper-server/patches/sources/net/minecraft/world/item/enchantment/Enchantment.java.patch new file mode 100644 index 000000000000..b96baf3f764e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/enchantment/Enchantment.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/item/enchantment/Enchantment.java ++++ b/net/minecraft/world/item/enchantment/Enchantment.java +@@ -317,7 +_,18 @@ + applyEffects( + this.getEffects(EnchantmentEffectComponents.POST_PIERCING_ATTACK), + entityContext(level, enchantmentLevel, entity, entity.position()), +- enchantmentEntityEffect -> enchantmentEntityEffect.apply(level, enchantmentLevel, item, entity, entity.position()) ++ // Paper start - EntityLungeEvent ++ enchantmentEntityEffect -> { ++ io.papermc.paper.event.entity.EntityLungeEvent entityLungeEvent = new io.papermc.paper.event.entity.EntityLungeEvent( ++ entity.asLivingEntity().getBukkitLivingEntity(), enchantmentLevel ++ ); ++ if (!entityLungeEvent.callEvent()) { ++ // event was canceled ++ return; ++ } ++ enchantmentEntityEffect.apply(level, entityLungeEvent.getLungePower(), item, entity, entity.position()); ++ } ++ // Paper end - EntityLungeEvent + ); + } +