Add entity knockback events

- EntityKnockbackEvent
- EntityPushedByEntityAttackEvent
- EntityKnockbackByEntityEvent

Co-authored-by: aerulion <aerulion@gmail.com>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
This commit is contained in:
Brokkonaut 2018-06-18 15:46:23 +02:00
parent d68fcd321f
commit 991875920d
16 changed files with 356 additions and 180 deletions

View file

@ -205,12 +205,12 @@
+ this.origin = location.toVector();
+ this.originWorld = location.getWorld().getUID();
+ }
+
+ @javax.annotation.Nullable
+ public org.bukkit.util.Vector getOriginVector() {
+ return this.origin != null ? this.origin.clone() : null;
+ }
+
+ @javax.annotation.Nullable
+ public UUID getOriginWorld() {
+ return this.originWorld;
@ -265,7 +265,7 @@
datawatcher_a.define(Entity.DATA_TICKS_FROZEN, 0);
this.defineSynchedData(datawatcher_a);
this.entityData = datawatcher_a.build();
@@ -362,19 +557,35 @@
@@ -362,20 +557,36 @@
}
public void kill(ServerLevel world) {
@ -290,7 +290,7 @@
public SynchedEntityData getEntityData() {
return this.entityData;
}
+
+ // CraftBukkit start
+ public void refreshEntityData(ServerPlayer to) {
+ List<SynchedEntityData.DataValue<?>> list = this.getEntityData().getNonDefaultValues();
@ -300,9 +300,10 @@
+ }
+ }
+ // CraftBukkit end
+
public boolean equals(Object object) {
return object instanceof Entity ? ((Entity) object).id == this.id : false;
}
@@ -385,22 +596,34 @@
}
@ -310,13 +311,13 @@
- this.setRemoved(reason);
+ // CraftBukkit start - add Bukkit remove cause
+ this.setRemoved(reason, null);
}
+ }
+
+ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) {
+ this.setRemoved(entity_removalreason, cause);
+ // CraftBukkit end
+ }
+
}
public void onClientRemoval() {}
public void onRemoval(Entity.RemovalReason reason) {}
@ -506,10 +507,13 @@
}
public boolean isFree(double offsetX, double offsetY, double offsetZ) {
@@ -750,6 +1050,28 @@
}
}
@@ -747,8 +1047,30 @@
if (movement.y != vec3d1.y) {
block.updateEntityMovementAfterFallOn(this.level(), this);
+ }
+ }
+
+ // CraftBukkit start
+ if (this.horizontalCollision && this.getBukkitEntity() instanceof Vehicle) {
+ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
@ -528,13 +532,12 @@
+ if (!bl.getType().isAir()) {
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
+ this.level.getCraftServer().getPluginManager().callEvent(event);
+ }
+ }
}
}
+ // CraftBukkit end
+
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
Entity.MovementEmission entity_movementemission = this.getMovementEmission();
@@ -1131,7 +1453,21 @@
protected SoundEvent getSwimHighSpeedSplashSound() {
@ -548,11 +551,11 @@
+
+ public SoundEvent getSwimSplashSound0() {
+ return this.getSwimSplashSound();
}
+ }
+
+ public SoundEvent getSwimHighSpeedSplashSound0() {
+ return this.getSwimHighSpeedSplashSound();
+ }
}
+ // CraftBukkit end
public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) {
@ -565,7 +568,30 @@
}
public void moveTo(Vec3 pos) {
@@ -1861,6 +2198,12 @@
@@ -1737,7 +2074,21 @@
}
public void push(double deltaX, double deltaY, double deltaZ) {
- this.setDeltaMovement(this.getDeltaMovement().add(deltaX, deltaY, deltaZ));
+ // Paper start - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
+ this.push(deltaX, deltaY, deltaZ, null);
+ }
+
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) {
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(deltaX, deltaY, deltaZ);
+ if (pushingEntity != null) {
+ io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent event = new io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.PUSH, pushingEntity.getBukkitEntity(), delta);
+ if (!event.callEvent()) {
+ return;
+ }
+ delta = event.getKnockback();
+ }
+ this.setDeltaMovement(this.getDeltaMovement().add(delta.getX(), delta.getY(), delta.getZ()));
+ // Paper end - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
this.hasImpulse = true;
}
@@ -1861,6 +2212,12 @@
return false;
}
@ -578,7 +604,7 @@
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
if (entityKilled instanceof ServerPlayer) {
CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource);
@@ -1889,16 +2232,22 @@
@@ -1889,16 +2246,22 @@
}
public boolean saveAsPassenger(CompoundTag nbt) {
@ -604,7 +630,7 @@
return true;
}
}
@@ -1909,54 +2258,98 @@
@@ -1909,54 +2272,98 @@
}
public CompoundTag saveWithoutId(CompoundTag nbt) {
@ -723,7 +749,7 @@
}
ListTag nbttaglist;
@@ -1972,10 +2365,10 @@
@@ -1972,10 +2379,10 @@
nbttaglist.add(StringTag.valueOf(s));
}
@ -736,7 +762,7 @@
if (this.isVehicle()) {
nbttaglist = new ListTag();
iterator = this.getPassengers().iterator();
@@ -1984,17 +2377,35 @@
@@ -1984,17 +2391,35 @@
Entity entity = (Entity) iterator.next();
CompoundTag nbttagcompound1 = new CompoundTag();
@ -775,7 +801,7 @@
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved");
@@ -2080,6 +2491,66 @@
@@ -2080,6 +2505,66 @@
} else {
throw new IllegalStateException("Entity has invalid position");
}
@ -842,7 +868,7 @@
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded");
@@ -2101,6 +2572,12 @@
@@ -2101,6 +2586,12 @@
return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null;
}
@ -855,7 +881,7 @@
protected abstract void readAdditionalSaveData(CompoundTag nbt);
protected abstract void addAdditionalSaveData(CompoundTag nbt);
@@ -2153,9 +2630,22 @@
@@ -2153,9 +2644,22 @@
if (stack.isEmpty()) {
return null;
} else {
@ -878,7 +904,7 @@
world.addFreshEntity(entityitem);
return entityitem;
}
@@ -2184,6 +2674,12 @@
@@ -2184,6 +2688,12 @@
if (this.isAlive() && this instanceof Leashable leashable) {
if (leashable.getLeashHolder() == player) {
if (!this.level().isClientSide()) {
@ -891,7 +917,7 @@
if (player.hasInfiniteMaterials()) {
leashable.removeLeash();
} else {
@@ -2200,6 +2696,13 @@
@@ -2200,6 +2710,13 @@
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
if (!this.level().isClientSide()) {
@ -905,7 +931,7 @@
leashable.setLeashedTo(player, true);
}
@@ -2265,7 +2768,7 @@
@@ -2265,7 +2782,7 @@
}
public boolean showVehicleHealth() {
@ -914,7 +940,7 @@
}
public boolean startRiding(Entity entity, boolean force) {
@@ -2273,7 +2776,7 @@
@@ -2273,7 +2790,7 @@
return false;
} else if (!entity.couldAcceptPassenger()) {
return false;
@ -923,7 +949,7 @@
return false;
} else {
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
@@ -2285,11 +2788,32 @@
@@ -2285,11 +2802,32 @@
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
return false;
} else {
@ -957,7 +983,7 @@
this.vehicle = entity;
this.vehicle.addPassenger(this);
entity.getIndirectPassengersStream().filter((entity2) -> {
@@ -2318,7 +2842,7 @@
@@ -2318,7 +2856,7 @@
Entity entity = this.vehicle;
this.vehicle = null;
@ -966,7 +992,7 @@
}
}
@@ -2349,21 +2873,50 @@
@@ -2349,21 +2887,50 @@
}
}
@ -1023,7 +1049,7 @@
}
protected boolean canAddPassenger(Entity passenger) {
@@ -2464,7 +3017,7 @@
@@ -2464,7 +3031,7 @@
if (teleporttransition != null) {
ServerLevel worldserver1 = teleporttransition.newLevel();
@ -1032,7 +1058,7 @@
this.teleport(teleporttransition);
}
}
@@ -2547,7 +3100,7 @@
@@ -2547,7 +3114,7 @@
}
public boolean isCrouching() {
@ -1041,7 +1067,7 @@
}
public boolean isSprinting() {
@@ -2563,7 +3116,7 @@
@@ -2563,7 +3130,7 @@
}
public boolean isVisuallySwimming() {
@ -1050,7 +1076,7 @@
}
public boolean isVisuallyCrawling() {
@@ -2571,6 +3124,13 @@
@@ -2571,6 +3138,13 @@
}
public void setSwimming(boolean swimming) {
@ -1064,7 +1090,7 @@
this.setSharedFlag(4, swimming);
}
@@ -2609,6 +3169,7 @@
@@ -2609,6 +3183,7 @@
@Nullable
public PlayerTeam getTeam() {
@ -1072,7 +1098,7 @@
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
}
@@ -2624,8 +3185,12 @@
@@ -2624,8 +3199,12 @@
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
}
@ -1086,7 +1112,7 @@
}
public boolean getSharedFlag(int index) {
@@ -2644,7 +3209,7 @@
@@ -2644,7 +3223,7 @@
}
public int getMaxAirSupply() {
@ -1095,7 +1121,7 @@
}
public int getAirSupply() {
@@ -2652,7 +3217,18 @@
@@ -2652,7 +3231,18 @@
}
public void setAirSupply(int air) {
@ -1115,7 +1141,7 @@
}
public int getTicksFrozen() {
@@ -2679,11 +3255,40 @@
@@ -2679,11 +3269,40 @@
public void thunderHit(ServerLevel world, LightningBolt lightning) {
this.setRemainingFireTicks(this.remainingFireTicks + 1);
@ -1158,7 +1184,7 @@
}
public void onAboveBubbleCol(boolean drag) {
@@ -2713,7 +3318,7 @@
@@ -2713,7 +3332,7 @@
this.resetFallDistance();
}
@ -1167,7 +1193,7 @@
return true;
}
@@ -2852,6 +3457,26 @@
@@ -2852,6 +3471,26 @@
if (world instanceof ServerLevel worldserver) {
if (!this.isRemoved()) {
@ -1194,7 +1220,7 @@
ServerLevel worldserver1 = teleportTarget.newLevel();
boolean flag = worldserver1.dimension() != worldserver.dimension();
@@ -2920,8 +3545,12 @@
@@ -2920,8 +3559,12 @@
} else {
entity.restoreFrom(this);
this.removeAfterChangingDimensions();
@ -1208,7 +1234,7 @@
Iterator iterator1 = list1.iterator();
while (iterator1.hasNext()) {
@@ -2947,7 +3576,7 @@
@@ -2947,7 +3590,7 @@
}
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
@ -1217,7 +1243,7 @@
Iterator iterator = this.getIndirectPassengers().iterator();
while (iterator.hasNext()) {
@@ -2995,8 +3624,9 @@
@@ -2995,8 +3638,9 @@
}
protected void removeAfterChangingDimensions() {
@ -1228,7 +1254,7 @@
leashable.removeLeash();
}
@@ -3004,7 +3634,21 @@
@@ -3004,7 +3648,21 @@
public Vec3 getRelativePortalPosition(Direction.Axis portalAxis, BlockUtil.FoundRectangle portalRect) {
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
@ -1250,7 +1276,7 @@
public boolean canUsePortal(boolean allowVehicles) {
return (allowVehicles || !this.isPassenger()) && this.isAlive();
@@ -3134,9 +3778,15 @@
@@ -3134,10 +3792,16 @@
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
}
@ -1261,15 +1287,16 @@
+ public final boolean teleportTo(ServerLevel world, double destX, double destY, double destZ, Set<Relative> flags, float yaw, float pitch, boolean resetCamera) {
+ return this.teleportTo(world, destX, destY, destZ, flags, yaw, pitch, resetCamera, PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+
+ public boolean teleportTo(ServerLevel worldserver, double d0, double d1, double d2, Set<Relative> set, float f, float f1, boolean flag, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
+ float f2 = Mth.clamp(f1, -90.0F, 90.0F);
+ Entity entity = this.teleport(new TeleportTransition(worldserver, new Vec3(d0, d1, d2), Vec3.ZERO, f, f2, set, TeleportTransition.DO_NOTHING, cause));
+ // CraftBukkit end
+
return entity != null;
}
@@ -3187,7 +3837,7 @@
@@ -3187,7 +3851,7 @@
/** @deprecated */
@Deprecated
protected void fixupDimensions() {
@ -1278,7 +1305,7 @@
EntityDimensions entitysize = this.getDimensions(entitypose);
this.dimensions = entitysize;
@@ -3196,7 +3846,7 @@
@@ -3196,7 +3860,7 @@
public void refreshDimensions() {
EntityDimensions entitysize = this.dimensions;
@ -1287,7 +1314,7 @@
EntityDimensions entitysize1 = this.getDimensions(entitypose);
this.dimensions = entitysize1;
@@ -3258,10 +3908,29 @@
@@ -3258,10 +3922,29 @@
}
public final void setBoundingBox(AABB boundingBox) {
@ -1319,7 +1346,7 @@
return this.getDimensions(pose).eyeHeight();
}
@@ -3335,7 +4004,7 @@
@@ -3335,7 +4018,7 @@
}
@Nullable
@ -1328,7 +1355,7 @@
return null;
}
@@ -3435,7 +4104,7 @@
@@ -3435,7 +4118,7 @@
}
public boolean isControlledByLocalInstance() {
@ -1337,7 +1364,7 @@
if (entityliving instanceof Player entityhuman) {
return entityhuman.isLocalPlayer();
@@ -3445,7 +4114,7 @@
@@ -3445,7 +4128,7 @@
}
public boolean isControlledByClient() {
@ -1346,7 +1373,7 @@
return entityliving != null && entityliving.isControlledByClient();
}
@@ -3463,7 +4132,7 @@
@@ -3463,7 +4146,7 @@
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
}
@ -1355,7 +1382,7 @@
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
}
@@ -3488,9 +4157,38 @@
@@ -3488,9 +4171,38 @@
public int getFireImmuneTicks() {
return 1;
}
@ -1395,20 +1422,19 @@
}
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
@@ -3550,7 +4248,12 @@
@@ -3551,6 +4263,11 @@
vec3d = vec3d.add(vec3d1);
++k1;
+ }
}
+ // CraftBukkit start - store last lava contact location
+ if (tag == FluidTags.LAVA) {
+ this.lastLavaContact = blockposition_mutableblockposition.immutable();
}
+ }
+ // CraftBukkit end
}
}
}
@@ -3613,7 +4316,7 @@
@@ -3613,7 +4330,7 @@
return new ClientboundAddEntityPacket(this, entityTrackerEntry);
}
@ -1417,7 +1443,7 @@
return this.type.getDimensions();
}
@@ -3818,8 +4521,16 @@
@@ -3818,8 +4535,16 @@
@Override
public final void setRemoved(Entity.RemovalReason reason) {
@ -1435,7 +1461,7 @@
}
if (this.removalReason.shouldDestroy()) {
@@ -3827,8 +4538,8 @@
@@ -3827,8 +4552,8 @@
}
this.getPassengers().forEach(Entity::stopRiding);
@ -1446,7 +1472,7 @@
}
public void unsetRemoved() {
@@ -3887,7 +4598,7 @@
@@ -3887,7 +4612,7 @@
}
public Vec3 getKnownMovement() {

View file

@ -161,23 +161,24 @@
}
public void onEquipItem(EquipmentSlot slot, ItemStack oldStack, ItemStack newStack) {
- if (!this.level().isClientSide() && !this.isSpectator()) {
- boolean flag = newStack.isEmpty() && oldStack.isEmpty();
+ // CraftBukkit start
+ this.onEquipItem(slot, oldStack, newStack, false);
+ }
+
+ public void onEquipItem(EquipmentSlot enumitemslot, ItemStack itemstack, ItemStack itemstack1, boolean silent) {
+ // CraftBukkit end
if (!this.level().isClientSide() && !this.isSpectator()) {
- boolean flag = newStack.isEmpty() && oldStack.isEmpty();
+ boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
- if (!flag && !ItemStack.isSameItemSameComponents(oldStack, newStack) && !this.firstTick) {
- Equippable equippable = (Equippable) newStack.get(DataComponents.EQUIPPABLE);
+ if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
+ Equippable equippable = (Equippable) itemstack1.get(DataComponents.EQUIPPABLE);
+ public void onEquipItem(EquipmentSlot enumitemslot, ItemStack itemstack, ItemStack itemstack1, boolean silent) {
+ // CraftBukkit end
+ if (!this.level().isClientSide() && !this.isSpectator()) {
+ boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
- if (!this.isSilent() && equippable != null && slot == equippable.slot()) {
- this.level().playSeededSound((Player) null, this.getX(), this.getY(), this.getZ(), equippable.equipSound(), this.getSoundSource(), 1.0F, 1.0F, this.random.nextLong());
+ if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
+ Equippable equippable = (Equippable) itemstack1.get(DataComponents.EQUIPPABLE);
+
+ if (!this.isSilent() && equippable != null && enumitemslot == equippable.slot() && !silent) { // CraftBukkit
+ this.level().playSeededSound((net.minecraft.world.entity.player.Player) null, this.getX(), this.getY(), this.getZ(), equippable.equipSound(), this.getSoundSource(), 1.0F, 1.0F, this.random.nextLong());
}
@ -238,10 +239,13 @@
if (nbt.contains("attributes", 9) && this.level() != null && !this.level().isClientSide) {
this.getAttributes().load(nbt.getList("attributes", 10));
}
@@ -781,6 +855,17 @@
}
}
@@ -778,8 +852,19 @@
if (mobeffect != null) {
this.activeEffects.put(mobeffect.getEffect(), mobeffect);
}
+ }
+ }
+
+ // CraftBukkit start
+ if (nbt.contains("Bukkit.MaxHealth")) {
+ Tag nbtbase = nbt.get("Bukkit.MaxHealth");
@ -249,13 +253,12 @@
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((FloatTag) nbtbase).getAsDouble());
+ } else if (nbtbase.getId() == 3) {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((IntTag) nbtbase).getAsDouble());
+ }
+ }
}
}
+ // CraftBukkit end
+
if (nbt.contains("Health", 99)) {
this.setHealth(nbt.getFloat("Health"));
}
@@ -792,6 +877,7 @@
String s = nbt.getString("Team");
Scoreboard scoreboard = this.level().getScoreboard();
@ -651,7 +654,7 @@
}
- this.knockback(0.4000000059604645D, d0, d1);
+ this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? EntityKnockbackEvent.KnockbackCause.DAMAGE : EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
+ this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
if (!flag) {
this.indicateDamage(d0, d1);
}
@ -693,7 +696,7 @@
protected void blockedByShield(LivingEntity target) {
- target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ());
+ target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), null, EntityKnockbackEvent.KnockbackCause.SHIELD_BLOCK); // CraftBukkit
+ target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.SHIELD_BLOCK); // CraftBukkit // Paper - fix attacker & knockback events
}
private boolean checkTotemDeathProtection(DamageSource source) {
@ -813,7 +816,7 @@
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {}
public long getLootTableSeed() {
@@ -1612,19 +1916,31 @@
@@ -1612,19 +1916,35 @@
}
public void knockback(double strength, double x, double z) {
@ -821,10 +824,10 @@
- if (strength > 0.0D) {
- this.hasImpulse = true;
+ // CraftBukkit start - EntityKnockbackEvent
+ this.knockback(strength, x, z, null, EntityKnockbackEvent.KnockbackCause.UNKNOWN);
+ this.knockback(strength, x, z, null, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.UNKNOWN); // Paper - knockback events
+ }
+
+ public void knockback(double d0, double d1, double d2, Entity attacker, EntityKnockbackEvent.KnockbackCause cause) {
+ public void knockback(double d0, double d1, double d2, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause) { // Paper - knockback events
+ d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
+ if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0
+ //this.hasImpulse = true; // CraftBukkit - Move down
@ -841,23 +844,25 @@
+ Vec3 vec3d1 = (new Vec3(d1, 0.0D, d2)).normalize().scale(d0);
- this.setDeltaMovement(vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + strength) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
+ EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, cause, d0, vec3d1, vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + d0) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
+ // Paper start - knockback events
+ Vec3 finalVelocity = new Vec3(vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + d0) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
+ Vec3 diff = finalVelocity.subtract(vec3d);
+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, attacker, cause, d0, diff);
+ // Paper end - knockback events
+ if (event.isCancelled()) {
+ return;
+ }
+
+ this.hasImpulse = true;
+ this.setDeltaMovement(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ());
+ this.setDeltaMovement(vec3d.add(event.getKnockback().getX(), event.getKnockback().getY(), event.getKnockback().getZ())); // Paper - knockback events
+ // CraftBukkit end
}
}
@@ -1681,8 +1997,22 @@
public LivingEntity.Fallsounds getFallSounds() {
@@ -1683,6 +2003,20 @@
return new LivingEntity.Fallsounds(SoundEvents.GENERIC_SMALL_FALL, SoundEvents.GENERIC_BIG_FALL);
+ }
+
}
+ // CraftBukkit start - Add delegate methods
+ public SoundEvent getHurtSound0(DamageSource damagesource) {
+ return this.getHurtSound(damagesource);
@ -865,8 +870,8 @@
+
+ public SoundEvent getDeathSound0() {
+ return this.getDeathSound();
}
+ }
+
+ public SoundEvent getFallDamageSound0(int fallHeight) {
+ return this.getFallDamageSound(fallHeight);
+ }
@ -875,7 +880,7 @@
public Optional<BlockPos> getLastClimbablePos() {
return this.lastClimbablePos;
}
@@ -1757,9 +2087,14 @@
@@ -1757,9 +2091,14 @@
int i = this.calculateFallDamage(fallDistance, damageMultiplier);
if (i > 0) {
@ -891,7 +896,7 @@
return true;
} else {
return flag;
@@ -1830,7 +2165,7 @@
@@ -1830,7 +2169,7 @@
protected float getDamageAfterArmorAbsorb(DamageSource source, float amount) {
if (!source.is(DamageTypeTags.BYPASSES_ARMOR)) {
@ -900,7 +905,7 @@
amount = CombatRules.getDamageAfterAbsorb(this, amount, source, (float) this.getArmorValue(), (float) this.getAttributeValue(Attributes.ARMOR_TOUGHNESS));
}
@@ -1841,7 +2176,8 @@
@@ -1841,7 +2180,8 @@
if (source.is(DamageTypeTags.BYPASSES_EFFECTS)) {
return amount;
} else {
@ -910,7 +915,7 @@
int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
int j = 25 - i;
float f1 = amount * (float) j;
@@ -1884,18 +2220,144 @@
@@ -1884,18 +2224,144 @@
}
}
@ -922,10 +927,7 @@
+ // CraftBukkit start
+ private EntityDamageEvent handleEntityDamage(final DamageSource damagesource, float f) {
+ float originalDamage = f;
- amount = Math.max(amount - this.getAbsorptionAmount(), 0.0F);
- this.setAbsorptionAmount(this.getAbsorptionAmount() - (f1 - amount));
- float f2 = f1 - amount;
+
+ com.google.common.base.Function<Double, Double> freezing = new com.google.common.base.Function<Double, Double>() {
+ @Override
+ public Double apply(Double f) {
@ -937,7 +939,10 @@
+ };
+ float freezingModifier = freezing.apply((double) f).floatValue();
+ f += freezingModifier;
+
- amount = Math.max(amount - this.getAbsorptionAmount(), 0.0F);
- this.setAbsorptionAmount(this.getAbsorptionAmount() - (f1 - amount));
- float f2 = f1 - amount;
+ com.google.common.base.Function<Double, Double> hardHat = new com.google.common.base.Function<Double, Double>() {
+ @Override
+ public Double apply(Double f) {
@ -949,7 +954,7 @@
+ };
+ float hardHatModifier = hardHat.apply((double) f).floatValue();
+ f += hardHatModifier;
+
+ com.google.common.base.Function<Double, Double> blocking = new com.google.common.base.Function<Double, Double>() {
+ @Override
+ public Double apply(Double f) {
@ -983,7 +988,7 @@
+ };
+ float resistanceModifier = resistance.apply((double) f).floatValue();
+ f += resistanceModifier;
+
+ com.google.common.base.Function<Double, Double> magic = new com.google.common.base.Function<Double, Double>() {
+ @Override
+ public Double apply(Double f) {
@ -1064,7 +1069,7 @@
if (entity instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entity;
@@ -1904,13 +2366,48 @@
@@ -1904,13 +2370,48 @@
}
}
@ -1117,27 +1122,28 @@
}
public CombatTracker getCombatTracker() {
@@ -1935,8 +2432,18 @@
@@ -1935,9 +2436,19 @@
}
public final void setArrowCount(int stuckArrowCount) {
- this.entityData.set(LivingEntity.DATA_ARROW_COUNT_ID, stuckArrowCount);
+ // CraftBukkit start
+ this.setArrowCount(stuckArrowCount, false);
+ }
+
}
+ public final void setArrowCount(int i, boolean flag) {
+ ArrowBodyCountChangeEvent event = CraftEventFactory.callArrowBodyCountChangeEvent(this, this.getArrowCount(), i, flag);
+ if (event.isCancelled()) {
+ return;
+ }
+ this.entityData.set(LivingEntity.DATA_ARROW_COUNT_ID, event.getNewAmount());
}
+ }
+ // CraftBukkit end
+
public final int getStingerCount() {
return (Integer) this.entityData.get(LivingEntity.DATA_STINGER_COUNT_ID);
@@ -1999,7 +2506,7 @@
}
@@ -1999,7 +2510,7 @@
this.playSound(soundeffect, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
}
@ -1146,7 +1152,7 @@
this.setHealth(0.0F);
this.die(this.damageSources().generic());
}
@@ -2182,6 +2689,12 @@
@@ -2182,6 +2693,12 @@
public abstract ItemStack getItemBySlot(EquipmentSlot slot);
@ -1159,7 +1165,7 @@
public abstract void setItemSlot(EquipmentSlot slot, ItemStack stack);
public Iterable<ItemStack> getHandSlots() {
@@ -2494,7 +3007,7 @@
@@ -2494,7 +3011,7 @@
}
@ -1168,7 +1174,7 @@
Vec3 vec3d1 = this.getRiddenInput(controllingPlayer, movementInput);
this.tickRidden(controllingPlayer, vec3d1);
@@ -2507,13 +3020,13 @@
@@ -2507,13 +3024,13 @@
}
@ -1185,7 +1191,7 @@
return this.getSpeed();
}
@@ -2571,7 +3084,7 @@
@@ -2571,7 +3088,7 @@
double d1 = Mth.clamp(motion.z, -0.15000000596046448D, 0.15000000596046448D);
double d2 = Math.max(motion.y, -0.15000000596046448D);
@ -1194,7 +1200,7 @@
d2 = 0.0D;
}
@@ -2586,7 +3099,7 @@
@@ -2586,7 +3103,7 @@
}
protected float getFlyingSpeed() {
@ -1203,7 +1209,7 @@
}
public float getSpeed() {
@@ -2634,7 +3147,7 @@
@@ -2634,7 +3151,7 @@
}
}
@ -1212,7 +1218,7 @@
if (this.tickCount % 20 == 0) {
this.getCombatTracker().recheckStatus();
}
@@ -2741,7 +3254,7 @@
@@ -2741,7 +3258,7 @@
this.elytraAnimationState.tick();
}
@ -1221,7 +1227,7 @@
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
if (map != null) {
@@ -2778,10 +3291,17 @@
@@ -2778,10 +3295,17 @@
throw new MatchException((String) null, (Throwable) null);
}
@ -1241,7 +1247,7 @@
if (map == null) {
map = Maps.newEnumMap(EquipmentSlot.class);
}
@@ -3000,7 +3520,7 @@
@@ -3000,7 +3524,7 @@
{
LivingEntity entityliving = this.getControllingPassenger();
@ -1250,7 +1256,7 @@
if (this.isAlive()) {
this.travelRidden(entityhuman, vec3d1);
break label112;
@@ -3063,6 +3583,7 @@
@@ -3063,6 +3587,7 @@
this.checkSlowFallDistance();
if (!this.level().isClientSide) {
if (!this.canGlide()) {
@ -1258,7 +1264,7 @@
this.setSharedFlag(7, false);
return;
}
@@ -3113,7 +3634,7 @@
@@ -3113,7 +3638,7 @@
Level world = this.level();
if (!(world instanceof ServerLevel worldserver)) {
@ -1267,7 +1273,7 @@
} else {
List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
@@ -3138,10 +3659,12 @@
@@ -3138,10 +3663,12 @@
}
Iterator iterator1 = list.iterator();
@ -1282,7 +1288,7 @@
this.doPush(entity1);
}
}
@@ -3305,15 +3828,22 @@
@@ -3305,15 +3832,22 @@
@Override
public boolean isPickable() {
@ -1307,7 +1313,7 @@
public float getYHeadRot() {
return this.yHeadRot;
}
@@ -3342,7 +3872,7 @@
@@ -3342,7 +3876,7 @@
}
public final void setAbsorptionAmount(float absorptionAmount) {
@ -1316,7 +1322,7 @@
}
protected void internalSetAbsorptionAmount(float absorptionAmount) {
@@ -3483,13 +4013,48 @@
@@ -3483,13 +4017,48 @@
this.releaseUsingItem();
} else {
if (!this.useItem.isEmpty() && this.isUsingItem()) {
@ -1329,7 +1335,7 @@
+ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(enumhand);
+ event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, hand); // Paper
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ // Update client
+ Consumable consumable = this.useItem.get(DataComponents.CONSUMABLE);
@ -1340,7 +1346,7 @@
+ entityPlayer.getBukkitEntity().updateScaledHealth();
+ return;
+ }
+
+ itemstack = (craftItem.equals(event.getItem())) ? this.useItem.finishUsingItem(this.level(), this) : CraftItemStack.asNMSCopy(event.getItem()).finishUsingItem(this.level(), this);
+ } else {
+ itemstack = this.useItem.finishUsingItem(this.level(), this);
@ -1366,7 +1372,7 @@
}
}
@@ -3544,12 +4109,24 @@
@@ -3544,12 +4113,24 @@
if (this.isUsingItem() && !this.useItem.isEmpty()) {
Item item = this.useItem.getItem();
@ -1392,7 +1398,7 @@
public boolean isSuppressingSlidingDownLadder() {
return this.isShiftKeyDown();
}
@@ -3568,12 +4145,18 @@
@@ -3568,12 +4149,18 @@
}
public boolean randomTeleport(double x, double y, double z, boolean particleEffects) {
@ -1413,7 +1419,7 @@
Level world = this.level();
if (world.hasChunkAt(blockposition)) {
@@ -3592,18 +4175,43 @@
@@ -3592,18 +4179,43 @@
}
if (flag2) {
@ -1425,7 +1431,7 @@
+ this.setPos(d0, d6, d2);
if (world.noCollision((Entity) this) && !world.containsAnyLiquid(this.getBoundingBox())) {
flag1 = true;
+ }
}
+ // now revert and call event if the teleport place is valid
+ this.setPos(d3, d4, d5);
+
@ -1445,7 +1451,7 @@
+ return Optional.empty();
+ }
+ }
}
+ }
+ // CraftBukkit end
}
}
@ -1461,7 +1467,7 @@
world.broadcastEntityEvent(this, (byte) 46);
}
@@ -3613,7 +4221,7 @@
@@ -3613,7 +4225,7 @@
entitycreature.getNavigation().stop();
}
@ -1470,7 +1476,7 @@
}
}
@@ -3706,7 +4314,7 @@
@@ -3706,7 +4318,7 @@
}
public void stopSleeping() {
@ -1479,7 +1485,7 @@
Level world = this.level();
java.util.Objects.requireNonNull(world);
@@ -3718,9 +4326,9 @@
@@ -3718,9 +4330,9 @@
this.level().setBlock(blockposition, (BlockState) iblockdata.setValue(BedBlock.OCCUPIED, false), 3);
Vec3 vec3d = (Vec3) BedBlock.findStandUpPosition(this.getType(), this.level(), blockposition, enumdirection, this.getYRot()).orElseGet(() -> {
@ -1491,7 +1497,7 @@
});
Vec3 vec3d1 = Vec3.atBottomCenterOf(blockposition).subtract(vec3d).normalize();
float f = (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
@@ -3740,7 +4348,7 @@
@@ -3740,7 +4352,7 @@
@Nullable
public Direction getBedOrientation() {
@ -1500,7 +1506,7 @@
return blockposition != null ? BedBlock.getBedOrientation(this.level(), blockposition) : null;
}
@@ -3905,7 +4513,7 @@
@@ -3905,7 +4517,7 @@
public float maxUpStep() {
float f = (float) this.getAttributeValue(Attributes.STEP_HEIGHT);

View file

@ -383,7 +383,7 @@
if (f1 > 0.0F && target instanceof LivingEntity) {
entityliving = (LivingEntity) target;
- entityliving.knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
+ entityliving.knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
+ entityliving.knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/behavior/RamTarget.java
+++ b/net/minecraft/world/entity/ai/behavior/RamTarget.java
@@ -89,7 +89,7 @@
float f = 0.25F * (float)(i - j);
float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f;
float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F;
- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z());
+ livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
this.finishRam(world, entity);
world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F);
} else if (this.hasRammedHornBreakingBlock(world, entity)) {

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
+++ b/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
@@ -83,7 +83,7 @@
if (target.hurtServer(world, world.damageSources().sonicBoom(entity), 10.0F)) {
double d = 0.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
double e = 2.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
- target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e);
+ target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
}
});
}

