diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java
new file mode 100644
index 000000000..007b61d01
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java
@@ -0,0 +1,103 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an entity attempts to perform a smash attack.
+ */
+@NullMarked
+public class EntityAttemptSmashAttackEvent extends EntityEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final LivingEntity target;
+ private final ItemStack weapon;
+ private final boolean originalResult;
+ private Result result = Result.DEFAULT;
+
+ @ApiStatus.Internal
+ public EntityAttemptSmashAttackEvent(
+ final LivingEntity attacker,
+ final LivingEntity target,
+ final ItemStack weapon,
+ final boolean originalResult
+ ) {
+ super(attacker);
+ this.target = target;
+ this.weapon = weapon;
+ this.originalResult = originalResult;
+ }
+
+ /**
+ * Yields the target of the attempted smash attack.
+ *
+ * @return the target entity
+ */
+ public LivingEntity getTarget() {
+ return target;
+ }
+
+ /**
+ * Yields a copy of the itemstack used in the smash attack attempt.
+ *
+ * @return the itemstack
+ */
+ public ItemStack getWeapon() {
+ return weapon.clone();
+ }
+
+ /**
+ * Yields the original result the server computed.
+ *
+ * @return {@code true} if this attempt would have been successful by vanilla's logic, {@code false} otherwise.
+ */
+ public boolean getOriginalResult() {
+ return originalResult;
+ }
+
+ /**
+ * Yields the effective result of this event.
+ * The result may take one of three values:
+ *
+ *
+ * - {@link Result#ALLOW}: The attempt will succeed.
+ * - {@link Result#DENY}: The attempt will fail.
+ * - {@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.
+ *
+ *
+ * @return the result.
+ */
+ public Result getResult() {
+ return this.result;
+ }
+
+ /**
+ * Configures a new result for this event.
+ * The passes result may take one of three values:
+ *
+ *
+ * - {@link Result#ALLOW}: The attempt will succeed.
+ * - {@link Result#DENY}: The attempt will fail.
+ * - {@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.
+ *
+ *
+ * @param result the new result of the event.
+ */
+ public void setResult(final Result result) {
+ this.result = result;
+ }
+
+ @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/MaceItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch
new file mode 100644
index 000000000..cfeffcdd8
--- /dev/null
+++ b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch
@@ -0,0 +1,17 @@
+--- a/net/minecraft/world/item/MaceItem.java
++++ b/net/minecraft/world/item/MaceItem.java
+@@ -61,7 +_,13 @@
+
+ @Override
+ public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
+- if (canSmashAttack(attacker)) {
++ // Paper start - Add EntityAttemptSmashAttackEvent
++ final boolean canSmashAttack = canSmashAttack(attacker);
++ io.papermc.paper.event.entity.EntityAttemptSmashAttackEvent event = new io.papermc.paper.event.entity.EntityAttemptSmashAttackEvent(attacker.getBukkitLivingEntity(), target.getBukkitLivingEntity(), stack.asBukkitCopy(), canSmashAttack);
++ event.callEvent();
++ final org.bukkit.event.Event.Result result = event.getResult();
++ if (result == org.bukkit.event.Event.Result.ALLOW || (canSmashAttack && result == org.bukkit.event.Event.Result.DEFAULT)) {
++ // Paper end - Add EntityAttemptSmashAttackEvent
+ ServerLevel serverLevel = (ServerLevel)attacker.level();
+ attacker.setDeltaMovement(attacker.getDeltaMovement().with(Direction.Axis.Y, 0.01F));
+ if (attacker instanceof ServerPlayer serverPlayer) {