Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: MiniDigger | Martin <admin@minidigger.dev>
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com>
Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
This commit is contained in:
Nassim Jahnke
2025-04-12 17:26:44 +02:00
parent 0767902699
commit f00727c57e
2092 changed files with 50551 additions and 48729 deletions

View File

@@ -1,49 +1,21 @@
--- a/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -33,6 +_,7 @@
import net.minecraft.world.entity.OminousItemSpawner;
import net.minecraft.world.entity.SlotAccess;
import net.minecraft.world.entity.ai.attributes.Attributes;
+import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
@@ -63,16 +_,16 @@
protected int inGroundTime;
public AbstractArrow.Pickup pickup = AbstractArrow.Pickup.DISALLOWED;
public int shakeTime;
- private int life;
+ public int life; // Paper - private -> public
private double baseDamage = 2.0;
- private SoundEvent soundEvent = this.getDefaultHitGroundSoundEvent();
+ public SoundEvent soundEvent = this.getDefaultHitGroundSoundEvent(); // Paper - private -> public
@Nullable
private IntOpenHashSet piercingIgnoreEntityIds;
@Nullable
private List<Entity> piercedAndKilledEntities;
- private ItemStack pickupItemStack = this.getDefaultPickupItem();
+ public ItemStack pickupItemStack = this.getDefaultPickupItem(); // Paper - private -> public
@Nullable
- private ItemStack firedFromWeapon = null;
+ public ItemStack firedFromWeapon = null; // Paper - private -> public
protected AbstractArrow(EntityType<? extends AbstractArrow> entityType, Level level) {
super(entityType, level);
@@ -87,7 +_,13 @@
@@ -93,7 +_,14 @@
ItemStack pickupItemStack,
@Nullable ItemStack firedFromWeapon
) {
+ // CraftBukkit start - handle the owner before the rest of things
+ this(entityType, x, y, z, level, pickupItemStack, firedFromWeapon, null);
+ }
+
+ protected AbstractArrow(EntityType<? extends AbstractArrow> entityType, double x, double y, double z, Level level, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon, @Nullable LivingEntity ownerEntity) {
this(entityType, level);
+ this.setOwner(ownerEntity);
+ // CraftBukkit end
this.pickupItemStack = pickupItemStack.copy();
this.setCustomName(pickupItemStack.get(DataComponents.CUSTOM_NAME));
this.applyComponentsFromItemStack(pickupItemStack);
Unit unit = pickupItemStack.remove(DataComponents.INTANGIBLE_PROJECTILE);
@@ -112,8 +_,8 @@
@@ -118,8 +_,8 @@
protected AbstractArrow(
EntityType<? extends AbstractArrow> entityType, LivingEntity owner, Level level, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon
) {
@@ -54,15 +26,15 @@
}
public void setSoundEvent(SoundEvent soundEvent) {
@@ -209,6 +_,7 @@
this.applyEffectsFromBlocks();
@@ -214,6 +_,7 @@
this.setSharedFlagOnFire(this.getRemainingFireTicks() > 0);
}
} else {
+ if (this.tickCount > 200) this.tickDespawn(); // Paper - tick despawnCounter regardless after 10 seconds
+ if (this.tickCount > 200) this.tickDespawn(); // Paper - tick life regardless after 10 seconds
this.inGroundTime = 0;
Vec3 vec31 = this.position();
if (this.isInWater()) {
@@ -275,12 +_,12 @@
@@ -280,12 +_,12 @@
if (entityHitResult == null) {
if (this.isAlive() && hitResult.getType() != HitResult.Type.MISS) {
@@ -77,7 +49,7 @@
this.hasImpulse = true;
if (this.getPierceLevel() > 0 && projectileDeflection == ProjectileDeflection.NONE) {
continue;
@@ -313,13 +_,26 @@
@@ -318,13 +_,26 @@
}
}
@@ -105,16 +77,7 @@
}
private void startFalling() {
@@ -329,7 +_,7 @@
this.life = 0;
}
- protected boolean isInGround() {
+ public boolean isInGround() { // Paper - protected -> public
return this.entityData.get(IN_GROUND);
}
@@ -347,8 +_,8 @@
@@ -357,8 +_,8 @@
protected void tickDespawn() {
this.life++;
@@ -125,7 +88,7 @@
}
}
@@ -375,9 +_,9 @@
@@ -392,9 +_,9 @@
}
@Override
@@ -137,7 +100,7 @@
}
}
@@ -404,7 +_,7 @@
@@ -421,7 +_,7 @@
}
if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) {
@@ -146,7 +109,7 @@
return;
}
@@ -420,10 +_,17 @@
@@ -437,10 +_,16 @@
livingEntity.setLastHurtMob(entity);
}
@@ -157,15 +120,14 @@
- entity.igniteForSeconds(5.0F);
+ // CraftBukkit start
+ org.bukkit.event.entity.EntityCombustByEntityEvent combustEvent = new org.bukkit.event.entity.EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5.0F);
+ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent);
+ if (!combustEvent.isCancelled()) {
+ if (combustEvent.callEvent()) {
+ entity.igniteForSeconds(combustEvent.getDuration(), false);
+ }
+ // CraftBukkit end
}
if (entity.hurtOrSimulate(damageSource, ceil)) {
@@ -461,7 +_,7 @@
@@ -478,7 +_,7 @@
this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
if (this.getPierceLevel() <= 0) {
@@ -174,7 +136,7 @@
}
} else {
entity.setRemainingFireTicks(remainingFireTicks);
@@ -472,7 +_,7 @@
@@ -489,7 +_,7 @@
this.spawnAtLocation(serverLevel2, this.getPickupItem(), 0.1F);
}
@@ -183,7 +145,7 @@
}
}
}
@@ -485,7 +_,7 @@
@@ -502,7 +_,7 @@
double max = Math.max(0.0, 1.0 - entity.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
Vec3 vec3 = this.getDeltaMovement().multiply(1.0, 0.0, 1.0).normalize().scale(d * 0.6 * max);
if (vec3.lengthSqr() > 0.0) {
@@ -192,16 +154,7 @@
}
}
}
@@ -597,7 +_,7 @@
this.setPierceLevel(compound.getByte("PierceLevel"));
if (compound.contains("SoundEvent", 8)) {
this.soundEvent = BuiltInRegistries.SOUND_EVENT
- .getOptional(ResourceLocation.parse(compound.getString("SoundEvent")))
+ .getOptional(ResourceLocation.tryParse(compound.getString("SoundEvent"))) // Paper - Validate resource location
.orElse(this.getDefaultHitGroundSoundEvent());
}
@@ -616,7 +_,14 @@
@@ -610,7 +_,14 @@
@Override
public void setOwner(@Nullable Entity entity) {
@@ -216,7 +169,7 @@
this.pickup = switch (entity) {
case Player player when this.pickup == AbstractArrow.Pickup.DISALLOWED -> AbstractArrow.Pickup.ALLOWED;
@@ -628,9 +_,24 @@
@@ -622,9 +_,22 @@
@Override
public void playerTouch(Player entity) {
if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) {
@@ -224,12 +177,10 @@
+ // CraftBukkit start
+ ItemStack itemstack = this.getPickupItem();
+ if (this.pickup == Pickup.ALLOWED && !itemstack.isEmpty() && entity.getInventory().canHold(itemstack) > 0) {
+ ItemEntity item = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack);
+ net.minecraft.world.entity.item.ItemEntity item = new net.minecraft.world.entity.item.ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack);
+ org.bukkit.event.player.PlayerPickupArrowEvent event = new org.bukkit.event.player.PlayerPickupArrowEvent((org.bukkit.entity.Player) entity.getBukkitEntity(), (org.bukkit.entity.Item) item.getBukkitEntity(), (org.bukkit.entity.AbstractArrow) this.getBukkitEntity());
+ // event.setCancelled(!entityhuman.canPickUpLoot); TODO
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ if (!event.callEvent()) {
+ return;
+ }
+ itemstack = item.getItem();
@@ -243,34 +194,3 @@
}
}
}
@@ -643,7 +_,7 @@
};
}
- protected ItemStack getPickupItem() {
+ public ItemStack getPickupItem() { // Paper - protected -> public
return this.pickupItemStack.copy();
}
@@ -675,7 +_,7 @@
this.setFlag(1, critArrow);
}
- private void setPierceLevel(byte pierceLevel) {
+ public void setPierceLevel(byte pierceLevel) { // Paper - private -> public
this.entityData.set(PIERCE_LEVEL, pierceLevel);
}
@@ -687,6 +_,12 @@
this.entityData.set(ID_FLAGS, (byte)(b & ~id));
}
}
+
+ // Paper start
+ public void setPickupItemStackPublic(final ItemStack pickupItemStack) {
+ this.setPickupItemStack(pickupItemStack);
+ }
+ // Paper end
protected void setPickupItemStack(ItemStack pickupItemStack) {
if (!pickupItemStack.isEmpty()) {

View File

@@ -0,0 +1,109 @@
--- a/net/minecraft/world/entity/projectile/AbstractThrownPotion.java
+++ b/net/minecraft/world/entity/projectile/AbstractThrownPotion.java
@@ -70,54 +_,95 @@
@Override
protected void onHit(HitResult result) {
super.onHit(result);
+ // Paper start - More projectile API
+ this.splash(result);
+ }
+
+ public void splash(@Nullable HitResult result) {
+ // Paper end - More projectile API
if (this.level() instanceof ServerLevel serverLevel) {
ItemStack item = this.getItem();
PotionContents potionContents = item.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
+ boolean showParticles = true; // Paper - Fix potions splash events
if (potionContents.is(Potions.WATER)) {
- this.onHitAsWater(serverLevel);
- } else if (potionContents.hasEffects()) {
- this.onHitAsPotion(serverLevel, item, result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null);
+ showParticles = this.onHitAsWater(serverLevel, result); // Paper - Fix potions splash events
+ } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
+ showParticles = this.onHitAsPotion(serverLevel, item, result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result); // Paper - pass HitResult
}
+ if (showParticles) { // Paper - Fix potions splash events
int i = potionContents.potion().isPresent() && potionContents.potion().get().value().hasInstantEffects() ? 2007 : 2002;
serverLevel.levelEvent(i, this.blockPosition(), potionContents.getColor());
- this.discard();
+ } // Paper - Fix potions splash events
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
}
}
- private void onHitAsWater(ServerLevel level) {
+ private static final Predicate<LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = AbstractThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+
+ private boolean onHitAsWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
- for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, WATER_SENSITIVE_OR_ON_FIRE)) {
+ // Paper start - Fix potions splash events
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>();
+ java.util.Set<org.bukkit.entity.LivingEntity> rehydrate = new java.util.HashSet<>();
+ java.util.Set<org.bukkit.entity.LivingEntity> extinguish = new java.util.HashSet<>();
+ for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, APPLY_WATER_GET_ENTITIES_PREDICATE)) {
+ if (livingEntity instanceof Axolotl axolotl) {
+ rehydrate.add(((org.bukkit.entity.Axolotl) axolotl.getBukkitEntity()));
+ }
+ // Paper end - Fix potions splash events
double d = this.distanceToSqr(livingEntity);
if (d < 16.0) {
if (livingEntity.isSensitiveToWater()) {
- livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); // Paper - Fix potions splash events
}
if (livingEntity.isOnFire() && livingEntity.isAlive()) {
- livingEntity.extinguishFire();
+ extinguish.add(livingEntity.getBukkitLivingEntity()); // Paper - Fix potions splash events
}
}
}
- for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) {
- axolotl.rehydrate();
+ // Paper start - Fix potions splash events
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
+ this, result, affected, rehydrate, extinguish
+ );
+ if (!event.isCancelled()) {
+ for (org.bukkit.entity.LivingEntity affectedEntity : event.getToDamage()) {
+ ((org.bukkit.craftbukkit.entity.CraftLivingEntity) affectedEntity).getHandle().hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ }
+ for (org.bukkit.entity.LivingEntity toExtinguish : event.getToExtinguish()) {
+ ((org.bukkit.craftbukkit.entity.CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
+ }
+ for (org.bukkit.entity.LivingEntity toRehydrate : event.getToRehydrate()) {
+ if (((org.bukkit.craftbukkit.entity.CraftLivingEntity) toRehydrate).getHandle() instanceof Axolotl axolotl) {
+ axolotl.rehydrate();
+ }
+ }
+ // Paper end - Fix potions splash events
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
- protected abstract void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity);
+ protected abstract boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable HitResult hitResult); // Paper - Pass HitResult // Paper - Fix potions splash events & More Projectile API
private void dowseFire(BlockPos pos) {
BlockState blockState = this.level().getBlockState(pos);
if (blockState.is(BlockTags.FIRE)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
this.level().destroyBlock(pos, false, this);
+ } // CraftBukkit
} else if (AbstractCandleBlock.isLit(blockState)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, false))) { // CraftBukkit
AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
+ } // CraftBukkit
} else if (CampfireBlock.isLitCampfire(blockState)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, false))) { // CraftBukkit
this.level().levelEvent(null, 1009, pos, 0);
CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, false));
+ } // CraftBukkit
}
}