View file

@ -81,6 +81,15 @@
}
}
@@ -417,7 +441,7 @@
double d3 = entity.getZ() - d1;
double d4 = Math.max(d2 * d2 + d3 * d3, 0.1D);
- entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D);
+ entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
if (!this.phaseManager.getCurrentPhase().isSitting() && entityliving.getLastHurtByMobTimestamp() < entity.tickCount - 2) {
DamageSource damagesource = this.damageSources().mobAttack(this);
@@ -458,6 +482,9 @@
int j1 = Mth.floor(box.maxZ);
boolean flag = false;

View file

@ -101,7 +101,12 @@
this.kill(worldserver);
this.dropItem(worldserver, (Entity) null);
}
@@ -113,7 +165,7 @@
@@ -109,11 +161,11 @@
}
@Override
- public void push(double deltaX, double deltaY, double deltaZ) {
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - override correct overload
Level world = this.level();
if (world instanceof ServerLevel worldserver) {

View file

@ -18,6 +18,18 @@
double d0 = enumdirection_enumaxis == Direction.Axis.X ? 0.0625D : 0.75D;
double d1 = enumdirection_enumaxis == Direction.Axis.Y ? 0.0625D : 0.75D;
double d2 = enumdirection_enumaxis == Direction.Axis.Z ? 0.0625D : 0.75D;
@@ -123,9 +129,9 @@
}
@Override
- public void push(double deltaX, double deltaY, double deltaZ) {
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - add push source entity param
if (!this.fixed) {
- super.push(deltaX, deltaY, deltaZ);
+ super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
}
}
@@ -155,6 +161,11 @@
if (this.isInvulnerableToBase(source)) {
return false;

View file

@ -22,3 +22,12 @@
flag = worldserver.destroyBlock(blockposition, true, this) || flag;
}
}
@@ -281,7 +289,7 @@
double d1 = entity.getZ() - this.getZ();
double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D);
- entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D);
+ entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
}
@Override

