Skip to content

Add Critical hit API #12319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.papermc.paper.event.player;

import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;

/**
* Event, that is fired when it is decided whether Player attack will be a critical hit or not.
* It will be fired cancelled when the hit will not be a critical hit. When cancelled, the hit won't be critical.
*/
@NullMarked
public class PlayerCriticalHitEntityEvent extends PlayerEvent implements Cancellable {

private static final HandlerList HANDLER_LIST = new HandlerList();

private final Entity attacked;
private float multiplier;

private boolean cancelled;

@ApiStatus.Internal
public PlayerCriticalHitEntityEvent(final Player who, final Entity attacked, final float multiplier, final boolean critical) {
super(who);
this.attacked = attacked;
this.multiplier = multiplier;
this.cancelled = !critical;
}

/**
* Gets the entity that was attacked in this event.
*
* @return entity that was attacked
*/
public Entity getAttacked() {
return attacked;
}

/**
* Gets a multiplier by which the damage will be multiplied when the hit is critical.
*
* @return critical hit damage multiplier
*/
public float getMultiplier() {
return multiplier;
}

/**
* Sets a multiplier by which the damage will be multiplied if the hit is critical
*
* @param multiplier critical hit damage multiplier
*/
public void setMultiplier(final float multiplier) {
this.multiplier = multiplier;
}

@Override
public boolean isCancelled() {
return cancelled;
}

@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}

@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27496,7 +27496,7 @@ index d1f235ebd835f58cf0c703c3a64d29825d98e183..080091efc19bc768bb9a660f366c42e8
}

diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index f054ea710108e5017bc48fdda5f180a04f5b55e2..f44600604a7bf68c990cd74a1ac2d7900ff6e88e 100644
index 0bb610f12e3ddda649ecb5ad62ffdc7bfd243223..19428343b37c9b739b3d28984d52e257f85f253f 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team;
Expand All @@ -27508,7 +27508,7 @@ index f054ea710108e5017bc48fdda5f180a04f5b55e2..f44600604a7bf68c990cd74a1ac2d790
private static final Logger LOGGER = LogUtils.getLogger();
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
@@ -388,6 +388,36 @@ public class ServerPlayer extends Player {
@@ -395,6 +395,36 @@ public class ServerPlayer extends Player {
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ index 87d4291a3944f706a694536da6de0f28c548ab8d..5576bf1d1d70ab7a010653d3207909b5
profiler.popPush("spawnAndTick");
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 1fe212e8584c177b49e83f29b1a869b534914348..cd6b5176f34248f844f0e591875701bd08f455ce 100644
index 02fb30a3adf92de0795aee213caf94a228b01ca0..67f6e40216e0be063a3cfb61427f095f7c74d785 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -368,6 +368,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -375,6 +375,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public boolean queueHealthUpdatePacket;
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
// Paper end - cancellable death event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ index 5576bf1d1d70ab7a010653d3207909b5de867e70..6540b2d6a1062d883811ce240c49d30d
spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true);
} else {
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index cd6b5176f34248f844f0e591875701bd08f455ce..f347ff8d863f4bcef46604c757de112cb3fe445c 100644
index 67f6e40216e0be063a3cfb61427f095f7c74d785..3de65c4025be91d938a350c884975cb6edc234d3 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -372,6 +372,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -379,6 +379,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length;
public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS];
// Paper end - Optional per player mob spawns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,22 @@
flag1 = true;
} else {
flag1 = false;
@@ -1161,7 +_,9 @@
@@ -1161,8 +_,14 @@
&& !this.isPassenger()
&& target instanceof LivingEntity
&& !this.isSprinting();
+ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
+ // Paper start - Critical hit API
+ io.papermc.paper.event.player.PlayerCriticalHitEntityEvent crit = new io.papermc.paper.event.player.PlayerCriticalHitEntityEvent((org.bukkit.entity.Player) this.getBukkitEntity(), target.getBukkitEntity(), 1.5F, flag2);
+ flag2 = crit.callEvent();
+ // Paper end - Critical hit API
if (flag2) {
- f *= 1.5F;
+ damageSource = damageSource.critical(); // Paper - critical damage API
f *= 1.5F;
+ f *= crit.getMultiplier(); // Paper - Critical hit API
}

float f2 = f + f1;
@@ -1188,17 +_,23 @@
if (target instanceof LivingEntity livingEntity1) {
livingEntity1.knockback(
Expand Down
Loading