diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index 221d69af9..29f907dda 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -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> 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 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 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() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index 5a6a6fa81..7b9ca6dc1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -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 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 freezing = new com.google.common.base.Function() { + @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 hardHat = new com.google.common.base.Function() { + @Override + public Double apply(Double f) { @@ -949,7 +954,7 @@ + }; + float hardHatModifier = hardHat.apply((double) f).floatValue(); + f += hardHatModifier; -+ + + com.google.common.base.Function blocking = new com.google.common.base.Function() { + @Override + public Double apply(Double f) { @@ -983,7 +988,7 @@ + }; + float resistanceModifier = resistance.apply((double) f).floatValue(); + f += resistanceModifier; - ++ + com.google.common.base.Function magic = new com.google.common.base.Function() { + @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 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 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); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch index 1715d82a3..6695b8d4a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -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)); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch new file mode 100644 index 000000000..3c23484d4 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/RamTarget.java.patch @@ -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)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java.patch new file mode 100644 index 000000000..4fbd06f25 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java.patch @@ -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 + } + }); + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index ad7f4d3b7..770de91dd 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -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; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch index 0d00e2d56..35af032ef 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch @@ -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) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch index 9ab163c22..a96cc7db9 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch @@ -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; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch index 13dc27be2..ea8587e36 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch @@ -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 diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch index 796c6a353..d3d16a6b2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -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 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 @@ } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/HoglinBase.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/HoglinBase.java.patch new file mode 100644 index 000000000..634a383e7 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/HoglinBase.java.patch @@ -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; + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index 2dccf8ff2..e53cacfe1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -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 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)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch index 3af8470be..e427ce764 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch @@ -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 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 @@ } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java.patch index ef15dd232..01844591e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java.patch @@ -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); diff --git a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch index 0921dea01..d289383a9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch @@ -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 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 list = this.calculateExplodedPositions(); -@@ -288,6 +402,7 @@ +@@ -288,6 +399,7 @@ } private static void addOrAppendStack(List droppedItemsOut, ItemStack item, BlockPos pos) { @@ -230,7 +227,7 @@ Iterator iterator = droppedItemsOut.iterator(); do { -@@ -372,4 +487,85 @@ +@@ -372,4 +484,85 @@ } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index f05a19f86..60a16ac62 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -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) {