From bb397ba74c034ffe5ae164d774a043cb7bca0472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20P=C5=82a=C5=BCewski?= Date: Thu, 21 Oct 2021 00:15:28 +0200 Subject: [PATCH] Add critical damage API (#6275) --- .../api/0342-Add-critical-damage-API.patch | 51 ++++++ .../server/0832-Add-critical-damage-API.patch | 168 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 patches/api/0342-Add-critical-damage-API.patch create mode 100644 patches/server/0832-Add-critical-damage-API.patch diff --git a/patches/api/0342-Add-critical-damage-API.patch b/patches/api/0342-Add-critical-damage-API.patch new file mode 100644 index 000000000..3a9d1f807 --- /dev/null +++ b/patches/api/0342-Add-critical-damage-API.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: dodison +Date: Mon, 26 Jul 2021 17:35:20 +0200 +Subject: [PATCH] Add critical damage API + + +diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +index 869bad7405ec7fa67728e90d8b9f2e11b542611f..7ce8f1a26c1b33dd0eb6e6435952fd73abf49879 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +@@ -11,15 +11,40 @@ import org.jetbrains.annotations.NotNull; + public class EntityDamageByEntityEvent extends EntityDamageEvent { + private final Entity damager; + ++ @Deprecated // Paper - add critical damage API + public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) { + super(damagee, cause, damage); + this.damager = damager; ++ this.critical = false; // Paper - add critical damage API + } + ++ @Deprecated // Paper - add critical damage API + public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map modifiers, @NotNull final Map> modifierFunctions) { ++ // Paper start - add critical damage API ++ this(damager, damagee, cause, modifiers, modifierFunctions, false); ++ } ++ ++ private final boolean critical; ++ public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map modifiers, @NotNull final Map> modifierFunctions, boolean critical) { ++ // Paper end + super(damagee, cause, modifiers, modifierFunctions); + this.damager = damager; ++ // Paper start - add critical damage API ++ this.critical = critical; ++ } ++ ++ /** ++ * Shows this damage instance was critical. ++ * The damage instance can be critical if the attacking player met the respective conditions. ++ * Furthermore arrows may also cause a critical damage event if the arrow {@link org.bukkit.entity.AbstractArrow#isCritical()}. ++ * ++ * @return if the hit was critical. ++ * @see https://minecraft.fandom.com/wiki/Damage#Critical_hit ++ */ ++ public boolean isCritical() { ++ return this.critical; + } ++ // Paper end + + /** + * Returns the entity that damaged the defender. diff --git a/patches/server/0832-Add-critical-damage-API.patch b/patches/server/0832-Add-critical-damage-API.patch new file mode 100644 index 000000000..3e5730d1e --- /dev/null +++ b/patches/server/0832-Add-critical-damage-API.patch @@ -0,0 +1,168 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: dodison +Date: Mon, 26 Jul 2021 17:32:36 +0200 +Subject: [PATCH] Add critical damage API + + +diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java +index 80d19af2ad423bd3de0e039c5bb8f97af536aaa9..57bf7dba266b4df7b36bab2d58a609a1ce8948ef 100644 +--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java ++++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java +@@ -64,6 +64,19 @@ public class DamageSource { + return this; + } + // CraftBukkit end ++ // Paper start - add critical damage API ++ private boolean critical; ++ public boolean isCritcal() { ++ return this.critical; ++ } ++ public DamageSource critical() { ++ return this.critical(true); ++ } ++ public DamageSource critical(boolean critical) { ++ this.critical = critical; ++ return this; ++ } ++ // Paper end + + public static DamageSource sting(LivingEntity attacker) { + return new EntityDamageSource("sting", attacker); +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index 1018f4640bab5876c5e0afb5b88f71437fb79662..cbdff14b26f67b5040c13659f9d64d9ec4c7eaed 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -2571,15 +2571,27 @@ public abstract class LivingEntity extends Entity { + return this.hasEffect(MobEffects.JUMP) ? (double) (0.1F * (float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D; + } + ++ protected long lastJumpTime = 0L; // Paper - add critical damage API + protected void jumpFromGround() { + double d0 = (double) this.getJumpPower() + this.getJumpBoostPower(); + Vec3 vec3d = this.getDeltaMovement(); ++ // Paper start - add critical damage API ++ long time = System.nanoTime(); ++ boolean canCrit = true; ++ if (this instanceof net.minecraft.world.entity.player.Player) { ++ canCrit = false; ++ if (time - this.lastJumpTime > (long)(0.250e9)) { ++ this.lastJumpTime = time; ++ canCrit = true; ++ } ++ } ++ // Paper end - add critical damage API + + this.setDeltaMovement(vec3d.x, d0, vec3d.z); + if (this.isSprinting()) { + float f = this.getYRot() * 0.017453292F; + +- this.setDeltaMovement(this.getDeltaMovement().add((double) (-Mth.sin(f) * 0.2F), 0.0D, (double) (Mth.cos(f) * 0.2F))); ++ if (canCrit) this.setDeltaMovement(this.getDeltaMovement().add((double) (-Mth.sin(f) * 0.2F), 0.0D, (double) (Mth.cos(f) * 0.2F))); // Paper - add critical damage API + } + + this.hasImpulse = true; +diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java +index ce713e1857121ca52467ad561c4fbb30ae054d87..94e76e295dbd0f3bac4b30a3e7338cd56a971207 100644 +--- a/src/main/java/net/minecraft/world/entity/player/Player.java ++++ b/src/main/java/net/minecraft/world/entity/player/Player.java +@@ -1218,7 +1218,7 @@ public abstract class Player extends LivingEntity { + flag1 = true; + } + +- boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; ++ boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; // Paper - Add critical damage API - conflict on change + + flag2 = flag2 && !level.paperConfig.disablePlayerCrits; // Paper + flag2 = flag2 && !this.isSprinting(); +@@ -1258,7 +1258,7 @@ public abstract class Player extends LivingEntity { + } + + Vec3 vec3d = target.getDeltaMovement(); +- boolean flag5 = target.hurt(DamageSource.playerAttack(this), f); ++ boolean flag5 = target.hurt(DamageSource.playerAttack(this).critical(flag2), f); // Paper - add critical damage API + + if (flag5) { + if (i > 0) { +@@ -1286,7 +1286,7 @@ public abstract class Player extends LivingEntity { + + if (entityliving != this && entityliving != target && !this.isAlliedTo(entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) { + // CraftBukkit start - Only apply knockback if the damage hits +- if (entityliving.hurt(DamageSource.playerAttack(this).sweep(), f4)) { ++ if (entityliving.hurt(DamageSource.playerAttack(this).sweep().critical(flag2), f4)) { // Paper - add critical damage API + entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +index 6636845ea044c3810e1880aad8b679134cd33668..52e4948fd1657fa1776ac6b0142e8c21e7567976 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +@@ -381,6 +381,7 @@ public abstract class AbstractArrow extends Projectile { + } + } + ++ if (this.isCritArrow()) damagesource = damagesource.critical(); // Paper - add critical damage API + boolean flag = entity.getType() == EntityType.ENDERMAN; + int k = entity.getRemainingFireTicks(); + +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 2b2654ec04e8abca9db09d6257edf11099bb0d9b..771a00ae7f467660b0c39ffeee05281e114df378 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -964,7 +964,7 @@ public class CraftEventFactory { + } else { + damageCause = DamageCause.ENTITY_EXPLOSION; + } +- event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions); ++ event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions, source.isCritcal()); // Paper - add critical damage API + } + event.setCancelled(cancelled); + +@@ -989,7 +989,7 @@ public class CraftEventFactory { + cause = DamageCause.THORNS; + } + +- return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled); ++ return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled, source.isCritcal()); // Paper - add critical damage API + } else if (source == DamageSource.OUT_OF_WORLD) { + EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions); + event.setCancelled(cancelled); +@@ -1044,7 +1044,7 @@ public class CraftEventFactory { + } else { + throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, damager.getHandle(), source.msgId)); + } +- EntityDamageEvent event = new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions); ++ EntityDamageEvent event = new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions, source.isCritcal()); // Paper - add critical damage API + event.setCancelled(cancelled); + CraftEventFactory.callEvent(event); + if (!event.isCancelled()) { +@@ -1087,20 +1087,28 @@ public class CraftEventFactory { + } + + if (cause != null) { +- return CraftEventFactory.callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions, cancelled); ++ return CraftEventFactory.callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions, cancelled, source.isCritcal()); // Paper - add critical damage API + } + + throw new IllegalStateException(String.format("Unhandled damage of %s from %s", entity, source.msgId)); + } + ++ @Deprecated // Paper - Add critical damage API + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions) { + return CraftEventFactory.callEntityDamageEvent(damager, damagee, cause, modifiers, modifierFunctions, false); + } + ++ // Paper start - Add critical damage API ++ @Deprecated + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions, boolean cancelled) { ++ return CraftEventFactory.callEntityDamageEvent(damager, damagee, cause, modifiers, modifierFunctions, false, false); ++ } ++ ++ private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions, boolean cancelled, boolean critical) { ++ // Paper end + EntityDamageEvent event; + if (damager != null) { +- event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); ++ event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions, critical); // Paper - add critical damage API + } else { + event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); + }