View file

@ -1,6 +1,16 @@
--- a/net/minecraft/world/entity/monster/creaking/Creaking.java
+++ b/net/minecraft/world/entity/monster/creaking/Creaking.java
@@ -206,7 +206,7 @@
@@ -198,15 +198,15 @@
}
@Override
- public void push(double deltaX, double deltaY, double deltaZ) {
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - add push source entity param
if (this.canMove()) {
- super.push(deltaX, deltaY, deltaZ);
+ super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
}
}
@Override
public Brain<Creaking> getBrain() {
@ -27,6 +37,18 @@
}
@Override
@@ -502,9 +502,9 @@
}
@Override
- public void knockback(double strength, double x, double z) {
+ public void knockback(double strength, double x, double z, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause) { // Paper - knockback events
if (this.canMove()) {
- super.knockback(strength, x, z);
+ super.knockback(strength, x, z, attacker, cause); // Paper - knockback events
}
}
@@ -549,7 +549,7 @@
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
+++ b/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
@@ -45,7 +45,7 @@
double j = f * (double)(attacker.level().random.nextFloat() * 0.5F + 0.2F);
Vec3 vec3 = new Vec3(g, 0.0, h).normalize().scale(j).yRot(i);
double k = f * (double)attacker.level().random.nextFloat() * 0.5;
- target.push(vec3.x, k, vec3.z);
+ target.push(vec3.x, k, vec3.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
target.hurtMarked = true;
}
}