View File

@@ -1,17 +1,11 @@
--- a/net/minecraft/world/entity/projectile/Arrow.java
+++ b/net/minecraft/world/entity/projectile/Arrow.java
@@ -121,12 +_,13 @@
mobEffectInstance.isVisible()
),
effectSource
+ , org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW // CraftBukkit
);
}
}
for (MobEffectInstance mobEffectInstance : potionContents.customEffects()) {
- living.addEffect(mobEffectInstance, effectSource);
+ living.addEffect(mobEffectInstance, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit
}
@@ -115,7 +_,7 @@
Entity effectSource = this.getEffectSource();
PotionContents potionContents = this.getPotionContents();
float potionDurationScale = this.getPotionDurationScale();
- potionContents.forEachEffect(mobEffectInstance -> living.addEffect(mobEffectInstance, effectSource), potionDurationScale);
+ potionContents.forEachEffect(mobEffectInstance -> living.addEffect(mobEffectInstance, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW), potionDurationScale); // CraftBukkit
}
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/DragonFireball.java
+++ b/net/minecraft/world/entity/projectile/DragonFireball.java
@@ -52,9 +_,11 @@
@@ -53,9 +_,11 @@
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/EvokerFangs.java
+++ b/net/minecraft/world/entity/projectile/EvokerFangs.java
@@ -109,7 +_,7 @@
@@ -107,7 +_,7 @@
}
if (--this.lifeTicks < 0) {
@@ -9,12 +9,12 @@
}
}
}
@@ -118,7 +_,7 @@
@@ -116,7 +_,7 @@
LivingEntity owner = this.getOwner();
if (target.isAlive() && !target.isInvulnerable() && target != owner) {
if (owner == null) {
- target.hurt(this.damageSources().magic(), 6.0F);
+ target.hurt(this.damageSources().magic().eventEntityDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API
+ target.hurt(this.damageSources().magic().eventEntityDamager(this), 6.0F); // CraftBukkit
} else {
if (owner.isAlliedTo(target)) {
return;

View File

@@ -1,18 +1,19 @@
--- a/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -70,6 +_,11 @@
@@ -73,6 +_,12 @@
}
public void signalTo(BlockPos pos) {
+ // Paper start - Change EnderEye target without changing other things
+ this.signalTo(pos, true);
+ }
+
+ public void signalTo(BlockPos pos, boolean update) {
+ // Paper end - Change EnderEye target without changing other things
double d = pos.getX();
int y = pos.getY();
double d1 = pos.getZ();
@@ -86,8 +_,10 @@
@@ -89,8 +_,10 @@
this.tz = d1;
}
@@ -23,7 +24,7 @@
}
@Override
@@ -161,7 +_,7 @@
@@ -164,7 +_,7 @@
this.life++;
if (this.life > 80 && !this.level().isClientSide) {
this.playSound(SoundEvents.ENDER_EYE_DEATH, 1.0F, 1.0F);
@@ -32,17 +33,3 @@
if (this.surviveAfterDeath) {
this.level().addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), this.getItem()));
} else {
@@ -181,7 +_,12 @@
@Override
public void readAdditionalSaveData(CompoundTag compound) {
if (compound.contains("Item", 10)) {
- this.setItem(ItemStack.parse(this.registryAccess(), compound.getCompound("Item")).orElse(this.getDefaultItem()));
+ // CraftBukkit start - SPIGOT-6103 summon, see also SPIGOT-5474
+ ItemStack itemStack = ItemStack.parse(this.registryAccess(), compound.getCompound("Item")).orElse(this.getDefaultItem());
+ if (!itemStack.isEmpty()) {
+ this.setItem(itemStack);
+ }
+ // CraftBukkit end
} else {
this.setItem(this.getDefaultItem());
}

View File

@@ -1,16 +0,0 @@
--- a/net/minecraft/world/entity/projectile/Fireball.java
+++ b/net/minecraft/world/entity/projectile/Fireball.java
@@ -60,7 +_,12 @@
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
if (compound.contains("Item", 10)) {
- this.setItem(ItemStack.parse(this.registryAccess(), compound.getCompound("Item")).orElse(this.getDefaultItem()));
+ // CraftBukkit start - SPIGOT-5474 probably came from bugged earlier versions
+ final ItemStack itemStack = ItemStack.parse(this.registryAccess(), compound.getCompound("Item")).orElse(this.getDefaultItem());
+ if (!itemStack.isEmpty()) {
+ this.setItem(itemStack);
+ }
+ // CraftBukkit end
} else {
this.setItem(this.getDefaultItem());
}

View File

@@ -1,14 +1,14 @@
--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
+++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
@@ -43,6 +_,7 @@
public int lifetime;
@@ -50,6 +_,7 @@
public int lifetime = 0;
@Nullable
public LivingEntity attachedToEntity;
+ @Nullable public java.util.UUID spawningEntity; // Paper
public FireworkRocketEntity(EntityType<? extends FireworkRocketEntity> entityType, Level level) {
super(entityType, level);
@@ -158,7 +_,7 @@
@@ -165,7 +_,7 @@
}
if (!this.noPhysics && this.isAlive() && hitResultOnMoveVector.getType() != HitResult.Type.MISS) {
@@ -17,7 +17,7 @@
this.hasImpulse = true;
}
@@ -182,7 +_,11 @@
@@ -189,7 +_,11 @@
}
if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) {
@@ -30,7 +30,7 @@
}
}
@@ -190,14 +_,18 @@
@@ -197,14 +_,18 @@
level.broadcastEntityEvent(this, (byte)17);
this.gameEvent(GameEvent.EXPLODE, this.getOwner());
this.dealExplosionDamage(level);
@@ -51,9 +51,9 @@
}
}
@@ -206,7 +_,11 @@
@@ -213,7 +_,11 @@
BlockPos blockPos = new BlockPos(result.getBlockPos());
this.level().getBlockState(blockPos).entityInside(this.level(), blockPos, this);
this.level().getBlockState(blockPos).entityInside(this.level(), blockPos, this, InsideBlockEffectApplier.NOOP);
if (this.level() instanceof ServerLevel serverLevel && this.hasExplosion()) {
- this.explode(serverLevel);
+ // Paper start - Call FireworkExplodeEvent
@@ -64,27 +64,19 @@
}
super.onHitBlock(result);
@@ -278,6 +_,11 @@
compound.putInt("LifeTime", this.lifetime);
compound.put("FireworksItem", this.getItem().save(this.registryAccess()));
@@ -286,6 +_,7 @@
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
compound.store("FireworksItem", ItemStack.CODEC, registryOps, this.getItem());
compound.putBoolean("ShotAtAngle", this.entityData.get(DATA_SHOT_AT_ANGLE));
+ // Paper start
+ if (this.spawningEntity != null) {
+ compound.putUUID("SpawningEntity", this.spawningEntity);
+ }
+ // Paper end
+ compound.storeNullable("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); // Paper
}
@Override
@@ -298,6 +_,11 @@
if (compound.contains("ShotAtAngle")) {
this.entityData.set(DATA_SHOT_AT_ANGLE, compound.getBoolean("ShotAtAngle"));
}
+ // Paper start
+ if (compound.hasUUID("SpawningEntity")) {
+ this.spawningEntity = compound.getUUID("SpawningEntity");
+ }
+ // Paper end
@@ -296,6 +_,7 @@
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
this.entityData.set(DATA_ID_FIREWORKS_ITEM, compound.read("FireworksItem", ItemStack.CODEC, registryOps).orElse(getDefaultItem()));
this.entityData.set(DATA_SHOT_AT_ANGLE, compound.getBooleanOr("ShotAtAngle", false));
+ this.spawningEntity = compound.read("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); // Paper
}
private List<FireworkExplosion> getExplosions() {

View File

@@ -27,7 +27,7 @@
}
public FishingHook(EntityType<? extends FishingHook> entityType, Level level) {
@@ -147,12 +_,12 @@
@@ -143,12 +_,12 @@
super.tick();
Player playerOwner = this.getPlayerOwner();
if (playerOwner == null) {
@@ -42,7 +42,7 @@
return;
}
} else {
@@ -251,14 +_,14 @@
@@ -247,14 +_,14 @@
if (!player.isRemoved() && player.isAlive() && (isFishingRod || isFishingRod1) && !(this.distanceToSqr(player) > 1024.0)) {
return false;
} else {
@@ -59,7 +59,7 @@
}
@Override
@@ -289,11 +_,11 @@
@@ -285,11 +_,11 @@
ServerLevel serverLevel = (ServerLevel)this.level();
int i = 1;
BlockPos blockPos = pos.above();
@@ -73,32 +73,31 @@
i--;
}
@@ -303,6 +_,10 @@
@@ -299,6 +_,10 @@
this.timeUntilLured = 0;
this.timeUntilHooked = 0;
this.getEntityData().set(DATA_BITING, false);
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) this.getPlayerOwner().getBukkitEntity(), null, (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.event.player.PlayerFishEvent.State.FAILED_ATTEMPT);
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+ playerFishEvent.callEvent();
+ // CraftBukkit end
}
} else if (this.timeUntilHooked > 0) {
this.timeUntilHooked -= i;
@@ -326,6 +_,13 @@
@@ -322,6 +_,12 @@
serverLevel.sendParticles(ParticleTypes.FISHING, d, d1, d2, 0, -f2, 0.01, f1, 1.0);
}
} else {
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) this.getPlayerOwner().getBukkitEntity(), null, (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.event.player.PlayerFishEvent.State.BITE);
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+ if (playerFishEvent.isCancelled()) {
+ if (!playerFishEvent.callEvent()) {
+ return;
+ }
+ // CraftBukkit end
this.playSound(SoundEvents.FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
double d3 = this.getY() + 0.5;
serverLevel.sendParticles(
@@ -377,14 +_,33 @@
@@ -373,14 +_,31 @@
}
if (this.timeUntilLured <= 0) {
@@ -121,9 +120,7 @@
} else {
- this.timeUntilLured = Mth.nextInt(this.random, 100, 600);
- this.timeUntilLured = this.timeUntilLured - this.lureSpeed;
+ // CraftBukkit start - logic to modify fishing wait time
+ this.resetTimeUntilLured(); // Paper - more projectile api - extract time until lured reset logic
+ // CraftBukkit end
}
}
+
@@ -136,19 +133,18 @@
public boolean calculateOpenWater(BlockPos pos) {
FishingHook.OpenWaterType openWaterType = FishingHook.OpenWaterType.INVALID;
@@ -443,15 +_,34 @@
@@ -439,15 +_,31 @@
public void readAdditionalSaveData(CompoundTag compound) {
}
+
+ // Paper start - Add hand parameter to PlayerFishEvent
+ @Deprecated
+ @io.papermc.paper.annotation.DoNotUse
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
public int retrieve(ItemStack stack) {
+ return this.retrieve(net.minecraft.world.InteractionHand.MAIN_HAND, stack);
+ return this.retrieve(stack, net.minecraft.world.InteractionHand.MAIN_HAND);
+ }
+
+ public int retrieve(net.minecraft.world.InteractionHand hand, ItemStack stack) {
+ public int retrieve(ItemStack stack, net.minecraft.world.InteractionHand hand) {
+ // Paper end - Add hand parameter to PlayerFishEvent
Player playerOwner = this.getPlayerOwner();
if (!this.level().isClientSide && playerOwner != null && !this.shouldStopFishing(playerOwner)) {
@@ -156,9 +152,7 @@
if (this.hookedIn != null) {
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) playerOwner.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), org.bukkit.event.player.PlayerFishEvent.State.CAUGHT_ENTITY); // Paper - Add hand parameter to PlayerFishEvent
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+
+ if (playerFishEvent.isCancelled()) {
+ if (!playerFishEvent.callEvent()) {
+ return 0;
+ }
+ if (this.hookedIn != null) { // Paper - re-check to see if there is a hooked entity
@@ -171,16 +165,14 @@
} else if (this.nibble > 0) {
LootParams lootParams = new LootParams.Builder((ServerLevel)this.level())
.withParameter(LootContextParams.ORIGIN, this.position())
@@ -465,18 +_,32 @@
@@ -461,18 +_,27 @@
for (ItemStack itemStack : randomItems) {
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemStack);
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) playerOwner.getBukkitEntity(), itemEntity.getBukkitEntity(), (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), org.bukkit.event.player.PlayerFishEvent.State.CAUGHT_FISH); // Paper - itemEntity may be null // Paper - Add hand parameter to PlayerFishEvent
+ playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1);
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+
+ if (playerFishEvent.isCancelled()) {
+ if (!playerFishEvent.callEvent()) {
+ return 0;
+ }
+ // CraftBukkit end
@@ -196,8 +188,7 @@
- playerOwner.level(), playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5, this.random.nextInt(6) + 1
- )
- );
+ // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
+ if (playerFishEvent.getExpToDrop() > 0) {
+ if (playerFishEvent.getExpToDrop() > 0) { // CraftBukkit - custom exp
+ playerOwner.level()
+ .addFreshEntity(
+ new ExperienceOrb(
@@ -205,20 +196,16 @@
+ )
+ );
+ }
+ // CraftBukkit end
+
if (itemStack.is(ItemTags.FISHES)) {
playerOwner.awardStat(Stats.FISH_CAUGHT, 1);
}
@@ -486,10 +_,27 @@
@@ -482,10 +_,24 @@
}
if (this.onGround()) {
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) playerOwner.getBukkitEntity(), null, (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), org.bukkit.event.player.PlayerFishEvent.State.IN_GROUND); // Paper - Add hand parameter to PlayerFishEvent
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+
+ if (playerFishEvent.isCancelled()) {
+ if (!playerFishEvent.callEvent()) {
+ return 0;
+ }
+ // CraftBukkit end
@@ -227,8 +214,7 @@
+ // CraftBukkit start
+ if (i == 0) {
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) playerOwner.getBukkitEntity(), null, (org.bukkit.entity.FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), org.bukkit.event.player.PlayerFishEvent.State.REEL_IN); // Paper - Add hand parameter to PlayerFishEvent
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
+ if (playerFishEvent.isCancelled()) {
+ if (!playerFishEvent.callEvent()) {
+ return 0;
+ }
+ }
@@ -239,24 +225,19 @@
return i;
} else {
return 0;
@@ -520,8 +_,15 @@
@@ -515,9 +_,9 @@
}
@Override
public void remove(Entity.RemovalReason reason) {
+ // CraftBukkit start - add Bukkit remove cause
+ this.remove(reason, null);
+ }
+
+ @Override
+ public void remove(Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
+ // CraftBukkit end
- public void remove(Entity.RemovalReason reason) {
+ public void remove(Entity.RemovalReason reason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause
this.updateOwnerInfo(null);
- super.remove(reason);
+ super.remove(reason, cause); // CraftBukkit - add Bukkit remove cause
}
@Override
@@ -570,7 +_,7 @@
@@ -565,7 +_,7 @@
if (this.getPlayerOwner() == null) {
int data = packet.getData();
LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(data), data);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/LargeFireball.java
+++ b/net/minecraft/world/entity/projectile/LargeFireball.java
@@ -18,11 +_,13 @@
@@ -19,11 +_,13 @@
public LargeFireball(EntityType<? extends LargeFireball> entityType, Level level) {
super(entityType, level);
@@ -14,7 +14,7 @@
}
@Override
@@ -30,8 +_,16 @@
@@ -31,8 +_,13 @@
super.onHit(result);
if (this.level() instanceof ServerLevel serverLevel) {
boolean _boolean = serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
@@ -22,24 +22,19 @@
- this.discard();
+ // CraftBukkit start - fire ExplosionPrimeEvent
+ org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ // give 'this' instead of (Entity) null so we know what causes the damage
+ if (event.callEvent()) {
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
+ }
+ // CraftBukkit end
+ // CraftBukkit end - fire ExplosionPrimeEvent
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
}
}
@@ -57,7 +_,8 @@
@@ -57,6 +_,6 @@
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
if (compound.contains("ExplosionPower", 99)) {
- this.explosionPower = compound.getByte("ExplosionPower");
+ // CraftBukkit - set bukkitYield when setting explosionpower
+ this.bukkitYield = this.explosionPower = compound.getByte("ExplosionPower");
}
- this.explosionPower = compound.getByteOr("ExplosionPower", (byte)1);
+ this.bukkitYield = this.explosionPower = compound.getByteOr("ExplosionPower", (byte)1); // CraftBukkit - set bukkitYield when setting explosionPower
}
}