View file

@ -35,12 +35,12 @@
public final InventoryMenu inventoryMenu;
public AbstractContainerMenu containerMenu;
protected FoodData foodData = new FoodData();
@@ -188,6 +198,17 @@
@@ -188,7 +198,18 @@
public Entity currentExplosionCause;
private boolean ignoreFallDamageFromCurrentImpulse;
private int currentImpulseContextResetGraceTime;
+ public boolean affectsSpawning = true; // Paper - Affects Spawning API
+
+ // CraftBukkit start
+ public boolean fauxSleeping;
+ public int oldLevel = -1;
@ -50,9 +50,10 @@
+ return (CraftHumanEntity) super.getBukkitEntity();
+ }
+ // CraftBukkit end
+
public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) {
super(EntityType.PLAYER, world);
this.lastItemInMainHand = ItemStack.EMPTY;
@@ -353,7 +374,7 @@
}
@ -278,7 +279,15 @@
if (flag2) {
f *= 1.5F;
}
@@ -1208,7 +1280,11 @@
@@ -1202,13 +1274,17 @@
if (target instanceof LivingEntity) {
LivingEntity entityliving1 = (LivingEntity) target;
- entityliving1.knockback((double) (f5 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
+ entityliving1.knockback((double) (f5 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // Paper - knockback events
} else {
- target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * f5 * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * f5 * 0.5F));
+ target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * f5 * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * f5 * 0.5F), this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
}
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
@ -294,13 +303,14 @@
if (entityliving2 != this && entityliving2 != target && !this.isAlliedTo((Entity) entityliving2) && (!(entityliving2 instanceof ArmorStand) || !((ArmorStand) entityliving2).isMarker()) && this.distanceToSqr((Entity) entityliving2) < 9.0D) {
float f7 = this.getEnchantedDamage(entityliving2, f6, damagesource) * f2;
- entityliving2.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
- entityliving2.hurt(damagesource, f7);
+ // CraftBukkit start - Only apply knockback if the damage hits
+ if (!entityliving2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep(), f7)) {
+ continue;
+ }
+ // CraftBukkit end
entityliving2.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
- entityliving2.hurt(damagesource, f7);
+ entityliving2.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.SWEEP_ATTACK); // CraftBukkit // Paper - knockback events
+ // entityliving2.hurt(damagesource, f7); // CraftBukkit - moved up
Level world = this.level();
@ -427,17 +437,18 @@
}
@Override
@@ -1664,11 +1792,30 @@
@@ -1663,12 +1791,31 @@
public int getXpNeededForNextLevel() {
return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
}
+ }
+ // Paper start - send while respecting visibility
+ private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
+ fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity itself
+ if (fromEntity instanceof ServerPlayer serverPlayer) {
+ serverPlayer.connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(soundEffect), soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong()));
+ }
+ }
}
+ // Paper end - send while respecting visibility
+ // CraftBukkit start
@ -550,10 +561,12 @@
}
@Override
@@ -2005,18 +2188,29 @@
@@ -2003,20 +2186,31 @@
@Override
public ImmutableList<Pose> getDismountPoses() {
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
}
+ }
+
+ // Paper start - PlayerReadyArrowEvent
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) {
+ return !(this instanceof ServerPlayer) ||
@ -562,9 +575,9 @@
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
+ ).callEvent();
+ }
}
+ // Paper end - PlayerReadyArrowEvent
+
@Override
public ItemStack getProjectile(ItemStack stack) {
if (!(stack.getItem() instanceof ProjectileWeaponItem)) {

View file

@ -49,7 +49,7 @@
+ // CraftBukkit start - handle the owner before the rest of things
+ this(type, x, y, z, world, stack, weapon, null);
+ }
+
+ protected AbstractArrow(EntityType<? extends AbstractArrow> entitytypes, double d0, double d1, double d2, Level world, ItemStack itemstack, @Nullable ItemStack itemstack1, @Nullable LivingEntity ownerEntity) {
+ this(entitytypes, world);
+ this.setOwner(ownerEntity);
@ -57,7 +57,7 @@
+ this.pickupItemStack = itemstack.copy();
+ this.setCustomName((Component) itemstack.get(DataComponents.CUSTOM_NAME));
+ Unit unit = (Unit) itemstack.remove(DataComponents.INTANGIBLE_PROJECTILE);
+
if (unit != null) {
this.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
}
@ -118,6 +118,18 @@
}
}
@@ -386,9 +410,9 @@
}
@Override
- public void push(double deltaX, double deltaY, double deltaZ) {
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - add push source entity param
if (!this.isInGround()) {
- super.push(deltaX, deltaY, deltaZ);
+ super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
}
}
@@ -423,7 +447,7 @@
}
@ -160,6 +172,15 @@
}
}
}
@@ -538,7 +568,7 @@
Vec3 vec3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale(d0 * 0.6D * d1);
if (vec3d.lengthSqr() > 0.0D) {
- target.push(vec3d.x, 0.1D, vec3d.z);
+ target.push(vec3d.x, 0.1D, vec3d.z, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
}
}
@@ -675,7 +705,7 @@
}