View File

@@ -14,7 +14,7 @@
if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else if (this.isInWaterOrBubble()) {
} else if (this.isInWater()) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {

View File

@@ -1,14 +1,14 @@
--- a/net/minecraft/world/entity/projectile/Projectile.java
+++ b/net/minecraft/world/entity/projectile/Projectile.java
@@ -43,6 +_,7 @@
public boolean hasBeenShot;
@@ -47,6 +_,7 @@
public boolean hasBeenShot = false;
@Nullable
private Entity lastDeflectedBy;
+ protected boolean hitCancelled = false; // CraftBukkit
Projectile(EntityType<? extends Projectile> entityType, Level level) {
super(entityType, level);
@@ -53,15 +_,36 @@
@@ -57,15 +_,36 @@
this.ownerUUID = owner.getUUID();
this.cachedOwner = owner;
}
@@ -47,14 +47,14 @@
} else {
return null;
@@ -98,6 +_,7 @@
@Override
protected void readAdditionalSaveData(CompoundTag compound) {
if (compound.hasUUID("Owner")) {
this.setOwnerThroughUUID(compound.getUUID("Owner"));
+ if (this instanceof ThrownEnderpearl && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit
}
this.leftOwner = compound.getBoolean("LeftOwner");
@@ -175,13 +_,25 @@
this.setOwnerThroughUUID(compound.read("Owner", UUIDUtil.CODEC).orElse(null));
+ if (this instanceof ThrownEnderpearl && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit
this.leftOwner = compound.getBooleanOr("LeftOwner", false);
this.hasBeenShot = compound.getBooleanOr("HasBeenShot", false);
}
@@ -173,7 +_,14 @@
float f2 = Mth.cos(y * (float) (Math.PI / 180.0)) * Mth.cos(x * (float) (Math.PI / 180.0));
this.shoot(f, f1, f2, velocity, inaccuracy);
Vec3 knownMovement = shooter.getKnownMovement();
@@ -68,6 +68,8 @@
+ // Paper end - allow disabling relative velocity
}
@Override
@@ -193,7 +_,12 @@
public static <T extends Projectile> T spawnProjectileFromRotation(
Projectile.ProjectileFactory<T> factory, ServerLevel level, ItemStack spawnedFrom, LivingEntity owner, float z, float velocity, float innaccuracy
) {
@@ -81,27 +83,29 @@
factory.create(level, owner, spawnedFrom),
level,
spawnedFrom,
@@ -206,7 +_,12 @@
@@ -218,7 +_,13 @@
public static <T extends Projectile> T spawnProjectileUsingShoot(
T projectile, ServerLevel level, ItemStack spawnedFrom, double x, double y, double z, float velocity, float inaccuracy
) {
- return spawnProjectile(projectile, level, spawnedFrom, projectile1 -> projectile.shoot(x, y, z, velocity, inaccuracy));
+ // Paper start - fixes and addition to spawn reason API
+ // Paper start - fixes and addition to spawn reason API
+ return spawnProjectileUsingShootDelayed(projectile, level, spawnedFrom, x, y, z, velocity, inaccuracy).spawn();
+ }
+
+ public static <T extends Projectile> Delayed<T> spawnProjectileUsingShootDelayed(T projectile, ServerLevel level, ItemStack spawnedFrom, double x, double y, double z, float velocity, float inaccuracy) {
+ return spawnProjectileDelayed(projectile, level, spawnedFrom, projectile1 -> projectile.shoot(x, y, z, velocity, inaccuracy));
+ // Paper end - fixes and addition to spawn reason API
+ // Paper end - fixes and addition to spawn reason API
}
public static <T extends Projectile> T spawnProjectile(T projectile, ServerLevel level, ItemStack spawnedFrom) {
@@ -214,11 +_,45 @@
@@ -226,11 +_,46 @@
}
public static <T extends Projectile> T spawnProjectile(T projectile, ServerLevel level, ItemStack stack, Consumer<T> adapter) {
+ // Paper start - delayed projectile spawning
+ return spawnProjectileDelayed(projectile, level, stack, adapter).spawn();
+ }
+
+ public static <T extends Projectile> Delayed<T> spawnProjectileDelayed(T projectile, ServerLevel level, ItemStack stack, Consumer<T> adapter) {
+ // Paper end - delayed projectile spawning
adapter.accept(projectile);
@@ -145,12 +149,12 @@
public void applyOnProjectileSpawned(ServerLevel level, ItemStack spawnedFrom) {
EnchantmentHelper.onProjectileSpawned(level, spawnedFrom, this, item -> {});
@@ -230,6 +_,17 @@
@@ -242,6 +_,17 @@
}
}
+ // CraftBukkit start - call projectile hit event
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) { // Paper - protected -> public
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) {
+ org.bukkit.event.entity.ProjectileHitEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, hitResult);
+ this.hitCancelled = event != null && event.isCancelled();
+ if (hitResult.getType() == HitResult.Type.BLOCK || !this.hitCancelled) {
@@ -163,7 +167,7 @@
protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) {
if (hitResult.getType() == HitResult.Type.ENTITY) {
EntityHitResult entityHitResult = (EntityHitResult)hitResult;
@@ -261,7 +_,13 @@
@@ -273,7 +_,13 @@
public boolean deflect(ProjectileDeflection deflection, @Nullable Entity entity, @Nullable Entity owner, boolean deflectedByPlayer) {
deflection.deflect(this, entity, this.random);
if (!this.level().isClientSide) {
@@ -178,7 +182,7 @@
this.onDeflection(entity, deflectedByPlayer);
}
@@ -297,15 +_,35 @@
@@ -309,15 +_,35 @@
}
protected void onHitBlock(BlockHitResult result) {
@@ -214,7 +218,7 @@
return owner == null || this.leftOwner || !owner.isPassengerOfSameVehicle(target);
}
}
@@ -318,13 +_,7 @@
@@ -330,13 +_,7 @@
}
protected static float lerpRotation(float currentRotation, float targetRotation) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ShulkerBullet.java
+++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java
@@ -57,7 +_,21 @@
@@ -58,7 +_,21 @@
this.finalTarget = finalTarget;
this.currentMoveDirection = Direction.UP;
this.selectNextMoveDirection(axis);
@@ -14,7 +14,7 @@
+ return this.finalTarget;
+ }
+
+ public void setTarget(Entity finalTarget) {
+ public void setTarget(@Nullable Entity finalTarget) {
+ this.finalTarget = finalTarget;
+ this.currentMoveDirection = Direction.UP;
+ this.selectNextMoveDirection(Direction.Axis.X);
@@ -23,7 +23,7 @@
@Override
public SoundSource getSoundSource() {
@@ -187,7 +_,7 @@
@@ -180,7 +_,7 @@
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == Difficulty.PEACEFUL) {
@@ -32,7 +32,7 @@
}
}
@@ -233,7 +_,7 @@
@@ -226,7 +_,7 @@
}
if (hitResult != null && this.isAlive() && hitResult.getType() != HitResult.Type.MISS) {
@@ -41,7 +41,7 @@
}
ProjectileUtil.rotateTowardsMovement(this, 0.5F);
@@ -301,7 +_,7 @@
@@ -299,7 +_,7 @@
}
if (entity instanceof LivingEntity livingEntity1) {
@@ -50,7 +50,7 @@
}
}
}
@@ -314,14 +_,20 @@
@@ -312,14 +_,20 @@
}
private void destroy() {
@@ -59,7 +59,7 @@
+ this.destroy(null);
+ }
+
+ private void destroy(org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
+ private void destroy(@Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
+ this.discard(cause);
+ // CraftBukkit end
this.level().gameEvent(GameEvent.ENTITY_DAMAGE, this.position(), GameEvent.Context.of(this));
@@ -73,7 +73,7 @@
}
@Override
@@ -336,9 +_,14 @@
@@ -334,9 +_,14 @@
@Override
public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/SpectralArrow.java
+++ b/net/minecraft/world/entity/projectile/SpectralArrow.java
@@ -38,7 +_,7 @@
@@ -39,7 +_,7 @@
protected void doPostHurtEffects(LivingEntity living) {
super.doPostHurtEffects(living);
MobEffectInstance mobEffectInstance = new MobEffectInstance(MobEffects.GLOWING, this.duration, 0);

View File

@@ -1,15 +0,0 @@
--- a/net/minecraft/world/entity/projectile/ThrowableItemProjectile.java
+++ b/net/minecraft/world/entity/projectile/ThrowableItemProjectile.java
@@ -35,6 +_,12 @@
protected abstract Item getDefaultItem();
+ // CraftBukkit start
+ public Item getDefaultItemPublic() {
+ return this.getDefaultItem();
+ }
+ // CraftBukkit end
+
@Override
public ItemStack getItem() {
return this.getEntityData().get(DATA_ITEM_STACK);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java
+++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java
@@ -59,7 +_,7 @@
@@ -60,7 +_,7 @@
this.applyEffectsFromBlocks();
super.tick();
if (hitResultOnMoveVector.getType() != HitResult.Type.MISS && this.isAlive()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ThrownEgg.java
+++ b/net/minecraft/world/entity/projectile/ThrownEgg.java
@@ -59,28 +_,62 @@
@@ -61,31 +_,66 @@
protected void onHit(HitResult result) {
super.onHit(result);
if (!this.level().isClientSide) {
@@ -8,29 +8,25 @@
+ // CraftBukkit start
+ boolean hatching = this.random.nextInt(8) == 0;
+ if (true) {
+ // CraftBukkit end
+ // CraftBukkit end
int i = 1;
if (this.random.nextInt(32) == 0) {
i = 4;
}
+ // CraftBukkit start
+ org.bukkit.entity.EntityType hatchingType = org.bukkit.entity.EntityType.CHICKEN;
+
+ net.minecraft.world.entity.Entity shooter = this.getOwner();
+ if (!hatching) {
+ i = 0;
+ }
+
+ net.minecraft.world.entity.Entity shooter = this.getOwner();
+ org.bukkit.entity.EntityType hatchingType = org.bukkit.entity.EntityType.CHICKEN;
+ if (shooter instanceof net.minecraft.server.level.ServerPlayer) {
+ org.bukkit.event.player.PlayerEggThrowEvent event = new org.bukkit.event.player.PlayerEggThrowEvent((org.bukkit.entity.Player) shooter.getBukkitEntity(), (org.bukkit.entity.Egg) this.getBukkitEntity(), hatching, (byte) i, hatchingType);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+ event.callEvent();
+
+ i = event.getNumHatches();
+ hatching = event.isHatching();
+ i = hatching ? event.getNumHatches() : 0; // If hatching is set to false, ensure child count is 0
+ hatchingType = event.getHatchingType();
+ // If hatching is set to false, ensure child count is 0
+ if (!hatching) {
+ i = 0;
+ }
+ }
+ // CraftBukkit end
+ // Paper start - Add ThrownEggHatchEvent
@@ -39,11 +35,12 @@
+ hatching = event.isHatching();
+ i = hatching ? event.getNumHatches() : 0; // If hatching is set to false, ensure child count is 0
+ hatchingType = event.getHatchingType();
+ EntityType<?> newEntityType = org.bukkit.craftbukkit.entity.CraftEntityType.bukkitToMinecraft(hatchingType);
+ // Paper end - Add ThrownEggHatchEvent
for (int i1 = 0; i1 < i; i1++) {
- Chicken chicken = EntityType.CHICKEN.create(this.level(), EntitySpawnReason.TRIGGERED);
+ net.minecraft.world.entity.Entity chicken = this.level().getWorld().makeEntity(new org.bukkit.Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F), hatchingType.getEntityClass()); // CraftBukkit
+ net.minecraft.world.entity.Entity chicken = newEntityType.create(this.level(), net.minecraft.world.entity.EntitySpawnReason.TRIGGERED); // CraftBukkit
if (chicken != null) {
- chicken.setAge(-24000);
+ // CraftBukkit start
@@ -51,7 +48,17 @@
+ ageable.setBaby();
+ }
+ // CraftBukkit end
chicken.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
chicken.snapTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
- Optional.ofNullable(this.getItem().get(DataComponents.CHICKEN_VARIANT))
- .flatMap(eitherHolder -> eitherHolder.unwrap(this.registryAccess()))
- .ifPresent(chicken::setVariant);
+ // CraftBukkit start
+ if (chicken instanceof Chicken realChicken) {
+ Optional.ofNullable(this.getItem().get(DataComponents.CHICKEN_VARIANT))
+ .flatMap(eitherHolder -> eitherHolder.unwrap(this.registryAccess()))
+ .ifPresent(realChicken::setVariant);
+ }
+ // CraftBukkit end
if (!chicken.fudgePositionAfterSizeChange(ZERO_SIZED_DIMENSIONS)) {
break;
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
+++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
@@ -126,11 +_,18 @@
@@ -122,11 +_,18 @@
Vec3 vec3 = this.oldPosition();
if (owner instanceof ServerPlayer serverPlayer) {
if (serverPlayer.connection.isAcceptingMessages()) {
@@ -14,13 +14,13 @@
if (this.random.nextFloat() < 0.05F && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
Endermite endermite = EntityType.ENDERMITE.create(serverLevel, EntitySpawnReason.TRIGGERED);
if (endermite != null) {
endermite.moveTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot());
endermite.snapTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot());
- serverLevel.addFreshEntity(endermite);
+ serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
}
}
@@ -138,15 +_,17 @@
@@ -134,15 +_,17 @@
owner.setPortalCooldown();
}
@@ -44,7 +44,7 @@
}
this.playSound(serverLevel, vec3);
@@ -162,9 +_,9 @@
@@ -158,9 +_,9 @@
this.playSound(serverLevel, vec3);
}
@@ -56,7 +56,7 @@
}
}
}
@@ -185,7 +_,7 @@
@@ -181,7 +_,7 @@
if (owner instanceof ServerPlayer serverPlayer
&& !owner.isAlive()
&& serverPlayer.serverLevel().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) {
@@ -65,7 +65,7 @@
} else {
super.tick();
}
@@ -212,7 +_,7 @@
@@ -208,7 +_,7 @@
public Entity teleport(TeleportTransition teleportTransition) {
Entity entity = super.teleport(teleportTransition);
if (entity != null) {
@@ -74,7 +74,7 @@
}
return entity;
@@ -220,7 +_,7 @@
@@ -216,7 +_,7 @@
@Override
public boolean canTeleport(Level fromLevel, Level toLevel) {

View File

@@ -7,7 +7,7 @@
- this.level().levelEvent(2002, this.blockPosition(), -13083194);
+ // CraftBukkit - moved to after event
int i = 3 + this.level().random.nextInt(5) + this.level().random.nextInt(5);
- ExperienceOrb.award((ServerLevel)this.level(), this.position(), i);
- ExperienceOrb.award((ServerLevel)this.level(), result.getLocation(), i);
- this.discard();
+ // CraftBukkit start
+ org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, result, i);
@@ -16,7 +16,7 @@
+ this.level().levelEvent(net.minecraft.world.level.block.LevelEvent.PARTICLES_SPELL_POTION_SPLASH, this.blockPosition(), net.minecraft.world.item.alchemy.PotionContents.BASE_POTION_COLOR);
+ }
+ // CraftBukkit end
+ ExperienceOrb.award((ServerLevel)this.level(), this.position(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper
+ ExperienceOrb.award((ServerLevel)this.level(), result.getLocation(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
}
}

View File

@@ -0,0 +1,27 @@
--- a/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java
+++ b/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java
@@ -30,7 +_,7 @@
}
@Override
- public void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity) {
+ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable net.minecraft.world.phys.HitResult hitResult) { // Paper - Pass HitResult // Paper - More projectile API
AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
if (this.getOwner() instanceof LivingEntity livingEntity) {
areaEffectCloud.setOwner(livingEntity);
@@ -42,6 +_,15 @@
areaEffectCloud.setWaitTime(10);
areaEffectCloud.setRadiusPerTick(-areaEffectCloud.getRadius() / areaEffectCloud.getDuration());
areaEffectCloud.applyComponentsFromItemStack(stack);
+ boolean noEffects = this.getItem().getOrDefault(net.minecraft.core.component.DataComponents.POTION_CONTENTS, net.minecraft.world.item.alchemy.PotionContents.EMPTY).hasEffects(); // Paper - Fix potions splash events
+ // CraftBukkit start
+ org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, hitResult, areaEffectCloud);
+ if (!(event.isCancelled() || areaEffectCloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !areaEffectCloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
level.addFreshEntity(areaEffectCloud);
+ } else {
+ areaEffectCloud.discard(null);
+ }
+ // CraftBukkit end
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
}

View File

@@ -1,193 +0,0 @@
--- a/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -82,51 +_,86 @@
@Override
protected void onHit(HitResult result) {
super.onHit(result);
+ // Paper start - More projectile API
+ this.splash(result);
+ }
+ public void splash(@Nullable HitResult result) {
+ // Paper end - More projectile API
if (this.level() instanceof ServerLevel serverLevel) {
ItemStack item = this.getItem();
PotionContents potionContents = item.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
+ boolean showParticles = true; // Paper - Fix potions splash events
if (potionContents.is(Potions.WATER)) {
- this.applyWater(serverLevel);
- } else if (potionContents.hasEffects()) {
+ showParticles = this.applyWater(serverLevel, result); // Paper - Fix potions splash events
+ } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
if (this.isLingering()) {
- this.makeAreaOfEffectCloud(potionContents);
+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass HitResult // Paper
} else {
- this.applySplash(
- serverLevel, potionContents.getAllEffects(), result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null
+ showParticles = this.applySplash( // Paper - Fix potions splash events
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass HitResult // Paper - More projectile API
);
}
}
+ if (showParticles) { // Paper - Fix potions splash events
int i = potionContents.potion().isPresent() && potionContents.potion().get().value().hasInstantEffects() ? 2007 : 2002;
serverLevel.levelEvent(i, this.blockPosition(), potionContents.getColor());
- this.discard();
+ } // Paper - Fix potions splash events
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
}
}
- private void applyWater(ServerLevel level) {
+ private static final Predicate<LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+
+ private boolean applyWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
- for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, WATER_SENSITIVE_OR_ON_FIRE)) {
+ // Paper start - Fix potions splash events
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>();
+ java.util.Set<org.bukkit.entity.LivingEntity> rehydrate = new java.util.HashSet<>();
+ java.util.Set<org.bukkit.entity.LivingEntity> extinguish = new java.util.HashSet<>();
+ for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, APPLY_WATER_GET_ENTITIES_PREDICATE)) {
+ if (livingEntity instanceof Axolotl axolotl) {
+ rehydrate.add(((org.bukkit.entity.Axolotl) axolotl.getBukkitEntity()));
+ }
+ // Paper end - Fix potions splash events
double d = this.distanceToSqr(livingEntity);
if (d < 16.0) {
if (livingEntity.isSensitiveToWater()) {
- livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); // Paper - Fix potions splash events
}
if (livingEntity.isOnFire() && livingEntity.isAlive()) {
- livingEntity.extinguishFire();
+ extinguish.add(livingEntity.getBukkitLivingEntity()); // Paper - Fix potions splash events
}
}
}
- for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) {
- axolotl.rehydrate();
+ // Paper start - Fix potions splash events
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
+ this, result, affected, rehydrate, extinguish
+ );
+ if (!event.isCancelled()) {
+ for (org.bukkit.entity.LivingEntity affectedEntity : event.getToDamage()) {
+ ((org.bukkit.craftbukkit.entity.CraftLivingEntity) affectedEntity).getHandle().hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ }
+ for (org.bukkit.entity.LivingEntity toExtinguish : event.getToExtinguish()) {
+ ((org.bukkit.craftbukkit.entity.CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
+ }
+ for (org.bukkit.entity.LivingEntity toRehydrate : event.getToRehydrate()) {
+ if (((org.bukkit.craftbukkit.entity.CraftLivingEntity) toRehydrate).getHandle() instanceof Axolotl axolotl) {
+ axolotl.rehydrate();
+ }
+ }
+ // Paper end - Fix potions splash events
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
- private void applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity) {
+ private boolean applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - Fix potions splash events & More projectile API
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(LivingEntity.class, aabb);
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>(); // CraftBukkit
if (!entitiesOfClass.isEmpty()) {
Entity effectSource = this.getEffectSource();
@@ -135,12 +_,31 @@
double d = this.distanceToSqr(livingEntity);
if (d < 16.0) {
double d1;
+ // Paper - diff on change, used when calling the splash event for water splash potions
if (livingEntity == entity) {
d1 = 1.0;
} else {
d1 = 1.0 - Math.sqrt(d) / 4.0;
}
+ affected.put(livingEntity.getBukkitLivingEntity(), d1);
+ // CraftBukkit start
+ }
+ }
+ }
+ }
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, result, affected);
+ if (!event.isCancelled() && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
+ Entity effectSource = this.getEffectSource();
+ for (org.bukkit.entity.LivingEntity victim : event.getAffectedEntities()) {
+ if (!(victim instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity craftLivingEntity)) {
+ continue;
+ }
+ LivingEntity livingEntity = craftLivingEntity.getHandle();
+ double d1 = event.getIntensity(victim);
+ {
+ {
+ // CraftBukkit end
for (MobEffectInstance mobEffectInstance : effects) {
Holder<MobEffect> effect = mobEffectInstance.getEffect();
if (effect.value().isInstantenous()) {
@@ -151,7 +_,7 @@
effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
);
if (!mobEffectInstance1.endsWithin(20)) {
- livingEntity.addEffect(mobEffectInstance1, effectSource);
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
}
}
}
@@ -159,9 +_,10 @@
}
}
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
- private void makeAreaOfEffectCloud(PotionContents potionContents) {
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - More projectile API
AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
if (this.getOwner() instanceof LivingEntity livingEntity) {
areaEffectCloud.setOwner(livingEntity);
@@ -172,7 +_,16 @@
areaEffectCloud.setWaitTime(10);
areaEffectCloud.setRadiusPerTick(-areaEffectCloud.getRadius() / areaEffectCloud.getDuration());
areaEffectCloud.setPotionContents(potionContents);
- this.level().addFreshEntity(areaEffectCloud);
+ boolean noEffects = potionContents.hasEffects(); // Paper - Fix potions splash events
+ // CraftBukkit start
+ org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, result, areaEffectCloud);
+ if (!(event.isCancelled() || areaEffectCloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !areaEffectCloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
+ this.level().addFreshEntity(areaEffectCloud);
+ } else {
+ areaEffectCloud.discard(null); // add Bukkit remove cause
+ }
+ // CraftBukkit end
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
public boolean isLingering() {
@@ -182,13 +_,19 @@
private void dowseFire(BlockPos pos) {
BlockState blockState = this.level().getBlockState(pos);
if (blockState.is(BlockTags.FIRE)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
this.level().destroyBlock(pos, false, this);
+ } // CraftBukkit
} else if (AbstractCandleBlock.isLit(blockState)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
+ } // CraftBukkit
} else if (CampfireBlock.isLitCampfire(blockState)) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
this.level().levelEvent(null, 1009, pos, 0);
CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)));
+ } // CraftBukkit
}
}