View file

@ -10,6 +10,15 @@
public abstract class AbstractWindCharge extends AbstractHurtingProjectile implements ItemSupplier {
@@ -98,7 +101,7 @@
}
@Override
- public void push(double deltaX, double deltaY, double deltaZ) {}
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) {} // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
public abstract void explode(Vec3 pos);
@@ -111,7 +114,7 @@
Vec3 vec3d1 = blockHitResult.getLocation().add(vec3d);

View file

@ -111,19 +111,16 @@
} else {
d6 = d5;
}
@@ -214,11 +256,22 @@
@@ -214,11 +256,19 @@
d3 *= d6;
Vec3 vec3d = new Vec3(d1, d2, d3);
+ // CraftBukkit start - Call EntityKnockbackEvent
+ if (entity instanceof LivingEntity) {
+ Vec3 result = entity.getDeltaMovement().add(vec3d);
+ org.bukkit.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.EXPLOSION, d6, vec3d, result.x, result.y, result.z);
+
+ // SPIGOT-7640: Need to subtract entity movement from the event result,
+ // since the code below (the setDeltaMovement call as well as the hitPlayers map)
+ // want the vector to be the relative velocity will the event provides the absolute velocity
+ vec3d = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ()).subtract(entity.getDeltaMovement());
+ // Paper start - knockback events
+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, this.damageSource.getEntity() != null ? this.damageSource.getEntity() : this.source, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.EXPLOSION, d6, vec3d);
+ vec3d = event.isCancelled() ? Vec3.ZERO : org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getKnockback());
+ // Paper end - knockback events
+ }
+ // CraftBukkit end
entity.push(vec3d);
@ -135,7 +132,7 @@
this.hitPlayers.put(entityhuman, vec3d);
}
}
@@ -235,10 +288,62 @@
@@ -235,10 +285,62 @@
List<ServerExplosion.StackCollector> list1 = new ArrayList();
Util.shuffle(positions, this.level.random);
@ -198,7 +195,7 @@
this.level.getBlockState(blockposition).onExplosionHit(this.level, blockposition, this, (itemstack, blockposition1) -> {
ServerExplosion.addOrAppendStack(list1, itemstack, blockposition1);
@@ -262,13 +367,22 @@
@@ -262,13 +364,22 @@
BlockPos blockposition = (BlockPos) iterator.next();
if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockposition).isAir() && this.level.getBlockState(blockposition.below()).isSolidRender()) {
@ -222,7 +219,7 @@
this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center);
List<BlockPos> list = this.calculateExplodedPositions();
@@ -288,6 +402,7 @@
@@ -288,6 +399,7 @@
}
private static void addOrAppendStack(List<ServerExplosion.StackCollector> droppedItemsOut, ItemStack item, BlockPos pos) {
@ -230,7 +227,7 @@
Iterator iterator = droppedItemsOut.iterator();
do {
@@ -372,4 +487,85 @@
@@ -372,4 +484,85 @@
}
}