View File

@@ -0,0 +1,65 @@
--- a/net/minecraft/world/entity/projectile/ThrownSplashPotion.java
+++ b/net/minecraft/world/entity/projectile/ThrownSplashPotion.java
@@ -36,12 +_,13 @@
}
@Override
- public void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity) {
+ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable net.minecraft.world.phys.HitResult hitResult) { // Paper - Add HitResult parameter // Paper - More projectile API
PotionContents potionContents = stack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
float orDefault = stack.getOrDefault(DataComponents.POTION_DURATION_SCALE, 1.0F);
Iterable<MobEffectInstance> allEffects = potionContents.getAllEffects();
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
List<LivingEntity> entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, aabb);
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>(); // CraftBukkit
if (!entitiesOfClass.isEmpty()) {
Entity effectSource = this.getEffectSource();
@@ -50,12 +_,31 @@
double d = this.distanceToSqr(livingEntity);
if (d < 16.0) {
double d1;
+ // Paper - diff on change, used when calling the splash event for water splash potions
if (livingEntity == entity) {
d1 = 1.0;
} else {
d1 = 1.0 - Math.sqrt(d) / 4.0;
}
+ // CraftBukkit start
+ affected.put(livingEntity.getBukkitLivingEntity(), d1);
+ }
+ }
+ }
+ }
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, hitResult, affected);
+ if (!event.isCancelled() && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
+ Entity effectSource = this.getEffectSource();
+ for (org.bukkit.entity.LivingEntity victim : event.getAffectedEntities()) {
+ if (!(victim instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity craftLivingEntity)) {
+ continue;
+ }
+ LivingEntity livingEntity = craftLivingEntity.getHandle();
+ double d1 = event.getIntensity(victim);
+ {
+ {
+ // CraftBukkit end
for (MobEffectInstance mobEffectInstance : allEffects) {
Holder<MobEffect> effect = mobEffectInstance.getEffect();
if (effect.value().isInstantenous()) {
@@ -66,7 +_,7 @@
effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
);
if (!mobEffectInstance1.endsWithin(20)) {
- livingEntity.addEffect(mobEffectInstance1, effectSource);
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
}
}
}
@@ -74,5 +_,6 @@
}
}
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ThrownTrident.java
+++ b/net/minecraft/world/entity/projectile/ThrownTrident.java
@@ -32,16 +_,19 @@
@@ -33,16 +_,19 @@
public ThrownTrident(EntityType<? extends ThrownTrident> entityType, Level level) {
super(entityType, level);
@@ -20,7 +20,7 @@
this.entityData.set(ID_LOYALTY, this.getLoyaltyFromItem(pickupItemStack));
this.entityData.set(ID_FOIL, pickupItemStack.hasFoil());
}
@@ -67,10 +_,10 @@
@@ -68,10 +_,10 @@
this.spawnAtLocation(serverLevel, this.getPickupItem(), 0.1F);
}
@@ -33,7 +33,7 @@
return;
}
@@ -99,6 +_,20 @@
@@ -100,6 +_,20 @@
return this.entityData.get(ID_FOIL);
}
@@ -54,12 +54,12 @@
@Nullable
@Override
protected EntityHitResult findHitEntity(Vec3 startVec, Vec3 endVec) {
@@ -108,7 +_,7 @@
@@ -109,7 +_,7 @@
@Override
protected void onHitEntity(EntityHitResult result) {
Entity entity = result.getEntity();
- float f = 8.0F;
+ float f = (float) this.getBaseDamage(); // Paper - Allow trident custom damage
+ float f = (float) this.baseDamage; // Paper - Allow trident custom damage
Entity owner = this.getOwner();
DamageSource damageSource = this.damageSources().trident(this, (Entity)(owner == null ? this : owner));
if (this.level() instanceof ServerLevel serverLevel) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/WitherSkull.java
+++ b/net/minecraft/world/entity/projectile/WitherSkull.java
@@ -65,11 +_,11 @@
@@ -66,11 +_,11 @@
if (var8.isAlive()) {
EnchantmentHelper.doPostAttackEffects(serverLevel, var8, damageSource);
} else {
@@ -14,7 +14,7 @@
}
if (flag && var8 instanceof LivingEntity livingEntityx) {
@@ -81,7 +_,7 @@
@@ -82,7 +_,7 @@
}
if (i > 0) {
@@ -23,7 +23,7 @@
}
}
}
@@ -91,8 +_,15 @@
@@ -92,8 +_,13 @@
protected void onHit(HitResult result) {
super.onHit(result);
if (!this.level().isClientSide) {
@@ -31,9 +31,7 @@
- this.discard();
+ // CraftBukkit start
+ org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ if (event.callEvent()) {
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
+ }
+ // CraftBukkit end