View file

@ -1936,19 +1936,33 @@ public class CraftEventFactory {
return event;
}
public static EntityKnockbackEvent callEntityKnockbackEvent(CraftLivingEntity entity, Entity attacker, EntityKnockbackEvent.KnockbackCause cause, double force, Vec3 raw, double x, double y, double z) {
Vector bukkitRaw = new Vector(-raw.x, raw.y, -raw.z); // Due to how the knockback calculation works, we need to invert x and z.
// Paper start - replace knockback events
public static io.papermc.paper.event.entity.EntityKnockbackEvent callEntityKnockbackEvent(CraftLivingEntity entity, Entity pusher, Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause, double force, Vec3 knockback) {
Vector apiKnockback = CraftVector.toBukkit(knockback);
EntityKnockbackEvent event;
if (attacker != null) {
event = new EntityKnockbackByEntityEvent(entity, attacker.getBukkitEntity(), cause, force, new Vector(-raw.x, raw.y, -raw.z), new Vector(x, y, z));
final Vector currentVelocity = entity.getVelocity();
final Vector legacyFinalKnockback = currentVelocity.clone().add(apiKnockback);
final org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause legacyCause = org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.valueOf(cause.name());
EntityKnockbackEvent legacyEvent;
if (pusher != null) {
legacyEvent = new EntityKnockbackByEntityEvent(entity, pusher.getBukkitEntity(), legacyCause, force, apiKnockback, legacyFinalKnockback);
} else {
event = new EntityKnockbackEvent(entity, cause, force, new Vector(-raw.x, raw.y, -raw.z), new Vector(x, y, z));
legacyEvent = new EntityKnockbackEvent(entity, legacyCause, force, apiKnockback, legacyFinalKnockback);
}
legacyEvent.callEvent();
Bukkit.getPluginManager().callEvent(event);
final io.papermc.paper.event.entity.EntityKnockbackEvent event;
apiKnockback = legacyEvent.getFinalKnockback().subtract(currentVelocity);
if (attacker != null) {
event = new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent(entity, attacker.getBukkitEntity(), cause, (float) force, apiKnockback);
} else {
event = new io.papermc.paper.event.entity.EntityKnockbackEvent(entity, cause, apiKnockback);
}
event.setCancelled(legacyEvent.isCancelled());
event.callEvent();
return event;
}
// Paper end - replace knockback events
public static void callEntityRemoveEvent(Entity entity, EntityRemoveEvent.Cause cause) {
if (entity instanceof ServerPlayer) {