mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
net.minecraft.world.entity.projectile
This commit is contained in:
parent
cb5feced53
commit
9ef230aa31
46 changed files with 1729 additions and 2211 deletions
|
@ -0,0 +1,224 @@
|
|||
--- 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;
|
||||
@@ -74,6 +_,16 @@
|
||||
@Nullable
|
||||
private ItemStack firedFromWeapon = null;
|
||||
|
||||
+ // Spigot Start
|
||||
+ @Override
|
||||
+ public void inactiveTick() {
|
||||
+ if (this.isInGround()) {
|
||||
+ this.life += 1;
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
}
|
||||
@@ -87,7 +_,13 @@
|
||||
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));
|
||||
Unit unit = pickupItemStack.remove(DataComponents.INTANGIBLE_PROJECTILE);
|
||||
@@ -112,8 +_,8 @@
|
||||
protected AbstractArrow(
|
||||
EntityType<? extends AbstractArrow> entityType, LivingEntity owner, Level level, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon
|
||||
) {
|
||||
- this(entityType, owner.getX(), owner.getEyeY() - 0.1F, owner.getZ(), level, pickupItemStack, firedFromWeapon);
|
||||
- this.setOwner(owner);
|
||||
+ this(entityType, owner.getX(), owner.getEyeY() - 0.1F, owner.getZ(), level, pickupItemStack, firedFromWeapon, owner); // CraftBukkit
|
||||
+ // this.setOwner(owner); // SPIGOT-7744 - Moved to the above constructor
|
||||
}
|
||||
|
||||
public void setSoundEvent(SoundEvent soundEvent) {
|
||||
@@ -209,6 +_,7 @@
|
||||
this.applyEffectsFromBlocks();
|
||||
}
|
||||
} else {
|
||||
+ if (this.tickCount > 200) this.tickDespawn(); // Paper - tick despawnCounter regardless after 10 seconds
|
||||
this.inGroundTime = 0;
|
||||
Vec3 vec31 = this.position();
|
||||
if (this.isInWater()) {
|
||||
@@ -275,12 +_,12 @@
|
||||
|
||||
if (entityHitResult == null) {
|
||||
if (this.isAlive() && hitResult.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(hitResult);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResult); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
break;
|
||||
} else if (this.isAlive() && !this.noPhysics) {
|
||||
- ProjectileDeflection projectileDeflection = this.hitTargetOrDeflectSelf(entityHitResult);
|
||||
+ ProjectileDeflection projectileDeflection = this.preHitTargetOrDeflectSelf(entityHitResult); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
if (this.getPierceLevel() > 0 && projectileDeflection == ProjectileDeflection.NONE) {
|
||||
continue;
|
||||
@@ -313,6 +_,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
+ @Override
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) {
|
||||
+ if (hitResult instanceof EntityHitResult entityHitResult && this.hitCancelled && this.getPierceLevel() > 0) {
|
||||
+ if (this.piercingIgnoreEntityIds == null) {
|
||||
+ this.piercingIgnoreEntityIds = new IntOpenHashSet(5);
|
||||
+ }
|
||||
+ this.piercingIgnoreEntityIds.add(entityHitResult.getEntity().getId());
|
||||
+ }
|
||||
+ return super.preHitTargetOrDeflectSelf(hitResult);
|
||||
+ }
|
||||
+ // Paper end - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
+
|
||||
@Override
|
||||
protected double getDefaultGravity() {
|
||||
return 0.05;
|
||||
@@ -347,8 +_,8 @@
|
||||
|
||||
protected void tickDespawn() {
|
||||
this.life++;
|
||||
- if (this.life >= 1200) {
|
||||
- this.discard();
|
||||
+ if (this.life >= (this.pickup == Pickup.CREATIVE_ONLY ? this.level().paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (this.pickup == Pickup.DISALLOWED ? this.level().paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - Configurable non-player arrow despawn rate; TODO: Extract this to init?
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,9 +_,9 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double x, double y, double z) {
|
||||
+ public void push(double x, double y, double z, @Nullable Entity pushingEntity) { // Paper - add push source entity param
|
||||
if (!this.isInGround()) {
|
||||
- super.push(x, y, z);
|
||||
+ super.push(x, y, z, pushingEntity); // Paper - add push source entity param
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -420,10 +_,17 @@
|
||||
livingEntity.setLastHurtMob(entity);
|
||||
}
|
||||
|
||||
+ if (this.isCritArrow()) damageSource = damageSource.critical(); // Paper - add critical damage API
|
||||
boolean flag = entity.getType() == EntityType.ENDERMAN;
|
||||
int remainingFireTicks = entity.getRemainingFireTicks();
|
||||
if (this.isOnFire() && !flag) {
|
||||
- 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()) {
|
||||
+ entity.igniteForSeconds(combustEvent.getDuration(), false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
if (entity.hurtOrSimulate(damageSource, ceil)) {
|
||||
@@ -461,7 +_,7 @@
|
||||
|
||||
this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
|
||||
if (this.getPierceLevel() <= 0) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
} else {
|
||||
entity.setRemainingFireTicks(remainingFireTicks);
|
||||
@@ -472,7 +_,7 @@
|
||||
this.spawnAtLocation(serverLevel2, this.getPickupItem(), 0.1F);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -485,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) {
|
||||
- entity.push(vec3.x, 0.1, vec3.z);
|
||||
+ entity.push(vec3.x, 0.1, vec3.z, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 @@
|
||||
|
||||
@Override
|
||||
public void setOwner(@Nullable Entity entity) {
|
||||
+ // Paper start - Fix PickupStatus getting reset
|
||||
+ this.setOwner(entity, true);
|
||||
+ }
|
||||
+
|
||||
+ public void setOwner(@Nullable Entity entity, boolean resetPickup) {
|
||||
+ // Paper end - Fix PickupStatus getting reset
|
||||
super.setOwner(entity);
|
||||
+ if (!resetPickup) return; // Paper - Fix PickupStatus getting reset
|
||||
|
||||
this.pickup = switch (entity) {
|
||||
case Player player when this.pickup == AbstractArrow.Pickup.DISALLOWED -> AbstractArrow.Pickup.ALLOWED;
|
||||
@@ -628,9 +_,24 @@
|
||||
@Override
|
||||
public void playerTouch(Player entity) {
|
||||
if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) {
|
||||
- if (this.tryPickup(entity)) {
|
||||
+ // 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);
|
||||
+ org.bukkit.event.player.PlayerPickupArrowEvent event = new org.bukkit.event.player.PlayerPickupArrowEvent((org.bukkit.entity.Player) entity.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.level().getCraftServer(), item), (org.bukkit.entity.AbstractArrow) this.getBukkitEntity());
|
||||
+ // event.setCancelled(!entityhuman.canPickUpLoot); TODO
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ itemstack = item.getItem();
|
||||
+ }
|
||||
+
|
||||
+ if ((this.pickup == AbstractArrow.Pickup.ALLOWED && entity.getInventory().add(itemstack)) || (this.pickup == AbstractArrow.Pickup.CREATIVE_ONLY && entity.getAbilities().instabuild)) {
|
||||
+ // CraftBukkit end
|
||||
entity.take(this, 1);
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
--- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
@@ -19,6 +_,8 @@
|
||||
public static final double INITAL_ACCELERATION_POWER = 0.1;
|
||||
public static final double DEFLECTION_SCALE = 0.5;
|
||||
public double accelerationPower = 0.1;
|
||||
+ public float bukkitYield = 1; // CraftBukkit
|
||||
+ public boolean isIncendiary = true; // CraftBukkit
|
||||
|
||||
protected AbstractHurtingProjectile(EntityType<? extends AbstractHurtingProjectile> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -83,12 +_,12 @@
|
||||
}
|
||||
|
||||
if (hitResultOnMoveVector.getType() != HitResult.Type.MISS && this.isAlive()) {
|
||||
- this.hitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
}
|
||||
|
||||
this.createParticleTrail();
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
--- 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
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
--- a/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -52,9 +_,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), entitiesOfClass.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events
|
||||
this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
- this.level().addFreshEntity(areaEffectCloud);
|
||||
- this.discard();
|
||||
+ this.level().addFreshEntity(areaEffectCloud, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EXPLOSION); // Paper - use correct spawn reason
|
||||
+ } else areaEffectCloud.discard(null); // Paper - EnderDragon Events
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
--- a/net/minecraft/world/entity/projectile/EvokerFangs.java
|
||||
+++ b/net/minecraft/world/entity/projectile/EvokerFangs.java
|
||||
@@ -109,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (--this.lifeTicks < 0) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,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().customEventDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API
|
||||
} else {
|
||||
if (owner.isAlliedTo(target)) {
|
||||
return;
|
|
@ -1,16 +1,6 @@
|
|||
--- a/net/minecraft/world/entity/projectile/EyeOfEnder.java
|
||||
+++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java
|
||||
@@ -17,6 +17,9 @@
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class EyeOfEnder extends Entity implements ItemSupplier {
|
||||
|
||||
@@ -73,6 +76,11 @@
|
||||
@@ -70,6 +_,11 @@
|
||||
}
|
||||
|
||||
public void signalTo(BlockPos pos) {
|
||||
|
@ -19,10 +9,10 @@
|
|||
+ }
|
||||
+ public void signalTo(BlockPos pos, boolean update) {
|
||||
+ // Paper end - Change EnderEye target without changing other things
|
||||
double d0 = (double) pos.getX();
|
||||
int i = pos.getY();
|
||||
double d1 = (double) pos.getZ();
|
||||
@@ -90,8 +98,10 @@
|
||||
double d = pos.getX();
|
||||
int y = pos.getY();
|
||||
double d1 = pos.getZ();
|
||||
@@ -86,8 +_,10 @@
|
||||
this.tz = d1;
|
||||
}
|
||||
|
||||
|
@ -33,24 +23,24 @@
|
|||
}
|
||||
|
||||
@Override
|
||||
@@ -153,7 +163,7 @@
|
||||
++this.life;
|
||||
@@ -161,7 +_,7 @@
|
||||
this.life++;
|
||||
if (this.life > 80 && !this.level().isClientSide) {
|
||||
this.playSound(SoundEvents.ENDER_EYE_DEATH, 1.0F, 1.0F);
|
||||
- this.discard();
|
||||
+ this.discard(this.surviveAfterDeath ? EntityRemoveEvent.Cause.DROP : EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
+ this.discard(this.surviveAfterDeath ? org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP : org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
if (this.surviveAfterDeath) {
|
||||
this.level().addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), this.getItem()));
|
||||
} else {
|
||||
@@ -174,7 +184,12 @@
|
||||
@@ -181,7 +_,12 @@
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
if (nbt.contains("Item", 10)) {
|
||||
- this.setItem((ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem()));
|
||||
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) ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem());
|
||||
+ if (!itemstack.isEmpty()) {
|
||||
+ this.setItem(itemstack);
|
||||
+ ItemStack itemStack = ItemStack.parse(this.registryAccess(), compound.getCompound("Item")).orElse(this.getDefaultItem());
|
||||
+ if (!itemStack.isEmpty()) {
|
||||
+ this.setItem(itemStack);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else {
|
|
@ -0,0 +1,16 @@
|
|||
--- 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());
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -43,6 +_,7 @@
|
||||
public int lifetime;
|
||||
@Nullable
|
||||
public LivingEntity attachedToEntity;
|
||||
+ @Nullable public java.util.UUID spawningEntity; // Paper
|
||||
|
||||
public FireworkRocketEntity(EntityType<? extends FireworkRocketEntity> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -84,6 +_,26 @@
|
||||
this.setOwner(shooter);
|
||||
}
|
||||
|
||||
+ // Spigot Start - copied from tick
|
||||
+ @Override
|
||||
+ public void inactiveTick() {
|
||||
+ this.life += 1;
|
||||
+
|
||||
+ if (this.life > this.lifetime) {
|
||||
+ Level world = this.level();
|
||||
+
|
||||
+ if (world instanceof ServerLevel serverLevel) {
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(serverLevel);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
@Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
||||
builder.define(DATA_ID_FIREWORKS_ITEM, getDefaultItem());
|
||||
@@ -158,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (!this.noPhysics && this.isAlive() && hitResultOnMoveVector.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResultOnMoveVector); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
|
||||
@@ -182,7 +_,11 @@
|
||||
}
|
||||
|
||||
if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) {
|
||||
- this.explode(serverLevel);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(serverLevel);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,14 +_,18 @@
|
||||
level.broadcastEntityEvent(this, (byte)17);
|
||||
this.gameEvent(GameEvent.EXPLODE, this.getOwner());
|
||||
this.dealExplosionDamage(level);
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHitEntity(EntityHitResult result) {
|
||||
super.onHitEntity(result);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
- this.explode(serverLevel);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(serverLevel);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +_,11 @@
|
||||
BlockPos blockPos = new BlockPos(result.getBlockPos());
|
||||
this.level().getBlockState(blockPos).entityInside(this.level(), blockPos, this);
|
||||
if (this.level() instanceof ServerLevel serverLevel && this.hasExplosion()) {
|
||||
- this.explode(serverLevel);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(serverLevel);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
super.onHitBlock(result);
|
||||
@@ -278,6 +_,11 @@
|
||||
compound.putInt("LifeTime", this.lifetime);
|
||||
compound.put("FireworksItem", this.getItem().save(this.registryAccess()));
|
||||
compound.putBoolean("ShotAtAngle", this.entityData.get(DATA_SHOT_AT_ANGLE));
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ compound.putUUID("SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
|
||||
private List<FireworkExplosion> getExplosions() {
|
|
@ -0,0 +1,281 @@
|
|||
--- a/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -66,10 +_,26 @@
|
||||
private final int luck;
|
||||
private final int lureSpeed;
|
||||
|
||||
+ // CraftBukkit start - Extra variables to enable modification of fishing wait time, values are minecraft defaults
|
||||
+ public int minWaitTime = 100;
|
||||
+ public int maxWaitTime = 600;
|
||||
+ public int minLureTime = 20;
|
||||
+ public int maxLureTime = 80;
|
||||
+ public float minLureAngle = 0.0F;
|
||||
+ public float maxLureAngle = 360.0F;
|
||||
+ public boolean applyLure = true;
|
||||
+ public boolean rainInfluenced = true;
|
||||
+ public boolean skyInfluenced = true;
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
private FishingHook(EntityType<? extends FishingHook> entityType, Level level, int luck, int lureSpeed) {
|
||||
super(entityType, level);
|
||||
this.luck = Math.max(0, luck);
|
||||
this.lureSpeed = Math.max(0, lureSpeed);
|
||||
+ // Paper start - Configurable fishing time ranges
|
||||
+ this.minWaitTime = level.paperConfig().fishingTimeRange.minimum;
|
||||
+ this.maxWaitTime = level.paperConfig().fishingTimeRange.maximum;
|
||||
+ // Paper end - Configurable fishing time ranges
|
||||
}
|
||||
|
||||
public FishingHook(EntityType<? extends FishingHook> entityType, Level level) {
|
||||
@@ -147,12 +_,12 @@
|
||||
super.tick();
|
||||
Player playerOwner = this.getPlayerOwner();
|
||||
if (playerOwner == null) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else if (this.level().isClientSide || !this.shouldStopFishing(playerOwner)) {
|
||||
if (this.onGround()) {
|
||||
this.life++;
|
||||
if (this.life >= 1200) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -251,14 +_,14 @@
|
||||
if (!player.isRemoved() && player.isAlive() && (isFishingRod || isFishingRod1) && !(this.distanceToSqr(player) > 1024.0)) {
|
||||
return false;
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCollision() {
|
||||
HitResult hitResultOnMoveVector = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity);
|
||||
- this.hitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,11 +_,11 @@
|
||||
ServerLevel serverLevel = (ServerLevel)this.level();
|
||||
int i = 1;
|
||||
BlockPos blockPos = pos.above();
|
||||
- if (this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockPos)) {
|
||||
+ if (this.rainInfluenced && this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockPos)) { // CraftBukkit
|
||||
i++;
|
||||
}
|
||||
|
||||
- if (this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockPos)) {
|
||||
+ if (this.skyInfluenced && this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockPos)) { // CraftBukkit
|
||||
i--;
|
||||
}
|
||||
|
||||
@@ -303,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);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
} else if (this.timeUntilHooked > 0) {
|
||||
this.timeUntilHooked -= i;
|
||||
@@ -326,6 +_,13 @@
|
||||
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()) {
|
||||
+ 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 @@
|
||||
}
|
||||
|
||||
if (this.timeUntilLured <= 0) {
|
||||
- this.fishAngle = Mth.nextFloat(this.random, 0.0F, 360.0F);
|
||||
- this.timeUntilHooked = Mth.nextInt(this.random, 20, 80);
|
||||
+ // CraftBukkit start - logic to modify fishing wait time, lure time, and lure angle
|
||||
+ this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
|
||||
+ this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add missing fishing event state
|
||||
+ if (this.getPlayerOwner() != null) {
|
||||
+ 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.LURED);
|
||||
+ if (!playerFishEvent.callEvent()) {
|
||||
+ this.timeUntilHooked = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing fishing event state
|
||||
}
|
||||
} 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
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - more projectile api - extract time until lured reset logic
|
||||
+ public void resetTimeUntilLured() {
|
||||
+ this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
||||
+ this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
||||
+ }
|
||||
+ // Paper end - more projectile api - extract time until lured reset logic
|
||||
|
||||
public boolean calculateOpenWater(BlockPos pos) {
|
||||
FishingHook.OpenWaterType openWaterType = FishingHook.OpenWaterType.INVALID;
|
||||
@@ -443,15 +_,34 @@
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
}
|
||||
|
||||
+
|
||||
+ // Paper start - Add hand parameter to PlayerFishEvent
|
||||
+ @Deprecated
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
public int retrieve(ItemStack stack) {
|
||||
+ return this.retrieve(net.minecraft.world.InteractionHand.MAIN_HAND, stack);
|
||||
+ }
|
||||
+
|
||||
+ public int retrieve(net.minecraft.world.InteractionHand hand, ItemStack stack) {
|
||||
+ // Paper end - Add hand parameter to PlayerFishEvent
|
||||
Player playerOwner = this.getPlayerOwner();
|
||||
if (!this.level().isClientSide && playerOwner != null && !this.shouldStopFishing(playerOwner)) {
|
||||
int i = 0;
|
||||
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()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (this.hookedIn != null) { // Paper - re-check to see if there is a hooked entity
|
||||
+ // CraftBukkit end
|
||||
this.pullEntity(this.hookedIn);
|
||||
CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)playerOwner, stack, this, Collections.emptyList());
|
||||
this.level().broadcastEntityEvent(this, (byte)31);
|
||||
i = this.hookedIn instanceof ItemEntity ? 3 : 5;
|
||||
+ } // Paper - re-check to see if there is a hooked entity
|
||||
} else if (this.nibble > 0) {
|
||||
LootParams lootParams = new LootParams.Builder((ServerLevel)this.level())
|
||||
.withParameter(LootContextParams.ORIGIN, this.position())
|
||||
@@ -464,19 +_,43 @@
|
||||
CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)playerOwner, stack, this, randomItems);
|
||||
|
||||
for (ItemStack itemStack : randomItems) {
|
||||
- ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemStack);
|
||||
+ // Paper start - new ItemEntity would throw if for whatever reason (mostly shitty datapacks) the itemStack turns out to be empty
|
||||
+ // if the item stack is empty we instead just have our itemEntity as null
|
||||
+ ItemEntity itemEntity = null;
|
||||
+ if (!itemStack.isEmpty()) {
|
||||
+ itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) playerOwner.getBukkitEntity(), itemEntity != null ? itemEntity.getBukkitEntity() : null, (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()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
double d = playerOwner.getX() - this.getX();
|
||||
double d1 = playerOwner.getY() - this.getY();
|
||||
double d2 = playerOwner.getZ() - this.getZ();
|
||||
double d3 = 0.1;
|
||||
- itemEntity.setDeltaMovement(d * 0.1, d1 * 0.1 + Math.sqrt(Math.sqrt(d * d + d1 * d1 + d2 * d2)) * 0.08, d2 * 0.1);
|
||||
- this.level().addFreshEntity(itemEntity);
|
||||
- playerOwner.level()
|
||||
- .addFreshEntity(
|
||||
- new ExperienceOrb(
|
||||
- playerOwner.level(), playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5, this.random.nextInt(6) + 1
|
||||
- )
|
||||
- );
|
||||
+ // Paper start - entity item can be null, so we need to check against this
|
||||
+ if (itemEntity != null) {
|
||||
+ itemEntity.setDeltaMovement(d * 0.1, d1 * 0.1 + Math.sqrt(Math.sqrt(d * d + d1 * d1 + d2 * d2)) * 0.08, d2 * 0.1);
|
||||
+ this.level().addFreshEntity(itemEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
|
||||
+ if (playerFishEvent.getExpToDrop() > 0) {
|
||||
+ playerOwner.level()
|
||||
+ .addFreshEntity(
|
||||
+ new ExperienceOrb(
|
||||
+ playerOwner.level(), playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this // Paper
|
||||
+ )
|
||||
+ );
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (itemStack.is(ItemTags.FISHES)) {
|
||||
playerOwner.awardStat(Stats.FISH_CAUGHT, 1);
|
||||
}
|
||||
@@ -486,10 +_,27 @@
|
||||
}
|
||||
|
||||
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()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
i = 2;
|
||||
}
|
||||
+ // 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()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return i;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -520,8 +_,15 @@
|
||||
|
||||
@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
|
||||
this.updateOwnerInfo(null);
|
||||
- super.remove(reason);
|
||||
+ super.remove(reason, cause); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -570,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);
|
||||
- this.discard();
|
||||
+ this.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
--- a/net/minecraft/world/entity/projectile/LargeFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/LargeFireball.java
|
||||
@@ -18,11 +_,13 @@
|
||||
|
||||
public LargeFireball(EntityType<? extends LargeFireball> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
|
||||
}
|
||||
|
||||
public LargeFireball(Level level, LivingEntity owner, Vec3 movement, int explosionPower) {
|
||||
super(EntityType.FIREBALL, owner, movement, level);
|
||||
this.explosionPower = explosionPower;
|
||||
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,8 +_,16 @@
|
||||
super.onHit(result);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
boolean _boolean = serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
||||
- this.level().explode(this, this.getX(), this.getY(), this.getZ(), this.explosionPower, _boolean, Level.ExplosionInteraction.MOB);
|
||||
- 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
|
||||
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +_,8 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
--- a/net/minecraft/world/entity/projectile/LlamaSpit.java
|
||||
+++ b/net/minecraft/world/entity/projectile/LlamaSpit.java
|
||||
@@ -43,16 +_,16 @@
|
||||
super.tick();
|
||||
Vec3 deltaMovement = this.getDeltaMovement();
|
||||
HitResult hitResultOnMoveVector = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity);
|
||||
- this.hitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResultOnMoveVector); // CraftBukkit - projectile hit event
|
||||
double d = this.getX() + deltaMovement.x;
|
||||
double d1 = this.getY() + deltaMovement.y;
|
||||
double d2 = this.getZ() + deltaMovement.z;
|
||||
this.updateRotation();
|
||||
float f = 0.99F;
|
||||
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()) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
this.setDeltaMovement(deltaMovement.scale(0.99F));
|
||||
this.applyGravity();
|
||||
@@ -76,7 +_,7 @@
|
||||
protected void onHitBlock(BlockHitResult result) {
|
||||
super.onHitBlock(result);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -43,6 +_,7 @@
|
||||
public boolean hasBeenShot;
|
||||
@Nullable
|
||||
private Entity lastDeflectedBy;
|
||||
+ protected boolean hitCancelled = false; // CraftBukkit
|
||||
|
||||
Projectile(EntityType<? extends Projectile> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -53,15 +_,36 @@
|
||||
this.ownerUUID = owner.getUUID();
|
||||
this.cachedOwner = owner;
|
||||
}
|
||||
- }
|
||||
+ // Paper start - Refresh ProjectileSource for projectiles
|
||||
+ else {
|
||||
+ this.ownerUUID = null;
|
||||
+ this.cachedOwner = null;
|
||||
+ this.projectileSource = null;
|
||||
+ }
|
||||
+ // Paper end - Refresh ProjectileSource for projectiles
|
||||
+ this.refreshProjectileSource(false); // Paper
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Refresh ProjectileSource for projectiles
|
||||
+ public void refreshProjectileSource(boolean fillCache) {
|
||||
+ if (fillCache) {
|
||||
+ this.getOwner();
|
||||
+ }
|
||||
+ if (this.cachedOwner != null && !this.cachedOwner.isRemoved() && this.projectileSource == null && this.cachedOwner.getBukkitEntity() instanceof org.bukkit.projectiles.ProjectileSource projSource) {
|
||||
+ this.projectileSource = projSource;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Refresh ProjectileSource for projectiles
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity getOwner() {
|
||||
if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) {
|
||||
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
|
||||
return this.cachedOwner;
|
||||
} else if (this.ownerUUID != null) {
|
||||
this.cachedOwner = this.findOwner(this.ownerUUID);
|
||||
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
|
||||
return this.cachedOwner;
|
||||
} else {
|
||||
return null;
|
||||
@@ -98,6 +_,7 @@
|
||||
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 +_,22 @@
|
||||
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();
|
||||
+ // Paper start - allow disabling relative velocity
|
||||
+ if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) {
|
||||
this.setDeltaMovement(this.getDeltaMovement().add(knownMovement.x, shooter.onGround() ? 0.0 : knownMovement.y, knownMovement.z));
|
||||
+ }
|
||||
+ // Paper end - allow disabling relative velocity
|
||||
}
|
||||
|
||||
public static <T extends Projectile> T spawnProjectileFromRotation(
|
||||
Projectile.ProjectileFactory<T> factory, ServerLevel level, ItemStack spawnedFrom, LivingEntity owner, float z, float velocity, float innaccuracy
|
||||
) {
|
||||
- return spawnProjectile(
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ return spawnProjectileFromRotationDelayed(factory, level, spawnedFrom, owner, z, velocity, innaccuracy).spawn();
|
||||
+ }
|
||||
+ public static <T extends Projectile> Delayed<T> spawnProjectileFromRotationDelayed(Projectile.ProjectileFactory<T> factory, ServerLevel level, ItemStack spawnedFrom, LivingEntity owner, float z, float velocity, float innaccuracy) {
|
||||
+ return spawnProjectileDelayed(
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
factory.create(level, owner, spawnedFrom),
|
||||
level,
|
||||
spawnedFrom,
|
||||
@@ -200,7 +_,22 @@
|
||||
float velocity,
|
||||
float inaccuracy
|
||||
) {
|
||||
- return spawnProjectile(factory.create(level, owner, spawnedFrom), level, spawnedFrom, projectile -> projectile.shoot(x, y, z, velocity, inaccuracy));
|
||||
+ // Paper start - fixes and addition to spawn reason API
|
||||
+ return Projectile.spawnProjectileUsingShootDelayed(factory, level, spawnedFrom, owner, x, y, z, velocity, inaccuracy).spawn();
|
||||
+ }
|
||||
+ public static <T extends Projectile> Delayed<T> spawnProjectileUsingShootDelayed(
|
||||
+ Projectile.ProjectileFactory<T> factory,
|
||||
+ ServerLevel level,
|
||||
+ ItemStack spawnedFrom,
|
||||
+ LivingEntity owner,
|
||||
+ double x,
|
||||
+ double y,
|
||||
+ double z,
|
||||
+ float velocity,
|
||||
+ float inaccuracy
|
||||
+ ) {
|
||||
+ return spawnProjectileDelayed(factory.create(level, owner, spawnedFrom), level, spawnedFrom, projectile -> projectile.shoot(x, y, z, velocity, inaccuracy));
|
||||
+ // Paper end - fixes and addition to spawn reason API
|
||||
}
|
||||
|
||||
public static <T extends Projectile> T spawnProjectileUsingShoot(
|
||||
@@ -214,11 +_,45 @@
|
||||
}
|
||||
|
||||
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);
|
||||
- level.addFreshEntity(projectile);
|
||||
- projectile.applyOnProjectileSpawned(level, stack);
|
||||
- return projectile;
|
||||
- }
|
||||
+ return new Delayed<>(projectile, level, stack); // Paper - delayed projectile spawning
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - delayed projectile spawning
|
||||
+ public record Delayed<T extends Projectile>(
|
||||
+ T projectile,
|
||||
+ ServerLevel world,
|
||||
+ ItemStack projectileStack
|
||||
+ ) {
|
||||
+ // Taken from net.minecraft.world.entity.projectile.Projectile.spawnProjectile(T, net.minecraft.server.level.ServerLevel, net.minecraft.world.item.ItemStack, java.util.function.Consumer<T>)
|
||||
+ public boolean attemptSpawn() {
|
||||
+ if (!this.world.addFreshEntity(this.projectile)) return false;
|
||||
+ this.projectile.applyOnProjectileSpawned(this.world, this.projectileStack);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public T spawn() {
|
||||
+ this.attemptSpawn();
|
||||
+ return this.projectile();
|
||||
+ }
|
||||
+
|
||||
+ public boolean attemptSpawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ if (!this.world.addFreshEntity(this.projectile, reason)) return false;
|
||||
+ this.projectile.applyOnProjectileSpawned(this.world, this.projectileStack);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public T spawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ this.attemptSpawn(reason);
|
||||
+ return this.projectile();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - delayed projectile spawning
|
||||
|
||||
public void applyOnProjectileSpawned(ServerLevel level, ItemStack spawnedFrom) {
|
||||
EnchantmentHelper.onProjectileSpawned(level, spawnedFrom, this, item -> {});
|
||||
@@ -230,6 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - call projectile hit event
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) { // Paper - protected -> public
|
||||
+ 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) {
|
||||
+ return this.hitTargetOrDeflectSelf(hitResult);
|
||||
+ }
|
||||
+ return ProjectileDeflection.NONE;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) {
|
||||
if (hitResult.getType() == HitResult.Type.ENTITY) {
|
||||
EntityHitResult entityHitResult = (EntityHitResult)hitResult;
|
||||
@@ -261,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) {
|
||||
- this.setOwner(owner);
|
||||
+ // Paper start - Fix PickupStatus getting reset
|
||||
+ if (this instanceof AbstractArrow arrow) {
|
||||
+ arrow.setOwner(owner, false);
|
||||
+ } else {
|
||||
+ this.setOwner(owner);
|
||||
+ }
|
||||
+ // Paper end - Fix PickupStatus getting reset
|
||||
this.onDeflection(entity, deflectedByPlayer);
|
||||
}
|
||||
|
||||
@@ -297,6 +_,11 @@
|
||||
}
|
||||
|
||||
protected void onHitBlock(BlockHitResult result) {
|
||||
+ // CraftBukkit start - cancellable hit event
|
||||
+ if (this.hitCancelled) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
BlockState blockState = this.level().getBlockState(result.getBlockPos());
|
||||
blockState.onProjectileHit(this.level(), blockState, result, this);
|
||||
}
|
||||
@@ -306,6 +_,15 @@
|
||||
return false;
|
||||
} else {
|
||||
Entity owner = this.getOwner();
|
||||
+ // Paper start - Cancel hit for vanished players
|
||||
+ if (owner instanceof net.minecraft.server.level.ServerPlayer && target instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) target.getBukkitEntity();
|
||||
+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) owner.getBukkitEntity();
|
||||
+ if (!shooter.canSee(collided)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Cancel hit for vanished players
|
||||
return owner == null || this.leftOwner || !owner.isPassengerOfSameVehicle(target);
|
||||
}
|
||||
}
|
||||
@@ -318,13 +_,7 @@
|
||||
}
|
||||
|
||||
protected static float lerpRotation(float currentRotation, float targetRotation) {
|
||||
- while (targetRotation - currentRotation < -180.0F) {
|
||||
- currentRotation -= 360.0F;
|
||||
- }
|
||||
-
|
||||
- while (targetRotation - currentRotation >= 180.0F) {
|
||||
- currentRotation += 360.0F;
|
||||
- }
|
||||
+ currentRotation += Math.round((targetRotation - currentRotation) / 360.0F) * 360.0F; // Paper - stop large look changes from crashing the server
|
||||
|
||||
return Mth.lerp(0.2F, currentRotation, targetRotation);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ShulkerBullet.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java
|
||||
@@ -57,7 +_,21 @@
|
||||
this.finalTarget = finalTarget;
|
||||
this.currentMoveDirection = Direction.UP;
|
||||
this.selectNextMoveDirection(axis);
|
||||
- }
|
||||
+ this.projectileSource = shooter.getBukkitLivingEntity(); // CraftBukkit
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ @Nullable
|
||||
+ public Entity getTarget() {
|
||||
+ return this.finalTarget;
|
||||
+ }
|
||||
+
|
||||
+ public void setTarget(Entity e) {
|
||||
+ this.finalTarget = e;
|
||||
+ this.currentMoveDirection = Direction.UP;
|
||||
+ this.selectNextMoveDirection(Direction.Axis.X);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
@Override
|
||||
public SoundSource getSoundSource() {
|
||||
@@ -187,7 +_,7 @@
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (hitResult != null && this.isAlive() && hitResult.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(hitResult);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResult); // CraftBukkit - projectile hit event
|
||||
}
|
||||
|
||||
ProjectileUtil.rotateTowardsMovement(this, 0.5F);
|
||||
@@ -301,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity livingEntity1) {
|
||||
- livingEntity1.addEffect(new MobEffectInstance(MobEffects.LEVITATION, 200), MoreObjects.firstNonNull(owner, this));
|
||||
+ livingEntity1.addEffect(new MobEffectInstance(MobEffects.LEVITATION, 200), MoreObjects.firstNonNull(owner, this), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,14 +_,20 @@
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
- this.discard();
|
||||
+ // CraftBukkit start - add Bukkit remove cause
|
||||
+ this.destroy(null);
|
||||
+ }
|
||||
+
|
||||
+ private void destroy(org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
|
||||
+ this.discard(cause);
|
||||
+ // CraftBukkit end
|
||||
this.level().gameEvent(GameEvent.ENTITY_DAMAGE, this.position(), GameEvent.Context.of(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
- this.destroy();
|
||||
+ this.destroy(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -336,9 +_,14 @@
|
||||
|
||||
@Override
|
||||
public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, false)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.playSound(SoundEvents.SHULKER_BULLET_HURT, 1.0F, 1.0F);
|
||||
level.sendParticles(ParticleTypes.CRIT, this.getX(), this.getY(), this.getZ(), 15, 0.2, 0.2, 0.2, 0.0);
|
||||
- this.destroy();
|
||||
+ this.destroy(org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
--- a/net/minecraft/world/entity/projectile/SmallFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/SmallFireball.java
|
||||
@@ -23,6 +_,11 @@
|
||||
|
||||
public SmallFireball(Level level, LivingEntity owner, Vec3 movement) {
|
||||
super(EntityType.SMALL_FIREBALL, owner, movement, level);
|
||||
+ // CraftBukkit start
|
||||
+ if (this.getOwner() != null && this.getOwner() instanceof Mob) {
|
||||
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public SmallFireball(Level level, double x, double y, double z, Vec3 movement) {
|
||||
@@ -36,7 +_,14 @@
|
||||
Entity var7 = result.getEntity();
|
||||
Entity owner = this.getOwner();
|
||||
int remainingFireTicks = var7.getRemainingFireTicks();
|
||||
- var7.igniteForSeconds(5.0F);
|
||||
+ // CraftBukkit start - Entity damage by entity event + combust event
|
||||
+ org.bukkit.event.entity.EntityCombustByEntityEvent event = new org.bukkit.event.entity.EntityCombustByEntityEvent(this.getBukkitEntity(), var7.getBukkitEntity(), 5.0F);
|
||||
+ var7.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (!event.isCancelled()) {
|
||||
+ var7.igniteForSeconds(event.getDuration(), false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
DamageSource damageSource = this.damageSources().fireball(this, owner);
|
||||
if (!var7.hurtServer(serverLevel, damageSource, 5.0F)) {
|
||||
var7.setRemainingFireTicks(remainingFireTicks);
|
||||
@@ -51,9 +_,9 @@
|
||||
super.onHitBlock(result);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
Entity owner = this.getOwner();
|
||||
- if (!(owner instanceof Mob) || serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
|
||||
+ if (this.isIncendiary) { // CraftBukkit
|
||||
BlockPos blockPos = result.getBlockPos().relative(result.getDirection());
|
||||
- if (this.level().isEmptyBlock(blockPos)) {
|
||||
+ if (this.level().isEmptyBlock(blockPos) && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.level(), blockPos, this).isCancelled()) { // CraftBukkit
|
||||
this.level().setBlockAndUpdate(blockPos, BaseFireBlock.getState(this.level(), blockPos));
|
||||
}
|
||||
}
|
||||
@@ -64,7 +_,7 @@
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Snowball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Snowball.java
|
||||
@@ -61,7 +_,7 @@
|
||||
super.onHit(result);
|
||||
if (!this.level().isClientSide) {
|
||||
this.level().broadcastEntityEvent(this, (byte)3);
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
--- a/net/minecraft/world/entity/projectile/SpectralArrow.java
|
||||
+++ b/net/minecraft/world/entity/projectile/SpectralArrow.java
|
||||
@@ -38,7 +_,7 @@
|
||||
protected void doPostHurtEffects(LivingEntity living) {
|
||||
super.doPostHurtEffects(living);
|
||||
MobEffectInstance mobEffectInstance = new MobEffectInstance(MobEffects.GLOWING, this.duration, 0);
|
||||
- living.addEffect(mobEffectInstance, this.getEffectSource());
|
||||
+ living.addEffect(mobEffectInstance, this.getEffectSource(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,6 +1,6 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrowableItemProjectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrowableItemProjectile.java
|
||||
@@ -34,6 +34,12 @@
|
||||
@@ -35,6 +_,12 @@
|
||||
|
||||
protected abstract Item getDefaultItem();
|
||||
|
||||
|
@ -12,4 +12,4 @@
|
|||
+
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
return (ItemStack) this.getEntityData().get(ThrowableItemProjectile.DATA_ITEM_STACK);
|
||||
return this.getEntityData().get(DATA_ITEM_STACK);
|
|
@ -0,0 +1,11 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
@@ -59,7 +_,7 @@
|
||||
this.applyEffectsFromBlocks();
|
||||
super.tick();
|
||||
if (hitResultOnMoveVector.getType() != HitResult.Type.MISS && this.isAlive()) {
|
||||
- this.hitTargetOrDeflectSelf(hitResultOnMoveVector);
|
||||
+ this.preHitTargetOrDeflectSelf(hitResultOnMoveVector); // CraftBukkit - projectile hit event
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
@@ -59,22 +_,56 @@
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
if (!this.level().isClientSide) {
|
||||
- if (this.random.nextInt(8) == 0) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean hatching = this.random.nextInt(8) == 0;
|
||||
+ if (true) {
|
||||
+ // 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;
|
||||
+ }
|
||||
+ 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);
|
||||
+
|
||||
+ i = event.getNumHatches();
|
||||
+ hatching = event.isHatching();
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // If hatching is set to false, ensure child count is 0
|
||||
+ if (!hatching) {
|
||||
+ i = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add ThrownEggHatchEvent
|
||||
+ com.destroystokyo.paper.event.entity.ThrownEggHatchEvent event = new com.destroystokyo.paper.event.entity.ThrownEggHatchEvent((org.bukkit.entity.Egg) getBukkitEntity(), hatching, (byte) i, hatchingType);
|
||||
+ event.callEvent();
|
||||
+ hatching = event.isHatching();
|
||||
+ i = hatching ? event.getNumHatches() : 0; // If hatching is set to false, ensure child count is 0
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // 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
|
||||
if (chicken != null) {
|
||||
- chicken.setAge(-24000);
|
||||
+ // CraftBukkit start
|
||||
+ if (chicken.getBukkitEntity() instanceof org.bukkit.entity.Ageable ageable) {
|
||||
+ ageable.setBaby();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
chicken.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
|
||||
if (!chicken.fudgePositionAfterSizeChange(ZERO_SIZED_DIMENSIONS)) {
|
||||
break;
|
||||
}
|
||||
|
||||
- this.level().addFreshEntity(chicken);
|
||||
+ this.level().addFreshEntity(chicken, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // CraftBukkit
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
@@ -126,11 +_,18 @@
|
||||
Vec3 vec3 = this.oldPosition();
|
||||
if (owner instanceof ServerPlayer serverPlayer) {
|
||||
if (serverPlayer.connection.isAcceptingMessages()) {
|
||||
+ // CraftBukkit start
|
||||
+ ServerPlayer serverPlayer1 = serverPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL));
|
||||
+ if (serverPlayer1 == null) {
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT);
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
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());
|
||||
- serverLevel.addFreshEntity(endermite);
|
||||
+ serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,15 +_,15 @@
|
||||
owner.setPortalCooldown();
|
||||
}
|
||||
|
||||
- ServerPlayer serverPlayer1 = serverPlayer.teleport(
|
||||
- new TeleportTransition(
|
||||
- serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING
|
||||
- )
|
||||
- );
|
||||
+ // ServerPlayer serverPlayer1 = serverPlayer.teleport(
|
||||
+ // new TeleportTransition(
|
||||
+ // serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING
|
||||
+ // )
|
||||
+ // );
|
||||
if (serverPlayer1 != null) {
|
||||
serverPlayer1.resetFallDistance();
|
||||
serverPlayer1.resetCurrentImpulseContext();
|
||||
- serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl(), 5.0F);
|
||||
+ serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
|
||||
}
|
||||
|
||||
this.playSound(serverLevel, vec3);
|
||||
@@ -162,9 +_,9 @@
|
||||
this.playSound(serverLevel, vec3);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +_,7 @@
|
||||
if (owner instanceof ServerPlayer serverPlayer
|
||||
&& !owner.isAlive()
|
||||
&& serverPlayer.serverLevel().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
super.tick();
|
||||
}
|
||||
@@ -212,7 +_,7 @@
|
||||
public Entity teleport(TeleportTransition teleportTransition) {
|
||||
Entity entity = super.teleport(teleportTransition);
|
||||
if (entity != null) {
|
||||
- entity.placePortalTicket(BlockPos.containing(entity.position()));
|
||||
+ if (!this.level().paperConfig().misc.legacyEnderPearlBehavior) entity.placePortalTicket(BlockPos.containing(entity.position())); // Paper - Allow using old ender pearl behavior
|
||||
}
|
||||
|
||||
return entity;
|
||||
@@ -220,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean canTeleport(Level fromLevel, Level toLevel) {
|
||||
- return fromLevel.dimension() == Level.END && toLevel.dimension() == Level.OVERWORLD && this.getOwner() instanceof ServerPlayer serverPlayer
|
||||
+ return fromLevel.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END && toLevel.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.OVERWORLD && this.getOwner() instanceof ServerPlayer serverPlayer // CraftBukkit
|
||||
? super.canTeleport(fromLevel, toLevel) && serverPlayer.seenCredits
|
||||
: super.canTeleport(fromLevel, toLevel);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
@@ -37,10 +_,17 @@
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
if (this.level() instanceof ServerLevel) {
|
||||
- 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);
|
||||
- this.discard();
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, result, i);
|
||||
+ i = event.getExperience();
|
||||
+ if (event.getShowEffect()) {
|
||||
+ 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
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -9,6 +_,7 @@
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
@@ -82,51 +_,87 @@
|
||||
@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 MovingObjectPosition // Paper
|
||||
} else {
|
||||
- this.applySplash(
|
||||
- serverLevel, potionContents.getAllEffects(), result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null
|
||||
+ showParticles = this.applySplash(
|
||||
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass MovingObjectPosition // 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<net.minecraft.world.entity.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);
|
||||
+ // livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
|
||||
}
|
||||
|
||||
if (livingEntity.isOnFire() && livingEntity.isAlive()) {
|
||||
- livingEntity.extinguishFire();
|
||||
+ extinguish.add(livingEntity.getBukkitLivingEntity());
|
||||
+ // livingEntity.extinguishFire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) {
|
||||
- axolotl.rehydrate();
|
||||
+ 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 MovingObjectPosition // 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,33 +_,57 @@
|
||||
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;
|
||||
}
|
||||
|
||||
- for (MobEffectInstance mobEffectInstance : effects) {
|
||||
- Holder<MobEffect> effect = mobEffectInstance.getEffect();
|
||||
- if (effect.value().isInstantenous()) {
|
||||
- effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
|
||||
- } else {
|
||||
- int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
|
||||
- MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
|
||||
- effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
|
||||
- );
|
||||
- if (!mobEffectInstance1.endsWithin(20)) {
|
||||
- livingEntity.addEffect(mobEffectInstance1, effectSource);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ affected.put(livingEntity.getBukkitLivingEntity(), d1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, result, affected);
|
||||
+ if (!event.isCancelled() && entitiesOfClass != null && !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;
|
||||
+ }
|
||||
+ net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle();
|
||||
+ double d1 = event.getIntensity(victim);
|
||||
+ // CraftBukkit end
|
||||
+ for (MobEffectInstance mobEffectInstance : effects) {
|
||||
+ Holder<MobEffect> effect = mobEffectInstance.getEffect();
|
||||
+ // CraftBukkit start - Abide by PVP settings - for players only!
|
||||
+ if (!this.level().pvpMode && this.getOwner() instanceof ServerPlayer && livingEntity instanceof ServerPlayer && livingEntity != this.getOwner()) {
|
||||
+ MobEffect mobEffect = effect.value();
|
||||
+ if (mobEffect == net.minecraft.world.effect.MobEffects.MOVEMENT_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.DIG_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.HARM || mobEffect == net.minecraft.world.effect.MobEffects.BLINDNESS
|
||||
+ || mobEffect == net.minecraft.world.effect.MobEffects.HUNGER || mobEffect == net.minecraft.world.effect.MobEffects.WEAKNESS || mobEffect == net.minecraft.world.effect.MobEffects.POISON) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ if (effect.value().isInstantenous()) {
|
||||
+ effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
|
||||
+ } else {
|
||||
+ int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
|
||||
+ MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
|
||||
+ effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
|
||||
+ );
|
||||
+ if (!mobEffectInstance1.endsWithin(20)) {
|
||||
+ livingEntity.addEffect(mobEffectInstance1, effectSource);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
- private void makeAreaOfEffectCloud(PotionContents potionContents) {
|
||||
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // 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); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
public boolean isLingering() {
|
||||
@@ -182,13 +_,25 @@
|
||||
private void dowseFire(BlockPos pos) {
|
||||
BlockState blockState = this.level().getBlockState(pos);
|
||||
if (blockState.is(BlockTags.FIRE)) {
|
||||
- this.level().destroyBlock(pos, false, this);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
+ this.level().destroyBlock(pos, false, this);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (AbstractCandleBlock.isLit(blockState)) {
|
||||
- AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, false))) {
|
||||
+ AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (CampfireBlock.isLitCampfire(blockState)) {
|
||||
- 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 start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, false))) {
|
||||
+ 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 end
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
@@ -32,16 +_,19 @@
|
||||
|
||||
public ThrownTrident(EntityType<? extends ThrownTrident> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
}
|
||||
|
||||
public ThrownTrident(Level level, LivingEntity shooter, ItemStack pickupItemStack) {
|
||||
super(EntityType.TRIDENT, shooter, level, pickupItemStack, null);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ID_LOYALTY, this.getLoyaltyFromItem(pickupItemStack));
|
||||
this.entityData.set(ID_FOIL, pickupItemStack.hasFoil());
|
||||
}
|
||||
|
||||
public ThrownTrident(Level level, double x, double y, double z, ItemStack pickupItemStack) {
|
||||
super(EntityType.TRIDENT, x, y, z, level, pickupItemStack, pickupItemStack);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ID_LOYALTY, this.getLoyaltyFromItem(pickupItemStack));
|
||||
this.entityData.set(ID_FOIL, pickupItemStack.hasFoil());
|
||||
}
|
||||
@@ -67,10 +_,10 @@
|
||||
this.spawnAtLocation(serverLevel, this.getPickupItem(), 0.1F);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
if (!(owner instanceof Player) && this.position().distanceTo(owner.getEyePosition()) < owner.getBbWidth() + 1.0) {
|
||||
- this.discard();
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,6 +_,20 @@
|
||||
return this.entityData.get(ID_FOIL);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void setFoil(boolean foil) {
|
||||
+ this.entityData.set(ThrownTrident.ID_FOIL, foil);
|
||||
+ }
|
||||
+
|
||||
+ public int getLoyalty() {
|
||||
+ return this.entityData.get(ThrownTrident.ID_LOYALTY);
|
||||
+ }
|
||||
+
|
||||
+ public void setLoyalty(byte loyalty) {
|
||||
+ this.entityData.set(ThrownTrident.ID_LOYALTY, loyalty);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
@Override
|
||||
protected EntityHitResult findHitEntity(Vec3 startVec, Vec3 endVec) {
|
||||
@@ -108,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
|
||||
Entity owner = this.getOwner();
|
||||
DamageSource damageSource = this.damageSources().trident(this, (Entity)(owner == null ? this : owner));
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
|
@ -0,0 +1,43 @@
|
|||
--- a/net/minecraft/world/entity/projectile/WitherSkull.java
|
||||
+++ b/net/minecraft/world/entity/projectile/WitherSkull.java
|
||||
@@ -65,11 +_,11 @@
|
||||
if (var8.isAlive()) {
|
||||
EnchantmentHelper.doPostAttackEffects(serverLevel, var8, damageSource);
|
||||
} else {
|
||||
- livingEntity.heal(5.0F);
|
||||
+ livingEntity.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- flag = var8.hurtServer(serverLevel, this.damageSources().magic(), 5.0F);
|
||||
+ flag = var8.hurtServer(serverLevel, this.damageSources().magic().customEventDamager(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls // Paper - fix DamageSource API
|
||||
}
|
||||
|
||||
if (flag && var8 instanceof LivingEntity livingEntityx) {
|
||||
@@ -81,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
- livingEntityx.addEffect(new MobEffectInstance(MobEffects.WITHER, 20 * i, 1), this.getEffectSource());
|
||||
+ livingEntityx.addEffect(new MobEffectInstance(MobEffects.WITHER, 20 * i, 1), this.getEffectSource(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,8 +_,15 @@
|
||||
protected void onHit(HitResult result) {
|
||||
super.onHit(result);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, Level.ExplosionInteraction.MOB);
|
||||
- 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()) {
|
||||
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
|
@ -1,320 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -36,6 +36,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;
|
||||
@@ -50,6 +51,10 @@
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
+import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.player.PlayerPickupArrowEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public abstract class AbstractArrow extends Projectile {
|
||||
|
||||
@@ -78,6 +83,18 @@
|
||||
@Nullable
|
||||
public ItemStack firedFromWeapon;
|
||||
|
||||
+ // Spigot Start
|
||||
+ @Override
|
||||
+ public void inactiveTick()
|
||||
+ {
|
||||
+ if ( this.isInGround() )
|
||||
+ {
|
||||
+ this.life += 1;
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, Level world) {
|
||||
super(type, world);
|
||||
this.pickup = AbstractArrow.Pickup.DISALLOWED;
|
||||
@@ -88,23 +105,30 @@
|
||||
}
|
||||
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, double x, double y, double z, Level world, ItemStack stack, @Nullable ItemStack weapon) {
|
||||
- this(type, world);
|
||||
- this.pickupItemStack = stack.copy();
|
||||
- this.setCustomName((Component) stack.get(DataComponents.CUSTOM_NAME));
|
||||
- Unit unit = (Unit) stack.remove(DataComponents.INTANGIBLE_PROJECTILE);
|
||||
+ // CraftBukkit start - handle the owner before the rest of things
|
||||
+ this(type, x, y, z, world, stack, weapon, null);
|
||||
+ }
|
||||
|
||||
+ protected AbstractArrow(EntityType<? extends AbstractArrow> entitytypes, double d0, double d1, double d2, Level world, ItemStack itemstack, @Nullable ItemStack itemstack1, @Nullable LivingEntity ownerEntity) {
|
||||
+ this(entitytypes, world);
|
||||
+ this.setOwner(ownerEntity);
|
||||
+ // CraftBukkit end
|
||||
+ 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;
|
||||
}
|
||||
|
||||
- this.setPos(x, y, z);
|
||||
- if (weapon != null && world instanceof ServerLevel worldserver) {
|
||||
- if (weapon.isEmpty()) {
|
||||
+ this.setPos(d0, d1, d2);
|
||||
+ if (itemstack1 != null && world instanceof ServerLevel worldserver) {
|
||||
+ if (itemstack1.isEmpty()) {
|
||||
throw new IllegalArgumentException("Invalid weapon firing an arrow");
|
||||
}
|
||||
|
||||
- this.firedFromWeapon = weapon.copy();
|
||||
- int i = EnchantmentHelper.getPiercingCount(worldserver, weapon, this.pickupItemStack);
|
||||
+ this.firedFromWeapon = itemstack1.copy();
|
||||
+ int i = EnchantmentHelper.getPiercingCount(worldserver, itemstack1, this.pickupItemStack);
|
||||
|
||||
if (i > 0) {
|
||||
this.setPierceLevel((byte) i);
|
||||
@@ -114,8 +138,8 @@
|
||||
}
|
||||
|
||||
protected AbstractArrow(EntityType<? extends AbstractArrow> type, LivingEntity owner, Level world, ItemStack stack, @Nullable ItemStack shotFrom) {
|
||||
- this(type, owner.getX(), owner.getEyeY() - 0.10000000149011612D, owner.getZ(), world, stack, shotFrom);
|
||||
- this.setOwner(owner);
|
||||
+ this(type, owner.getX(), owner.getEyeY() - 0.10000000149011612D, owner.getZ(), world, stack, shotFrom, owner); // CraftBukkit
|
||||
+ // this.setOwner(entityliving); // SPIGOT-7744 - Moved to the above constructor
|
||||
}
|
||||
|
||||
public void setSoundEvent(SoundEvent sound) {
|
||||
@@ -220,6 +244,7 @@
|
||||
}
|
||||
|
||||
} else {
|
||||
+ if (tickCount > 200) this.tickDespawn(); // Paper - tick despawnCounter regardless after 10 seconds
|
||||
this.inGroundTime = 0;
|
||||
Vec3 vec3d2 = this.position();
|
||||
|
||||
@@ -282,7 +307,7 @@
|
||||
|
||||
if (movingobjectpositionentity == null) {
|
||||
if (this.isAlive() && blockHitResult.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(blockHitResult);
|
||||
+ this.preHitTargetOrDeflectSelf(blockHitResult); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
} else {
|
||||
@@ -290,7 +315,7 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
- ProjectileDeflection projectiledeflection = this.hitTargetOrDeflectSelf(movingobjectpositionentity);
|
||||
+ ProjectileDeflection projectiledeflection = this.preHitTargetOrDeflectSelf(movingobjectpositionentity); // CraftBukkit - projectile hit event
|
||||
|
||||
this.hasImpulse = true;
|
||||
if (this.getPierceLevel() > 0 && projectiledeflection == ProjectileDeflection.NONE) {
|
||||
@@ -318,7 +343,20 @@
|
||||
this.level().addParticle(ParticleTypes.BUBBLE, pos.x - vec3d1.x * 0.25D, pos.y - vec3d1.y * 0.25D, pos.z - vec3d1.z * 0.25D, vec3d1.x, vec3d1.y, vec3d1.z);
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
+ @Override
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult hitResult) {
|
||||
+ if (hitResult instanceof EntityHitResult entityHitResult && this.hitCancelled && this.getPierceLevel() > 0) {
|
||||
+ if (this.piercingIgnoreEntityIds == null) {
|
||||
+ this.piercingIgnoreEntityIds = new IntOpenHashSet(5);
|
||||
+ }
|
||||
+ this.piercingIgnoreEntityIds.add(entityHitResult.getEntity().getId());
|
||||
+ }
|
||||
+ return super.preHitTargetOrDeflectSelf(hitResult);
|
||||
}
|
||||
+ // Paper end - Fix cancelling ProjectileHitEvent for piercing arrows
|
||||
|
||||
@Override
|
||||
protected double getDefaultGravity() {
|
||||
@@ -356,8 +394,8 @@
|
||||
|
||||
protected void tickDespawn() {
|
||||
++this.life;
|
||||
- if (this.life >= 1200) {
|
||||
- this.discard();
|
||||
+ if (this.life >= (pickup == Pickup.CREATIVE_ONLY ? this.level().paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (pickup == Pickup.DISALLOWED ? this.level().paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - Configurable non-player arrow despawn rate; TODO: Extract this to init?
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
||||
@@ -386,9 +424,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 +461,7 @@
|
||||
}
|
||||
|
||||
if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -440,11 +478,18 @@
|
||||
entityliving.setLastHurtMob(entity);
|
||||
}
|
||||
|
||||
+ if (this.isCritArrow()) damagesource = damagesource.critical(); // Paper - add critical damage API
|
||||
boolean flag = entity.getType() == EntityType.ENDERMAN;
|
||||
int k = entity.getRemainingFireTicks();
|
||||
|
||||
if (this.isOnFire() && !flag) {
|
||||
- entity.igniteForSeconds(5.0F);
|
||||
+ // CraftBukkit start
|
||||
+ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5.0F);
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent);
|
||||
+ if (!combustEvent.isCancelled()) {
|
||||
+ entity.igniteForSeconds(combustEvent.getDuration(), false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
if (entity.hurtOrSimulate(damagesource, (float) i)) {
|
||||
@@ -490,7 +535,7 @@
|
||||
|
||||
this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
|
||||
if (this.getPierceLevel() <= 0) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
} else {
|
||||
entity.setRemainingFireTicks(k);
|
||||
@@ -506,7 +551,7 @@
|
||||
this.spawnAtLocation(worldserver2, this.getPickupItem(), 0.1F);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,7 +583,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,7 +710,7 @@
|
||||
this.setCritArrow(nbt.getBoolean("crit"));
|
||||
this.setPierceLevel(nbt.getByte("PierceLevel"));
|
||||
if (nbt.contains("SoundEvent", 8)) {
|
||||
- this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.parse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent());
|
||||
+ this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.tryParse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent()); // Paper - Validate resource location
|
||||
}
|
||||
|
||||
if (nbt.contains("item", 10)) {
|
||||
@@ -675,7 +720,7 @@
|
||||
}
|
||||
|
||||
if (nbt.contains("weapon", 10)) {
|
||||
- this.firedFromWeapon = (ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("weapon")).orElse((Object) null);
|
||||
+ this.firedFromWeapon = (ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("weapon")).orElse(null); // CraftBukkit - decompile error
|
||||
} else {
|
||||
this.firedFromWeapon = null;
|
||||
}
|
||||
@@ -684,38 +729,42 @@
|
||||
|
||||
@Override
|
||||
public void setOwner(@Nullable Entity entity) {
|
||||
+ // Paper start - Fix PickupStatus getting reset
|
||||
+ this.setOwner(entity, true);
|
||||
+ }
|
||||
+
|
||||
+ public void setOwner(@Nullable Entity entity, boolean resetPickup) {
|
||||
+ // Paper end - Fix PickupStatus getting reset
|
||||
super.setOwner(entity);
|
||||
+ if (!resetPickup) return; // Paper - Fix PickupStatus getting reset
|
||||
Entity entity1 = entity;
|
||||
byte b0 = 0;
|
||||
|
||||
- EntityArrow.PickupStatus entityarrow_pickupstatus;
|
||||
+ EntityArrow.PickupStatus entityarrow_pickupstatus = this.pickup; // CraftBukkit - decompile error
|
||||
|
||||
label16:
|
||||
- while(true) {
|
||||
- //$FF: b0->value
|
||||
- //0->net/minecraft/world/entity/player/EntityHuman
|
||||
- //1->net/minecraft/world/entity/OminousItemSpawner
|
||||
- switch (entity1.typeSwitch<invokedynamic>(entity1, b0)) {
|
||||
- case -1:
|
||||
- default:
|
||||
- entityarrow_pickupstatus = this.pickup;
|
||||
- break label16;
|
||||
- case 0:
|
||||
- EntityHuman entityhuman = (EntityHuman)entity1;
|
||||
+ // CraftBukkit start - decompile error
|
||||
+ while (true) {
|
||||
+ switch (entity1) {
|
||||
+ case EntityHuman entityhuman:
|
||||
|
||||
if (this.pickup != EntityArrow.PickupStatus.DISALLOWED) {
|
||||
b0 = 1;
|
||||
- break;
|
||||
+ break label16;
|
||||
}
|
||||
|
||||
entityarrow_pickupstatus = EntityArrow.PickupStatus.ALLOWED;
|
||||
break label16;
|
||||
- case 1:
|
||||
- OminousItemSpawner ominousitemspawner = (OminousItemSpawner)entity1;
|
||||
+ case OminousItemSpawner ominousitemspawner:
|
||||
|
||||
entityarrow_pickupstatus = EntityArrow.PickupStatus.DISALLOWED;
|
||||
break label16;
|
||||
+ case null: // SPIGOT-7751: Fix crash caused by null owner
|
||||
+ default:
|
||||
+ entityarrow_pickupstatus = this.pickup;
|
||||
+ break label16;
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
this.pickup = entityarrow_pickupstatus;
|
||||
@@ -724,9 +773,24 @@
|
||||
@Override
|
||||
public void playerTouch(Player player) {
|
||||
if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) {
|
||||
- if (this.tryPickup(player)) {
|
||||
+ // CraftBukkit start
|
||||
+ ItemStack itemstack = this.getPickupItem();
|
||||
+ if (this.pickup == Pickup.ALLOWED && !itemstack.isEmpty() && player.getInventory().canHold(itemstack) > 0) {
|
||||
+ ItemEntity item = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack);
|
||||
+ PlayerPickupArrowEvent event = new PlayerPickupArrowEvent((org.bukkit.entity.Player) player.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.level().getCraftServer(), item), (org.bukkit.entity.AbstractArrow) this.getBukkitEntity());
|
||||
+ // event.setCancelled(!entityhuman.canPickUpLoot); TODO
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ itemstack = item.getItem();
|
||||
+ }
|
||||
+
|
||||
+ if ((this.pickup == AbstractArrow.Pickup.ALLOWED && player.getInventory().add(itemstack)) || (this.pickup == AbstractArrow.Pickup.CREATIVE_ONLY && player.getAbilities().instabuild)) {
|
||||
+ // CraftBukkit end
|
||||
player.take(this, 1);
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
@@ -14,12 +14,17 @@
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public abstract class AbstractHurtingProjectile extends Projectile {
|
||||
|
||||
public static final double INITAL_ACCELERATION_POWER = 0.1D;
|
||||
public static final double DEFLECTION_SCALE = 0.5D;
|
||||
public double accelerationPower;
|
||||
+ public float bukkitYield = 1; // CraftBukkit
|
||||
+ public boolean isIncendiary = true; // CraftBukkit
|
||||
|
||||
protected AbstractHurtingProjectile(EntityType<? extends AbstractHurtingProjectile> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -69,7 +74,7 @@
|
||||
|
||||
this.applyInertia();
|
||||
if (!this.level().isClientSide && (entity != null && entity.isRemoved() || !this.level().hasChunkAt(this.blockPosition()))) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
HitResult movingobjectposition = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity, this.getClipType());
|
||||
Vec3 vec3d;
|
||||
@@ -89,7 +94,7 @@
|
||||
}
|
||||
|
||||
if (movingobjectposition.getType() != HitResult.Type.MISS && this.isAlive()) {
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
}
|
||||
|
||||
this.createParticleTrail();
|
|
@ -1,20 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Arrow.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Arrow.java
|
||||
@@ -119,7 +119,7 @@
|
||||
mobeffect = (MobEffectInstance) iterator.next();
|
||||
target.addEffect(new MobEffectInstance(mobeffect.getEffect(), Math.max(mobeffect.mapDuration((i) -> {
|
||||
return i / 8;
|
||||
- }), 1), mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isVisible()), entity);
|
||||
+ }), 1), mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isVisible()), entity, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
mobeffect = (MobEffectInstance) iterator.next();
|
||||
- target.addEffect(mobeffect, entity);
|
||||
+ target.addEffect(mobeffect, entity, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -14,6 +14,9 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class DragonFireball extends AbstractHurtingProjectile {
|
||||
|
||||
@@ -59,9 +62,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events
|
||||
this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
- this.level().addFreshEntity(entityareaeffectcloud);
|
||||
- this.discard();
|
||||
+ this.level().addFreshEntity(entityareaeffectcloud, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EXPLOSION); // Paper - use correct spawn reason
|
||||
+ } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/EvokerFangs.java
|
||||
+++ b/net/minecraft/world/entity/projectile/EvokerFangs.java
|
||||
@@ -16,6 +16,9 @@
|
||||
import net.minecraft.world.entity.TraceableEntity;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class EvokerFangs extends Entity implements TraceableEntity {
|
||||
|
||||
@@ -121,7 +124,7 @@
|
||||
}
|
||||
|
||||
if (--this.lifeTicks < 0) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +135,7 @@
|
||||
|
||||
if (target.isAlive() && !target.isInvulnerable() && target != entityliving1) {
|
||||
if (entityliving1 == null) {
|
||||
- target.hurt(this.damageSources().magic(), 6.0F);
|
||||
+ target.hurt(this.damageSources().magic().customEventDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API
|
||||
} else {
|
||||
if (entityliving1.isAlliedTo((Entity) target)) {
|
||||
return;
|
|
@ -1,16 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Fireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Fireball.java
|
||||
@@ -61,7 +61,12 @@
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
if (nbt.contains("Item", 10)) {
|
||||
- this.setItem((ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem()));
|
||||
+ // CraftBukkit start - SPIGOT-5474 probably came from bugged earlier versions
|
||||
+ ItemStack itemstack = (ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem());
|
||||
+ if (!itemstack.isEmpty()) {
|
||||
+ this.setItem(itemstack);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else {
|
||||
this.setItem(this.getDefaultItem());
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -32,6 +32,9 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
|
||||
@@ -42,6 +45,7 @@
|
||||
public int lifetime;
|
||||
@Nullable
|
||||
public LivingEntity attachedToEntity;
|
||||
+ @Nullable public java.util.UUID spawningEntity; // Paper
|
||||
|
||||
public FireworkRocketEntity(EntityType<? extends FireworkRocketEntity> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -84,7 +88,29 @@
|
||||
this.setOwner(entity);
|
||||
}
|
||||
|
||||
+ // Spigot Start - copied from tick
|
||||
@Override
|
||||
+ public void inactiveTick() {
|
||||
+ this.life += 1;
|
||||
+
|
||||
+ if (this.life > this.lifetime) {
|
||||
+ Level world = this.level();
|
||||
+
|
||||
+ if (world instanceof ServerLevel) {
|
||||
+ ServerLevel worldserver = (ServerLevel) world;
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(worldserver);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ super.inactiveTick();
|
||||
+ }
|
||||
+ // Spigot End
|
||||
+
|
||||
+ @Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
||||
builder.define(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, FireworkRocketEntity.getDefaultItem());
|
||||
builder.define(FireworkRocketEntity.DATA_ATTACHED_TO_TARGET, OptionalInt.empty());
|
||||
@@ -152,7 +178,7 @@
|
||||
}
|
||||
|
||||
if (!this.noPhysics && this.isAlive() && movingobjectposition.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
|
||||
@@ -172,7 +198,11 @@
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
|
||||
- this.explode(worldserver);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(worldserver);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +212,7 @@
|
||||
world.broadcastEntityEvent(this, (byte) 17);
|
||||
this.gameEvent(GameEvent.EXPLODE, this.getOwner());
|
||||
this.dealExplosionDamage(world);
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +221,11 @@
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
- this.explode(worldserver);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(worldserver);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
}
|
||||
@@ -205,7 +239,11 @@
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
if (this.hasExplosion()) {
|
||||
- this.explode(worldserver);
|
||||
+ // CraftBukkit start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
|
||||
+ this.explode(worldserver);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +325,11 @@
|
||||
nbt.putInt("LifeTime", this.lifetime);
|
||||
nbt.put("FireworksItem", this.getItem().save(this.registryAccess()));
|
||||
nbt.putBoolean("ShotAtAngle", (Boolean) this.entityData.get(FireworkRocketEntity.DATA_SHOT_AT_ANGLE));
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ nbt.putUUID("SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -303,7 +346,11 @@
|
||||
if (nbt.contains("ShotAtAngle")) {
|
||||
this.entityData.set(FireworkRocketEntity.DATA_SHOT_AT_ANGLE, nbt.getBoolean("ShotAtAngle"));
|
||||
}
|
||||
-
|
||||
+ // Paper start
|
||||
+ if (nbt.hasUUID("SpawningEntity")) {
|
||||
+ this.spawningEntity = nbt.getUUID("SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private List<FireworkExplosion> getExplosions() {
|
|
@ -1,352 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -29,7 +29,6 @@
|
||||
import net.minecraft.world.entity.ExperienceOrb;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
-import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -47,6 +46,13 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.entity.FishHook;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.player.PlayerFishEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class FishingHook extends Projectile {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -68,6 +74,18 @@
|
||||
private final int luck;
|
||||
private final int lureSpeed;
|
||||
|
||||
+ // CraftBukkit start - Extra variables to enable modification of fishing wait time, values are minecraft defaults
|
||||
+ public int minWaitTime = 100;
|
||||
+ public int maxWaitTime = 600;
|
||||
+ public int minLureTime = 20;
|
||||
+ public int maxLureTime = 80;
|
||||
+ public float minLureAngle = 0.0F;
|
||||
+ public float maxLureAngle = 360.0F;
|
||||
+ public boolean applyLure = true;
|
||||
+ public boolean rainInfluenced = true;
|
||||
+ public boolean skyInfluenced = true;
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
private FishingHook(EntityType<? extends FishingHook> type, Level world, int luckBonus, int waitTimeReductionTicks) {
|
||||
super(type, world);
|
||||
this.syncronizedRandom = RandomSource.create();
|
||||
@@ -75,13 +93,17 @@
|
||||
this.currentState = FishingHook.FishHookState.FLYING;
|
||||
this.luck = Math.max(0, luckBonus);
|
||||
this.lureSpeed = Math.max(0, waitTimeReductionTicks);
|
||||
+ // Paper start - Configurable fishing time ranges
|
||||
+ minWaitTime = world.paperConfig().fishingTimeRange.minimum;
|
||||
+ maxWaitTime = world.paperConfig().fishingTimeRange.maximum;
|
||||
+ // Paper end - Configurable fishing time ranges
|
||||
}
|
||||
|
||||
public FishingHook(EntityType<? extends FishingHook> type, Level world) {
|
||||
this(type, world, 0, 0);
|
||||
}
|
||||
|
||||
- public FishingHook(Player thrower, Level world, int luckBonus, int waitTimeReductionTicks) {
|
||||
+ public FishingHook(net.minecraft.world.entity.player.Player thrower, Level world, int luckBonus, int waitTimeReductionTicks) {
|
||||
this(EntityType.FISHING_BOBBER, world, luckBonus, waitTimeReductionTicks);
|
||||
this.setOwner(thrower);
|
||||
float f = thrower.getXRot();
|
||||
@@ -149,15 +171,15 @@
|
||||
public void tick() {
|
||||
this.syncronizedRandom.setSeed(this.getUUID().getLeastSignificantBits() ^ this.level().getGameTime());
|
||||
super.tick();
|
||||
- Player entityhuman = this.getPlayerOwner();
|
||||
+ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner();
|
||||
|
||||
if (entityhuman == null) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else if (this.level().isClientSide || !this.shouldStopFishing(entityhuman)) {
|
||||
if (this.onGround()) {
|
||||
++this.life;
|
||||
if (this.life >= 1200) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -250,7 +272,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private boolean shouldStopFishing(Player player) {
|
||||
+ private boolean shouldStopFishing(net.minecraft.world.entity.player.Player player) {
|
||||
ItemStack itemstack = player.getMainHandItem();
|
||||
ItemStack itemstack1 = player.getOffhandItem();
|
||||
boolean flag = itemstack.is(Items.FISHING_ROD);
|
||||
@@ -259,7 +281,7 @@
|
||||
if (!player.isRemoved() && player.isAlive() && (flag || flag1) && this.distanceToSqr((Entity) player) <= 1024.0D) {
|
||||
return false;
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -267,7 +289,7 @@
|
||||
private void checkCollision() {
|
||||
HitResult movingobjectposition = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity);
|
||||
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -300,11 +322,11 @@
|
||||
int i = 1;
|
||||
BlockPos blockposition1 = pos.above();
|
||||
|
||||
- if (this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockposition1)) {
|
||||
+ if (this.rainInfluenced && this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockposition1)) { // CraftBukkit
|
||||
++i;
|
||||
}
|
||||
|
||||
- if (this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockposition1)) {
|
||||
+ if (this.skyInfluenced && this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockposition1)) { // CraftBukkit
|
||||
--i;
|
||||
}
|
||||
|
||||
@@ -314,6 +336,10 @@
|
||||
this.timeUntilLured = 0;
|
||||
this.timeUntilHooked = 0;
|
||||
this.getEntityData().set(FishingHook.DATA_BITING, false);
|
||||
+ // CraftBukkit start
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
} else {
|
||||
float f;
|
||||
@@ -347,6 +373,13 @@
|
||||
worldserver.sendParticles(ParticleTypes.FISHING, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D);
|
||||
}
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.BITE);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
+ if (playerFishEvent.isCancelled()) {
|
||||
+ 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.5D;
|
||||
|
||||
@@ -379,16 +412,34 @@
|
||||
}
|
||||
|
||||
if (this.timeUntilLured <= 0) {
|
||||
- this.fishAngle = Mth.nextFloat(this.random, 0.0F, 360.0F);
|
||||
- this.timeUntilHooked = Mth.nextInt(this.random, 20, 80);
|
||||
+ // CraftBukkit start - logic to modify fishing wait time, lure time, and lure angle
|
||||
+ this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
|
||||
+ this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add missing fishing event state
|
||||
+ if (this.getPlayerOwner() != null) {
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.LURED);
|
||||
+ if (!playerFishEvent.callEvent()) {
|
||||
+ this.timeUntilHooked = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing fishing event state
|
||||
}
|
||||
} else {
|
||||
- this.timeUntilLured = Mth.nextInt(this.random, 100, 600);
|
||||
- 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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+ // Paper start - more projectile api - extract time until lured reset logic
|
||||
+ public void resetTimeUntilLured() {
|
||||
+ this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
||||
+ this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
||||
+ }
|
||||
+ // Paper end - more projectile api - extract time until lured reset logic
|
||||
|
||||
public boolean calculateOpenWater(BlockPos pos) {
|
||||
FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID;
|
||||
@@ -445,17 +496,35 @@
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {}
|
||||
|
||||
+ // Paper start - Add hand parameter to PlayerFishEvent
|
||||
+ @Deprecated
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
public int retrieve(ItemStack usedItem) {
|
||||
- Player entityhuman = this.getPlayerOwner();
|
||||
+ return this.retrieve(net.minecraft.world.InteractionHand.MAIN_HAND, usedItem);
|
||||
+ }
|
||||
|
||||
+ public int retrieve(net.minecraft.world.InteractionHand hand, ItemStack usedItem) {
|
||||
+ // Paper end - Add hand parameter to PlayerFishEvent
|
||||
+ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner();
|
||||
+
|
||||
if (!this.level().isClientSide && entityhuman != null && !this.shouldStopFishing(entityhuman)) {
|
||||
int i = 0;
|
||||
|
||||
if (this.hookedIn != null) {
|
||||
+ // CraftBukkit start
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_ENTITY); // Paper - Add hand parameter to PlayerFishEvent
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
+
|
||||
+ if (playerFishEvent.isCancelled()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (this.hookedIn != null) { // Paper - re-check to see if there is a hooked entity
|
||||
+ // CraftBukkit end
|
||||
this.pullEntity(this.hookedIn);
|
||||
CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, Collections.emptyList());
|
||||
this.level().broadcastEntityEvent(this, (byte) 31);
|
||||
i = this.hookedIn instanceof ItemEntity ? 3 : 5;
|
||||
+ } // Paper - re-check to see if there is a hooked entity
|
||||
} else if (this.nibble > 0) {
|
||||
LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING);
|
||||
LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING);
|
||||
@@ -466,15 +535,38 @@
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ItemStack itemstack1 = (ItemStack) iterator.next();
|
||||
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1);
|
||||
+ // Paper start - new ItemEntity would throw if for whatever reason (mostly shitty datapacks) the itemstack1 turns out to be empty
|
||||
+ // if the item stack is empty we instead just have our entityitem as null
|
||||
+ ItemEntity entityitem = null;
|
||||
+ if (!itemstack1.isEmpty()) {
|
||||
+ entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftBukkit start
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem 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()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
double d0 = entityhuman.getX() - this.getX();
|
||||
double d1 = entityhuman.getY() - this.getY();
|
||||
double d2 = entityhuman.getZ() - this.getZ();
|
||||
double d3 = 0.1D;
|
||||
|
||||
- entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D);
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
- entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, this.random.nextInt(6) + 1));
|
||||
+ // Paper start - entity item can be null, so we need to check against this
|
||||
+ if (entityitem != null) {
|
||||
+ entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D);
|
||||
+ this.level().addFreshEntity(entityitem);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
|
||||
+ if (playerFishEvent.getExpToDrop() > 0) {
|
||||
+ entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this)); // Paper
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (itemstack1.is(ItemTags.FISHES)) {
|
||||
entityhuman.awardStat(Stats.FISH_CAUGHT, 1);
|
||||
}
|
||||
@@ -484,10 +576,27 @@
|
||||
}
|
||||
|
||||
if (this.onGround()) {
|
||||
+ // CraftBukkit start
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.IN_GROUND); // Paper - Add hand parameter to PlayerFishEvent
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
+
|
||||
+ if (playerFishEvent.isCancelled()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
i = 2;
|
||||
}
|
||||
+ // CraftBukkit start
|
||||
+ if (i == 0) {
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.REEL_IN); // Paper - Add hand parameter to PlayerFishEvent
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
+ if (playerFishEvent.isCancelled()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return i;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -496,7 +605,7 @@
|
||||
|
||||
@Override
|
||||
public void handleEntityEvent(byte status) {
|
||||
- if (status == 31 && this.level().isClientSide && this.hookedIn instanceof Player && ((Player) this.hookedIn).isLocalPlayer()) {
|
||||
+ if (status == 31 && this.level().isClientSide && this.hookedIn instanceof net.minecraft.world.entity.player.Player && ((net.minecraft.world.entity.player.Player) this.hookedIn).isLocalPlayer()) {
|
||||
this.pullEntity(this.hookedIn);
|
||||
}
|
||||
|
||||
@@ -520,8 +629,15 @@
|
||||
|
||||
@Override
|
||||
public void remove(Entity.RemovalReason reason) {
|
||||
+ // CraftBukkit start - add Bukkit remove cause
|
||||
+ this.remove(reason, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) {
|
||||
+ // CraftBukkit end
|
||||
this.updateOwnerInfo((FishingHook) null);
|
||||
- super.remove(reason);
|
||||
+ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -536,7 +652,7 @@
|
||||
}
|
||||
|
||||
private void updateOwnerInfo(@Nullable FishingHook fishingBobber) {
|
||||
- Player entityhuman = this.getPlayerOwner();
|
||||
+ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner();
|
||||
|
||||
if (entityhuman != null) {
|
||||
entityhuman.fishing = fishingBobber;
|
||||
@@ -545,10 +661,10 @@
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- public Player getPlayerOwner() {
|
||||
+ public net.minecraft.world.entity.player.Player getPlayerOwner() {
|
||||
Entity entity = this.getOwner();
|
||||
|
||||
- return entity instanceof Player ? (Player) entity : null;
|
||||
+ return entity instanceof net.minecraft.world.entity.player.Player ? (net.minecraft.world.entity.player.Player) entity : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -575,7 +691,7 @@
|
||||
int i = packet.getData();
|
||||
|
||||
FishingHook.LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(i), i);
|
||||
- this.discard();
|
||||
+ this.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/LargeFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/LargeFireball.java
|
||||
@@ -12,6 +12,10 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class LargeFireball extends Fireball {
|
||||
|
||||
@@ -19,11 +23,13 @@
|
||||
|
||||
public LargeFireball(EntityType<? extends LargeFireball> type, Level world) {
|
||||
super(type, world);
|
||||
+ this.isIncendiary = (world instanceof ServerLevel worldserver) && worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
|
||||
}
|
||||
|
||||
public LargeFireball(Level world, LivingEntity owner, Vec3 velocity, int explosionPower) {
|
||||
super(EntityType.FIREBALL, owner, velocity, world);
|
||||
this.explosionPower = explosionPower;
|
||||
+ this.isIncendiary = (world instanceof ServerLevel worldserver) && worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,8 +40,16 @@
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
boolean flag = worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
||||
|
||||
- this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionPower, flag, Level.ExplosionInteraction.MOB);
|
||||
- this.discard();
|
||||
+ // CraftBukkit start - fire ExplosionPrimeEvent
|
||||
+ ExplosionPrimeEvent event = new 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
|
||||
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,7 +79,8 @@
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
if (nbt.contains("ExplosionPower", 99)) {
|
||||
- this.explosionPower = nbt.getByte("ExplosionPower");
|
||||
+ // CraftBukkit - set bukkitYield when setting explosionpower
|
||||
+ this.bukkitYield = this.explosionPower = nbt.getByte("ExplosionPower");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/LlamaSpit.java
|
||||
+++ b/net/minecraft/world/entity/projectile/LlamaSpit.java
|
||||
@@ -17,6 +17,9 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class LlamaSpit extends Projectile {
|
||||
|
||||
@@ -41,7 +44,7 @@
|
||||
Vec3 vec3d = this.getDeltaMovement();
|
||||
HitResult movingobjectposition = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity);
|
||||
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
double d0 = this.getX() + vec3d.x;
|
||||
double d1 = this.getY() + vec3d.y;
|
||||
double d2 = this.getZ() + vec3d.z;
|
||||
@@ -50,9 +53,9 @@
|
||||
float f = 0.99F;
|
||||
|
||||
if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else if (this.isInWaterOrBubble()) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
this.setDeltaMovement(vec3d.scale(0.9900000095367432D));
|
||||
this.applyGravity();
|
||||
@@ -83,7 +86,7 @@
|
||||
protected void onHitBlock(BlockHitResult blockHitResult) {
|
||||
super.onHitBlock(blockHitResult);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,231 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -35,6 +35,9 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.projectiles.ProjectileSource;
|
||||
+// CraftBukkit end
|
||||
|
||||
public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
|
||||
@@ -47,6 +50,10 @@
|
||||
@Nullable
|
||||
private Entity lastDeflectedBy;
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ protected boolean hitCancelled = false;
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
Projectile(EntityType<? extends Projectile> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
@@ -56,16 +63,35 @@
|
||||
this.ownerUUID = entity.getUUID();
|
||||
this.cachedOwner = entity;
|
||||
}
|
||||
-
|
||||
+ // Paper start - Refresh ProjectileSource for projectiles
|
||||
+ else {
|
||||
+ this.ownerUUID = null;
|
||||
+ this.cachedOwner = null;
|
||||
+ this.projectileSource = null;
|
||||
+ }
|
||||
+ // Paper end - Refresh ProjectileSource for projectiles
|
||||
+ this.refreshProjectileSource(false); // Paper
|
||||
}
|
||||
+ // Paper start - Refresh ProjectileSource for projectiles
|
||||
+ public void refreshProjectileSource(boolean fillCache) {
|
||||
+ if (fillCache) {
|
||||
+ this.getOwner();
|
||||
+ }
|
||||
+ if (this.cachedOwner != null && !this.cachedOwner.isRemoved() && this.projectileSource == null && this.cachedOwner.getBukkitEntity() instanceof ProjectileSource projSource) {
|
||||
+ this.projectileSource = projSource;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Refresh ProjectileSource for projectiles
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity getOwner() {
|
||||
if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) {
|
||||
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
|
||||
return this.cachedOwner;
|
||||
} else if (this.ownerUUID != null) {
|
||||
this.cachedOwner = this.findOwner(this.ownerUUID);
|
||||
+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles
|
||||
return this.cachedOwner;
|
||||
} else {
|
||||
return null;
|
||||
@@ -108,6 +134,7 @@
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
if (nbt.hasUUID("Owner")) {
|
||||
this.setOwnerThroughUUID(nbt.getUUID("Owner"));
|
||||
+ if (this instanceof ThrownEnderpearl && this.level() != null && 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 = nbt.getBoolean("LeftOwner");
|
||||
@@ -184,12 +211,20 @@
|
||||
|
||||
this.shoot((double) f5, (double) f6, (double) f7, speed, divergence);
|
||||
Vec3 vec3d = shooter.getKnownMovement();
|
||||
-
|
||||
+ // Paper start - allow disabling relative velocity
|
||||
+ if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) {
|
||||
this.setDeltaMovement(this.getDeltaMovement().add(vec3d.x, shooter.onGround() ? 0.0D : vec3d.y, vec3d.z));
|
||||
+ }
|
||||
+ // Paper end - allow disabling relative velocity
|
||||
}
|
||||
|
||||
public static <T extends Projectile> T spawnProjectileFromRotation(Projectile.ProjectileFactory<T> creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) {
|
||||
- return Projectile.spawnProjectile(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> {
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ return spawnProjectileFromRotationDelayed(creator, world, projectileStack, shooter, roll, power, divergence).spawn();
|
||||
+ }
|
||||
+ public static <T extends Projectile> Delayed<T> spawnProjectileFromRotationDelayed(Projectile.ProjectileFactory<T> creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) {
|
||||
+ return Projectile.spawnProjectileDelayed(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> {
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
iprojectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot(), roll, power, divergence);
|
||||
});
|
||||
}
|
||||
@@ -201,7 +236,12 @@
|
||||
}
|
||||
|
||||
public static <T extends Projectile> T spawnProjectileUsingShoot(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) {
|
||||
- return Projectile.spawnProjectile(projectile, world, projectileStack, (iprojectile) -> {
|
||||
+ // Paper start - fixes and addition to spawn reason API
|
||||
+ return spawnProjectileUsingShootDelayed(projectile, world, projectileStack, velocityX, velocityY, velocityZ, power, divergence).spawn();
|
||||
+ }
|
||||
+ public static <T extends Projectile> Delayed<T> spawnProjectileUsingShootDelayed(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) {
|
||||
+ return Projectile.spawnProjectileDelayed(projectile, world, projectileStack, (iprojectile) -> {
|
||||
+ // Paper end - fixes and addition to spawn reason API
|
||||
projectile.shoot(velocityX, velocityY, velocityZ, power, divergence);
|
||||
});
|
||||
}
|
||||
@@ -211,11 +251,45 @@
|
||||
});
|
||||
}
|
||||
|
||||
+ // Paper start - delayed projectile spawning
|
||||
+ public record Delayed<T extends Projectile>(
|
||||
+ T projectile,
|
||||
+ ServerLevel world,
|
||||
+ ItemStack projectileStack
|
||||
+ ) {
|
||||
+ // Taken from net.minecraft.world.entity.projectile.Projectile.spawnProjectile(T, net.minecraft.server.level.ServerLevel, net.minecraft.world.item.ItemStack, java.util.function.Consumer<T>)
|
||||
+ public boolean attemptSpawn() {
|
||||
+ if (!world.addFreshEntity(projectile)) return false;
|
||||
+ projectile.applyOnProjectileSpawned(this.world, this.projectileStack);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public T spawn() {
|
||||
+ this.attemptSpawn();
|
||||
+ return projectile();
|
||||
+ }
|
||||
+
|
||||
+ public boolean attemptSpawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ if (!world.addFreshEntity(projectile, reason)) return false;
|
||||
+ projectile.applyOnProjectileSpawned(this.world, this.projectileStack);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public T spawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ this.attemptSpawn(reason);
|
||||
+ return projectile();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - delayed projectile spawning
|
||||
+
|
||||
public static <T extends Projectile> T spawnProjectile(T projectile, ServerLevel world, ItemStack projectileStack, Consumer<T> beforeSpawn) {
|
||||
+ // Paper start - delayed projectile spawning
|
||||
+ return spawnProjectileDelayed(projectile, world, projectileStack, beforeSpawn).spawn();
|
||||
+ }
|
||||
+ public static <T extends Projectile> Delayed<T> spawnProjectileDelayed(T projectile, ServerLevel world, ItemStack projectileStack, Consumer<T> beforeSpawn) {
|
||||
+ // Paper end - delayed projectile spawning
|
||||
beforeSpawn.accept(projectile);
|
||||
- world.addFreshEntity(projectile);
|
||||
- projectile.applyOnProjectileSpawned(world, projectileStack);
|
||||
- return projectile;
|
||||
+ return new Delayed<>(projectile, world, projectileStack); // Paper - delayed projectile spawning
|
||||
}
|
||||
|
||||
public void applyOnProjectileSpawned(ServerLevel world, ItemStack projectileStack) {
|
||||
@@ -232,6 +306,17 @@
|
||||
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - call projectile hit event
|
||||
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult movingobjectposition) { // Paper - protected -> public
|
||||
+ org.bukkit.event.entity.ProjectileHitEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition);
|
||||
+ this.hitCancelled = event != null && event.isCancelled();
|
||||
+ if (movingobjectposition.getType() == HitResult.Type.BLOCK || !this.hitCancelled) {
|
||||
+ return this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ }
|
||||
+ return ProjectileDeflection.NONE;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) {
|
||||
if (hitResult.getType() == HitResult.Type.ENTITY) {
|
||||
EntityHitResult movingobjectpositionentity = (EntityHitResult) hitResult;
|
||||
@@ -269,7 +354,13 @@
|
||||
public boolean deflect(ProjectileDeflection deflection, @Nullable Entity deflector, @Nullable Entity owner, boolean fromAttack) {
|
||||
deflection.deflect(this, deflector, this.random);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.setOwner(owner);
|
||||
+ // Paper start - Fix PickupStatus getting reset
|
||||
+ if (this instanceof AbstractArrow arrow) {
|
||||
+ arrow.setOwner(owner, false);
|
||||
+ } else {
|
||||
+ this.setOwner(owner);
|
||||
+ }
|
||||
+ // Paper end - Fix PickupStatus getting reset
|
||||
this.onDeflection(deflector, fromAttack);
|
||||
}
|
||||
|
||||
@@ -309,6 +400,11 @@
|
||||
protected void onHitEntity(EntityHitResult entityHitResult) {}
|
||||
|
||||
protected void onHitBlock(BlockHitResult blockHitResult) {
|
||||
+ // CraftBukkit start - cancellable hit event
|
||||
+ if (this.hitCancelled) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
BlockState iblockdata = this.level().getBlockState(blockHitResult.getBlockPos());
|
||||
|
||||
iblockdata.onProjectileHit(this.level(), iblockdata, blockHitResult, this);
|
||||
@@ -320,6 +416,15 @@
|
||||
} else {
|
||||
Entity entity1 = this.getOwner();
|
||||
|
||||
+ // Paper start - Cancel hit for vanished players
|
||||
+ if (entity1 instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity();
|
||||
+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity();
|
||||
+ if (!shooter.canSee(collided)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Cancel hit for vanished players
|
||||
return entity1 == null || this.leftOwner || !entity1.isPassengerOfSameVehicle(entity);
|
||||
}
|
||||
}
|
||||
@@ -333,14 +438,8 @@
|
||||
}
|
||||
|
||||
protected static float lerpRotation(float prevRot, float newRot) {
|
||||
- while (newRot - prevRot < -180.0F) {
|
||||
- prevRot -= 360.0F;
|
||||
- }
|
||||
+ prevRot += Math.round((newRot - prevRot) / 360.0F) * 360.0F; // Paper - stop large look changes from crashing the server
|
||||
|
||||
- while (newRot - prevRot >= 180.0F) {
|
||||
- prevRot += 360.0F;
|
||||
- }
|
||||
-
|
||||
return Mth.lerp(0.2F, prevRot, newRot);
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ShulkerBullet.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java
|
||||
@@ -31,6 +31,9 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ShulkerBullet extends Projectile {
|
||||
|
||||
@@ -60,8 +63,21 @@
|
||||
this.finalTarget = target;
|
||||
this.currentMoveDirection = Direction.UP;
|
||||
this.selectNextMoveDirection(axis);
|
||||
+ this.projectileSource = (org.bukkit.entity.LivingEntity) owner.getBukkitEntity(); // CraftBukkit
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public Entity getTarget() {
|
||||
+ return this.finalTarget;
|
||||
+ }
|
||||
+
|
||||
+ public void setTarget(Entity e) {
|
||||
+ this.finalTarget = e;
|
||||
+ this.currentMoveDirection = Direction.UP;
|
||||
+ this.selectNextMoveDirection(Direction.Axis.X);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public SoundSource getSoundSource() {
|
||||
return SoundSource.HOSTILE;
|
||||
@@ -194,7 +210,7 @@
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
||||
@@ -239,7 +255,7 @@
|
||||
}
|
||||
|
||||
if (movingobjectposition != null && this.isAlive() && movingobjectposition.getType() != HitResult.Type.MISS) {
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
}
|
||||
|
||||
ProjectileUtil.rotateTowardsMovement(this, 0.5F);
|
||||
@@ -312,7 +328,7 @@
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity entityliving1 = (LivingEntity) entity;
|
||||
|
||||
- entityliving1.addEffect(new MobEffectInstance(MobEffects.LEVITATION, 200), (Entity) MoreObjects.firstNonNull(entity1, this));
|
||||
+ entityliving1.addEffect(new MobEffectInstance(MobEffects.LEVITATION, 200), (Entity) MoreObjects.firstNonNull(entity1, this), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,14 +342,20 @@
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
- this.discard();
|
||||
+ // CraftBukkit start - add Bukkit remove cause
|
||||
+ this.destroy(null);
|
||||
+ }
|
||||
+
|
||||
+ private void destroy(EntityRemoveEvent.Cause cause) {
|
||||
+ this.discard(cause);
|
||||
+ // CraftBukkit end
|
||||
this.level().gameEvent((Holder) GameEvent.ENTITY_DAMAGE, this.position(), GameEvent.Context.of((Entity) this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
- this.destroy();
|
||||
+ this.destroy(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,9 +370,14 @@
|
||||
|
||||
@Override
|
||||
public boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount, false)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.playSound(SoundEvents.SHULKER_BULLET_HURT, 1.0F, 1.0F);
|
||||
world.sendParticles(ParticleTypes.CRIT, this.getX(), this.getY(), this.getZ(), 15, 0.2D, 0.2D, 0.2D, 0.0D);
|
||||
- this.destroy();
|
||||
+ this.destroy(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/SmallFireball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/SmallFireball.java
|
||||
@@ -15,6 +15,10 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class SmallFireball extends Fireball {
|
||||
|
||||
@@ -24,6 +28,11 @@
|
||||
|
||||
public SmallFireball(Level world, LivingEntity owner, Vec3 velocity) {
|
||||
super(EntityType.SMALL_FIREBALL, owner, velocity, world);
|
||||
+ // CraftBukkit start
|
||||
+ if (this.getOwner() != null && this.getOwner() instanceof Mob) {
|
||||
+ this.isIncendiary = (world instanceof ServerLevel worldserver) && worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public SmallFireball(Level world, double x, double y, double z, Vec3 velocity) {
|
||||
@@ -40,7 +49,14 @@
|
||||
Entity entity1 = this.getOwner();
|
||||
int i = entity.getRemainingFireTicks();
|
||||
|
||||
- entity.igniteForSeconds(5.0F);
|
||||
+ // CraftBukkit start - Entity damage by entity event + combust event
|
||||
+ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), entity.getBukkitEntity(), 5.0F);
|
||||
+ entity.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (!event.isCancelled()) {
|
||||
+ entity.igniteForSeconds(event.getDuration(), false);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
DamageSource damagesource = this.damageSources().fireball(this, entity1);
|
||||
|
||||
if (!entity.hurtServer(worldserver, damagesource, 5.0F)) {
|
||||
@@ -60,10 +76,10 @@
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
Entity entity = this.getOwner();
|
||||
|
||||
- if (!(entity instanceof Mob) || worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
|
||||
+ if (this.isIncendiary) { // CraftBukkit
|
||||
BlockPos blockposition = blockHitResult.getBlockPos().relative(blockHitResult.getDirection());
|
||||
|
||||
- if (this.level().isEmptyBlock(blockposition)) {
|
||||
+ if (this.level().isEmptyBlock(blockposition) && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.level(), blockposition, this).isCancelled()) { // CraftBukkit
|
||||
this.level().setBlockAndUpdate(blockposition, BaseFireBlock.getState(this.level(), blockposition));
|
||||
}
|
||||
}
|
||||
@@ -75,7 +91,7 @@
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/Snowball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Snowball.java
|
||||
@@ -13,6 +13,9 @@
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class Snowball extends ThrowableItemProjectile {
|
||||
|
||||
@@ -65,7 +68,7 @@
|
||||
super.onHit(hitResult);
|
||||
if (!this.level().isClientSide) {
|
||||
this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/SpectralArrow.java
|
||||
+++ b/net/minecraft/world/entity/projectile/SpectralArrow.java
|
||||
@@ -41,7 +41,7 @@
|
||||
super.doPostHurtEffects(target);
|
||||
MobEffectInstance mobeffect = new MobEffectInstance(MobEffects.GLOWING, this.duration, 0);
|
||||
|
||||
- target.addEffect(mobeffect, this.getEffectSource());
|
||||
+ target.addEffect(mobeffect, this.getEffectSource(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,11 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
@@ -63,7 +63,7 @@
|
||||
this.applyEffectsFromBlocks();
|
||||
super.tick();
|
||||
if (movingobjectposition.getType() != HitResult.Type.MISS && this.isAlive()) {
|
||||
- this.hitTargetOrDeflectSelf(movingobjectposition);
|
||||
+ this.preHitTargetOrDeflectSelf(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
}
|
||||
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
@@ -1,33 +1,39 @@
|
||||
package net.minecraft.world.entity.projectile;
|
||||
|
||||
-import net.minecraft.core.particles.ItemParticleOption;
|
||||
-import net.minecraft.core.particles.ParticleTypes;
|
||||
-import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
-import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
-import net.minecraft.world.entity.animal.Chicken;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
+import net.minecraft.core.particles.ItemParticleOption;
|
||||
+import net.minecraft.core.particles.ParticleTypes;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.EntityDimensions;
|
||||
+import org.bukkit.entity.Ageable;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.player.PlayerEggThrowEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ThrownEgg extends ThrowableItemProjectile {
|
||||
|
||||
private static final EntityDimensions ZERO_SIZED_DIMENSIONS = EntityDimensions.fixed(0.0F, 0.0F);
|
||||
|
||||
- public ThrownEgg(EntityType<? extends ThrownEgg> type, Level world) {
|
||||
+ public ThrownEgg(net.minecraft.world.entity.EntityType<? extends ThrownEgg> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
public ThrownEgg(Level world, LivingEntity owner, ItemStack stack) {
|
||||
- super(EntityType.EGG, owner, world, stack);
|
||||
+ super(net.minecraft.world.entity.EntityType.EGG, owner, world, stack);
|
||||
}
|
||||
|
||||
public ThrownEgg(Level world, double x, double y, double z, ItemStack stack) {
|
||||
- super(EntityType.EGG, x, y, z, world, stack);
|
||||
+ super(net.minecraft.world.entity.EntityType.EGG, x, y, z, world, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,30 +58,65 @@
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
if (!this.level().isClientSide) {
|
||||
- if (this.random.nextInt(8) == 0) {
|
||||
+ // CraftBukkit start
|
||||
+ boolean hatching = this.random.nextInt(8) == 0;
|
||||
+ if (true) {
|
||||
+ // CraftBukkit end
|
||||
byte b0 = 1;
|
||||
|
||||
if (this.random.nextInt(32) == 0) {
|
||||
b0 = 4;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ EntityType hatchingType = EntityType.CHICKEN;
|
||||
+
|
||||
+ Entity shooter = this.getOwner();
|
||||
+ if (!hatching) {
|
||||
+ b0 = 0;
|
||||
+ }
|
||||
+ if (shooter instanceof ServerPlayer) {
|
||||
+ PlayerEggThrowEvent event = new PlayerEggThrowEvent((Player) shooter.getBukkitEntity(), (org.bukkit.entity.Egg) this.getBukkitEntity(), hatching, b0, hatchingType);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ b0 = event.getNumHatches();
|
||||
+ hatching = event.isHatching();
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // If hatching is set to false, ensure child count is 0
|
||||
+ if (!hatching) {
|
||||
+ b0 = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add ThrownEggHatchEvent
|
||||
+ com.destroystokyo.paper.event.entity.ThrownEggHatchEvent event = new com.destroystokyo.paper.event.entity.ThrownEggHatchEvent((org.bukkit.entity.Egg) getBukkitEntity(), hatching, b0, hatchingType);
|
||||
+ event.callEvent();
|
||||
+ hatching = event.isHatching();
|
||||
+ b0 = hatching ? event.getNumHatches() : 0; // If hatching is set to false, ensure child count is 0
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // Paper end - Add ThrownEggHatchEvent
|
||||
+
|
||||
for (int i = 0; i < b0; ++i) {
|
||||
- Chicken entitychicken = (Chicken) EntityType.CHICKEN.create(this.level(), EntitySpawnReason.TRIGGERED);
|
||||
+ Entity entitychicken = this.level().getWorld().makeEntity(new org.bukkit.Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F), hatchingType.getEntityClass()); // CraftBukkit
|
||||
|
||||
if (entitychicken != null) {
|
||||
- entitychicken.setAge(-24000);
|
||||
+ // CraftBukkit start
|
||||
+ if (entitychicken.getBukkitEntity() instanceof Ageable) {
|
||||
+ ((Ageable) entitychicken.getBukkitEntity()).setBaby();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
entitychicken.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
|
||||
if (!entitychicken.fudgePositionAfterSizeChange(ThrownEgg.ZERO_SIZED_DIMENSIONS)) {
|
||||
break;
|
||||
}
|
||||
|
||||
- this.level().addFreshEntity(entitychicken);
|
||||
+ this.level().addFreshEntity(entitychicken, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // CraftBukkit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
@@ -24,10 +24,15 @@
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
+import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ThrownEnderpearl extends ThrowableItemProjectile {
|
||||
|
||||
@@ -140,12 +145,19 @@
|
||||
ServerPlayer entityplayer = (ServerPlayer) entity;
|
||||
|
||||
if (entityplayer.connection.isAcceptingMessages()) {
|
||||
+ // CraftBukkit start
|
||||
+ ServerPlayer entityplayer1 = entityplayer.teleport(new TeleportTransition(worldserver, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, PlayerTeleportEvent.TeleportCause.ENDER_PEARL));
|
||||
+ if (entityplayer1 == null) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT);
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (this.random.nextFloat() < 0.05F && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
|
||||
Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(worldserver, EntitySpawnReason.TRIGGERED);
|
||||
|
||||
if (entityendermite != null) {
|
||||
entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
|
||||
- worldserver.addFreshEntity(entityendermite);
|
||||
+ worldserver.addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,12 +165,12 @@
|
||||
entity.setPortalCooldown();
|
||||
}
|
||||
|
||||
- ServerPlayer entityplayer1 = entityplayer.teleport(new TeleportTransition(worldserver, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING));
|
||||
+ // EntityPlayer entityplayer1 = entityplayer.teleport(new TeleportTransition(worldserver, vec3d, Vec3D.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING)); // CraftBukkit - moved up
|
||||
|
||||
if (entityplayer1 != null) {
|
||||
entityplayer1.resetFallDistance();
|
||||
entityplayer1.resetCurrentImpulseContext();
|
||||
- entityplayer1.hurtServer(entityplayer.serverLevel(), this.damageSources().enderPearl(), 5.0F);
|
||||
+ entityplayer1.hurtServer(entityplayer.serverLevel(), this.damageSources().enderPearl().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
|
||||
}
|
||||
|
||||
this.playSound(worldserver, vec3d);
|
||||
@@ -173,11 +185,11 @@
|
||||
this.playSound(worldserver, vec3d);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +222,7 @@
|
||||
entity = this.getOwner();
|
||||
if (entity instanceof ServerPlayer entityplayer) {
|
||||
if (!entity.isAlive() && entityplayer.serverLevel().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
break label30;
|
||||
}
|
||||
}
|
||||
@@ -240,7 +252,7 @@
|
||||
Entity entity = super.teleport(teleportTarget);
|
||||
|
||||
if (entity != null) {
|
||||
- entity.placePortalTicket(BlockPos.containing(entity.position()));
|
||||
+ if (!this.level().paperConfig().misc.legacyEnderPearlBehavior) entity.placePortalTicket(BlockPos.containing(entity.position())); // Paper - Allow using old ender pearl behavior
|
||||
}
|
||||
|
||||
return entity;
|
||||
@@ -248,7 +260,7 @@
|
||||
|
||||
@Override
|
||||
public boolean canTeleport(Level from, Level to) {
|
||||
- if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) {
|
||||
+ if (from.getTypeKey() == LevelStem.END && to.getTypeKey() == LevelStem.OVERWORLD) { // CraftBukkit
|
||||
Entity entity = this.getOwner();
|
||||
|
||||
if (entity instanceof ServerPlayer) {
|
|
@ -1,36 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
@@ -9,6 +9,9 @@
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ThrownExperienceBottle extends ThrowableItemProjectile {
|
||||
|
||||
@@ -38,11 +41,20 @@
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
if (this.level() instanceof ServerLevel) {
|
||||
- this.level().levelEvent(2002, this.blockPosition(), -13083194);
|
||||
+ // CraftBukkit - moved to after event
|
||||
+ // this.level().levelEvent(2002, this.blockPosition(), -13083194);
|
||||
int i = 3 + this.level().random.nextInt(5) + this.level().random.nextInt(5);
|
||||
|
||||
- ExperienceOrb.award((ServerLevel) this.level(), this.position(), i);
|
||||
- this.discard();
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, hitResult, i);
|
||||
+ i = event.getExperience();
|
||||
+ if (event.getShowEffect()) {
|
||||
+ this.level().levelEvent(2002, this.blockPosition(), -13083194);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
|
@ -1,322 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownPotion.java
|
||||
@@ -10,6 +10,7 @@
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
@@ -17,7 +18,6 @@
|
||||
import net.minecraft.world.entity.AreaEffectCloud;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
-import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.animal.axolotl.Axolotl;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
@@ -28,18 +28,28 @@
|
||||
import net.minecraft.world.item.alchemy.Potions;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractCandleBlock;
|
||||
+// CraftBukkit start
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import net.minecraft.world.effect.MobEffects;
|
||||
+import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ThrownPotion extends ThrowableItemProjectile {
|
||||
|
||||
public static final double SPLASH_RANGE = 4.0D;
|
||||
private static final double SPLASH_RANGE_SQ = 16.0D;
|
||||
- public static final Predicate<LivingEntity> WATER_SENSITIVE_OR_ON_FIRE = (entityliving) -> {
|
||||
+ public static final Predicate<net.minecraft.world.entity.LivingEntity> WATER_SENSITIVE_OR_ON_FIRE = (entityliving) -> {
|
||||
return entityliving.isSensitiveToWater() || entityliving.isOnFire();
|
||||
};
|
||||
|
||||
@@ -47,7 +57,7 @@
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
- public ThrownPotion(Level world, LivingEntity owner, ItemStack stack) {
|
||||
+ public ThrownPotion(Level world, net.minecraft.world.entity.LivingEntity owner, ItemStack stack) {
|
||||
super(EntityType.POTION, owner, world, stack);
|
||||
}
|
||||
|
||||
@@ -93,70 +103,96 @@
|
||||
@Override
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
+ // Paper start - More projectile API
|
||||
+ this.splash(hitResult);
|
||||
+ }
|
||||
+ public void splash(@Nullable HitResult hitResult) {
|
||||
+ // Paper end - More projectile API
|
||||
Level world = this.level();
|
||||
-
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
ItemStack itemstack = this.getItem();
|
||||
PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
|
||||
+ boolean showParticles = true; // Paper - Fix potions splash events
|
||||
if (potioncontents.is(Potions.WATER)) {
|
||||
- this.applyWater(worldserver);
|
||||
- } else if (potioncontents.hasEffects()) {
|
||||
+ showParticles = this.applyWater(worldserver, hitResult); // 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, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
|
||||
} else {
|
||||
- this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null);
|
||||
+ showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
}
|
||||
}
|
||||
|
||||
+ if (showParticles) { // Paper - Fix potions splash events
|
||||
int i = potioncontents.potion().isPresent() && ((Potion) ((Holder) potioncontents.potion().get()).value()).hasInstantEffects() ? 2007 : 2002;
|
||||
|
||||
worldserver.levelEvent(i, this.blockPosition(), potioncontents.getColor());
|
||||
- this.discard();
|
||||
+ } // Paper - Fix potions splash events
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
}
|
||||
|
||||
- private void applyWater(ServerLevel world) {
|
||||
+ private static final Predicate<net.minecraft.world.entity.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 world, @Nullable HitResult hitResult) { // Paper - Fix potions splash events
|
||||
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
|
||||
- List<LivingEntity> list = this.level().getEntitiesOfClass(LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE);
|
||||
+ // Paper start - Fix potions splash events
|
||||
+ List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.APPLY_WATER_GET_ENTITIES_PREDICATE);
|
||||
+ Map<LivingEntity, Double> affected = new HashMap<>();
|
||||
+ java.util.Set<LivingEntity> rehydrate = new java.util.HashSet<>();
|
||||
+ java.util.Set<LivingEntity> extinguish = new java.util.HashSet<>();
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
- LivingEntity entityliving = (LivingEntity) iterator.next();
|
||||
+ net.minecraft.world.entity.LivingEntity entityliving = (net.minecraft.world.entity.LivingEntity) iterator.next();
|
||||
+ if (entityliving instanceof Axolotl axolotl) {
|
||||
+ rehydrate.add(((org.bukkit.entity.Axolotl) axolotl.getBukkitEntity()));
|
||||
+ }
|
||||
double d0 = this.distanceToSqr((Entity) entityliving);
|
||||
|
||||
if (d0 < 16.0D) {
|
||||
if (entityliving.isSensitiveToWater()) {
|
||||
- entityliving.hurtServer(world, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
|
||||
+ affected.put(entityliving.getBukkitLivingEntity(), 1.0);
|
||||
}
|
||||
|
||||
if (entityliving.isOnFire() && entityliving.isAlive()) {
|
||||
- entityliving.extinguishFire();
|
||||
+ extinguish.add(entityliving.getBukkitLivingEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- List<Axolotl> list1 = this.level().getEntitiesOfClass(Axolotl.class, axisalignedbb);
|
||||
- Iterator iterator1 = list1.iterator();
|
||||
-
|
||||
- while (iterator1.hasNext()) {
|
||||
- Axolotl axolotl = (Axolotl) iterator1.next();
|
||||
-
|
||||
- axolotl.rehydrate();
|
||||
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
|
||||
+ this, hitResult, affected, rehydrate, extinguish
|
||||
+ );
|
||||
+ if (!event.isCancelled()) {
|
||||
+ for (LivingEntity affectedEntity : event.getToDamage()) {
|
||||
+ ((CraftLivingEntity) affectedEntity).getHandle().hurtServer(world, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
|
||||
+ }
|
||||
+ for (LivingEntity toExtinguish : event.getToExtinguish()) {
|
||||
+ ((CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
|
||||
+ }
|
||||
+ for (LivingEntity toRehydrate : event.getToRehydrate()) {
|
||||
+ if (((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 world, Iterable<MobEffectInstance> effects, @Nullable Entity entity) {
|
||||
+ private boolean applySplash(ServerLevel worldserver, Iterable<MobEffectInstance> iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
|
||||
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
|
||||
- List<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, axisalignedbb);
|
||||
+ List<net.minecraft.world.entity.LivingEntity> list = worldserver.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
|
||||
+ Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
Entity entity1 = this.getEffectSource();
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
- LivingEntity entityliving = (LivingEntity) iterator.next();
|
||||
+ net.minecraft.world.entity.LivingEntity entityliving = (net.minecraft.world.entity.LivingEntity) iterator.next();
|
||||
|
||||
if (entityliving.isAffectedByPotions()) {
|
||||
double d0 = this.distanceToSqr((Entity) entityliving);
|
||||
@@ -164,43 +200,71 @@
|
||||
if (d0 < 16.0D) {
|
||||
double d1;
|
||||
|
||||
+ // Paper - diff on change, used when calling the splash event for water splash potions
|
||||
if (entityliving == entity) {
|
||||
d1 = 1.0D;
|
||||
} else {
|
||||
d1 = 1.0D - Math.sqrt(d0) / 4.0D;
|
||||
}
|
||||
|
||||
- Iterator iterator1 = effects.iterator();
|
||||
+ // CraftBukkit start
|
||||
+ affected.put((LivingEntity) entityliving.getBukkitEntity(), d1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- while (iterator1.hasNext()) {
|
||||
- MobEffectInstance mobeffect = (MobEffectInstance) iterator1.next();
|
||||
- Holder<MobEffect> holder = mobeffect.getEffect();
|
||||
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, position, affected);
|
||||
+ if (!event.isCancelled() && list != null && !list.isEmpty()) { // do not process effects if there are no effects to process
|
||||
+ Entity entity1 = this.getEffectSource();
|
||||
+ for (LivingEntity victim : event.getAffectedEntities()) {
|
||||
+ if (!(victim instanceof CraftLivingEntity)) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (((MobEffect) holder.value()).isInstantenous()) {
|
||||
- ((MobEffect) holder.value()).applyInstantenousEffect(world, this, this.getOwner(), entityliving, mobeffect.getAmplifier(), d1);
|
||||
- } else {
|
||||
- int i = mobeffect.mapDuration((j) -> {
|
||||
- return (int) (d1 * (double) j + 0.5D);
|
||||
- });
|
||||
- MobEffectInstance mobeffect1 = new MobEffectInstance(holder, i, mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isVisible());
|
||||
+ net.minecraft.world.entity.LivingEntity entityliving = ((CraftLivingEntity) victim).getHandle();
|
||||
+ double d1 = event.getIntensity(victim);
|
||||
+ // CraftBukkit end
|
||||
|
||||
- if (!mobeffect1.endsWithin(20)) {
|
||||
- entityliving.addEffect(mobeffect1, entity1);
|
||||
- }
|
||||
- }
|
||||
+ Iterator iterator1 = iterable.iterator();
|
||||
+
|
||||
+ while (iterator1.hasNext()) {
|
||||
+ MobEffectInstance mobeffect = (MobEffectInstance) iterator1.next();
|
||||
+ Holder<MobEffect> holder = mobeffect.getEffect();
|
||||
+ // CraftBukkit start - Abide by PVP settings - for players only!
|
||||
+ if (!this.level().pvpMode && this.getOwner() instanceof ServerPlayer && entityliving instanceof ServerPlayer && entityliving != this.getOwner()) {
|
||||
+ MobEffect mobeffectlist = (MobEffect) holder.value();
|
||||
+ if (mobeffectlist == MobEffects.MOVEMENT_SLOWDOWN || mobeffectlist == MobEffects.DIG_SLOWDOWN || mobeffectlist == MobEffects.HARM || mobeffectlist == MobEffects.BLINDNESS
|
||||
+ || mobeffectlist == MobEffects.HUNGER || mobeffectlist == MobEffects.WEAKNESS || mobeffectlist == MobEffects.POISON) {
|
||||
+ continue;
|
||||
}
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ if (((MobEffect) holder.value()).isInstantenous()) {
|
||||
+ ((MobEffect) holder.value()).applyInstantenousEffect(worldserver, this, this.getOwner(), entityliving, mobeffect.getAmplifier(), d1);
|
||||
+ } else {
|
||||
+ int i = mobeffect.mapDuration((j) -> {
|
||||
+ return (int) (d1 * (double) j + 0.5D);
|
||||
+ });
|
||||
+ MobEffectInstance mobeffect1 = new MobEffectInstance(holder, i, mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isVisible());
|
||||
+
|
||||
+ if (!mobeffect1.endsWithin(20)) {
|
||||
+ entityliving.addEffect(mobeffect1, entity1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
|
||||
}
|
||||
|
||||
- private void makeAreaOfEffectCloud(PotionContents potion) {
|
||||
+ private boolean makeAreaOfEffectCloud(PotionContents potioncontents, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
||||
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
|
||||
Entity entity = this.getOwner();
|
||||
|
||||
- if (entity instanceof LivingEntity entityliving) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.LivingEntity entityliving) {
|
||||
entityareaeffectcloud.setOwner(entityliving);
|
||||
}
|
||||
|
||||
@@ -208,8 +272,17 @@
|
||||
entityareaeffectcloud.setRadiusOnUse(-0.5F);
|
||||
entityareaeffectcloud.setWaitTime(10);
|
||||
entityareaeffectcloud.setRadiusPerTick(-entityareaeffectcloud.getRadius() / (float) entityareaeffectcloud.getDuration());
|
||||
- entityareaeffectcloud.setPotionContents(potion);
|
||||
- this.level().addFreshEntity(entityareaeffectcloud);
|
||||
+ entityareaeffectcloud.setPotionContents(potioncontents);
|
||||
+ boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud);
|
||||
+ if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !entityareaeffectcloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
|
||||
+ this.level().addFreshEntity(entityareaeffectcloud);
|
||||
+ } else {
|
||||
+ entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ return !event.isCancelled(); // Paper - Fix potions splash events
|
||||
}
|
||||
|
||||
public boolean isLingering() {
|
||||
@@ -220,19 +293,31 @@
|
||||
BlockState iblockdata = this.level().getBlockState(pos);
|
||||
|
||||
if (iblockdata.is(BlockTags.FIRE)) {
|
||||
- this.level().destroyBlock(pos, false, this);
|
||||
+ // CraftBukkit start
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this, pos, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
+ this.level().destroyBlock(pos, false, this);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (AbstractCandleBlock.isLit(iblockdata)) {
|
||||
- AbstractCandleBlock.extinguish((Player) null, iblockdata, this.level(), pos);
|
||||
+ // CraftBukkit start
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this, pos, iblockdata.setValue(AbstractCandleBlock.LIT, false))) {
|
||||
+ AbstractCandleBlock.extinguish((Player) null, iblockdata, this.level(), pos);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (CampfireBlock.isLitCampfire(iblockdata)) {
|
||||
- this.level().levelEvent((Player) null, 1009, pos, 0);
|
||||
- CampfireBlock.dowse(this.getOwner(), this.level(), pos, iblockdata);
|
||||
- this.level().setBlockAndUpdate(pos, (BlockState) iblockdata.setValue(CampfireBlock.LIT, false));
|
||||
+ // CraftBukkit start
|
||||
+ if (CraftEventFactory.callEntityChangeBlockEvent(this, pos, iblockdata.setValue(CampfireBlock.LIT, false))) {
|
||||
+ this.level().levelEvent((Player) null, 1009, pos, 0);
|
||||
+ CampfireBlock.dowse(this.getOwner(), this.level(), pos, iblockdata);
|
||||
+ this.level().setBlockAndUpdate(pos, (BlockState) iblockdata.setValue(CampfireBlock.LIT, false));
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
- public DoubleDoubleImmutablePair calculateHorizontalHurtKnockbackDirection(LivingEntity target, DamageSource source) {
|
||||
+ public DoubleDoubleImmutablePair calculateHorizontalHurtKnockbackDirection(net.minecraft.world.entity.LivingEntity target, DamageSource source) {
|
||||
double d0 = target.position().x - this.position().x;
|
||||
double d1 = target.position().z - this.position().z;
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
+++ b/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
@@ -23,6 +23,9 @@
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ThrownTrident extends AbstractArrow {
|
||||
|
||||
@@ -34,16 +37,19 @@
|
||||
|
||||
public ThrownTrident(EntityType<? extends ThrownTrident> type, Level world) {
|
||||
super(type, world);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, LivingEntity owner, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, owner, world, stack, (ItemStack) null);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, double x, double y, double z, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, x, y, z, world, stack, stack);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
@@ -76,10 +82,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
if (!(entity instanceof Player) && this.position().distanceTo(entity.getEyePosition()) < (double) entity.getBbWidth() + 1.0D) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,8 +115,22 @@
|
||||
|
||||
public boolean isFoil() {
|
||||
return (Boolean) this.entityData.get(ThrownTrident.ID_FOIL);
|
||||
+ }
|
||||
+
|
||||
+ // Paper start
|
||||
+ public void setFoil(boolean foil) {
|
||||
+ this.entityData.set(ThrownTrident.ID_FOIL, foil);
|
||||
}
|
||||
|
||||
+ public int getLoyalty() {
|
||||
+ return this.entityData.get(ThrownTrident.ID_LOYALTY);
|
||||
+ }
|
||||
+
|
||||
+ public void setLoyalty(byte loyalty) {
|
||||
+ this.entityData.set(ThrownTrident.ID_LOYALTY, loyalty);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
@Override
|
||||
protected EntityHitResult findHitEntity(Vec3 currentPosition, Vec3 nextPosition) {
|
||||
@@ -120,7 +140,7 @@
|
||||
@Override
|
||||
protected void onHitEntity(EntityHitResult entityHitResult) {
|
||||
Entity entity = entityHitResult.getEntity();
|
||||
- float f = 8.0F;
|
||||
+ float f = (float) this.getBaseDamage(); // Paper - Allow trident custom damage
|
||||
Entity entity1 = this.getOwner();
|
||||
DamageSource damagesource = this.damageSources().trident(this, (Entity) (entity1 == null ? this : entity1));
|
||||
Level world = this.level();
|
||||
@@ -137,7 +157,7 @@
|
||||
|
||||
world = this.level();
|
||||
if (world instanceof ServerLevel) {
|
||||
- worldserver = (ServerLevel) world;
|
||||
+ ServerLevel worldserver = (ServerLevel) world; // CraftBukkit - decompile error
|
||||
EnchantmentHelper.doPostAttackEffectsWithItemSourceOnBreak(worldserver, entity, damagesource, this.getWeaponItem(), (item) -> {
|
||||
this.kill(worldserver);
|
||||
});
|
|
@ -1,55 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/projectile/WitherSkull.java
|
||||
+++ b/net/minecraft/world/entity/projectile/WitherSkull.java
|
||||
@@ -23,6 +23,10 @@
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class WitherSkull extends AbstractHurtingProjectile {
|
||||
|
||||
@@ -69,11 +73,11 @@
|
||||
if (entity.isAlive()) {
|
||||
EnchantmentHelper.doPostAttackEffects(worldserver, entity, damagesource);
|
||||
} else {
|
||||
- entityliving.heal(5.0F);
|
||||
+ entityliving.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- flag = entity.hurtServer(worldserver, this.damageSources().magic(), 5.0F);
|
||||
+ flag = entity.hurtServer(worldserver, this.damageSources().magic().customEventDamager(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls // Paper - fix DamageSource API
|
||||
}
|
||||
|
||||
if (flag && entity instanceof LivingEntity entityliving) {
|
||||
@@ -86,7 +90,7 @@
|
||||
}
|
||||
|
||||
if (b0 > 0) {
|
||||
- entityliving.addEffect(new MobEffectInstance(MobEffects.WITHER, 20 * b0, 1), this.getEffectSource());
|
||||
+ entityliving.addEffect(new MobEffectInstance(MobEffects.WITHER, 20 * b0, 1), this.getEffectSource(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,8 +101,16 @@
|
||||
protected void onHit(HitResult hitResult) {
|
||||
super.onHit(hitResult);
|
||||
if (!this.level().isClientSide) {
|
||||
- this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, Level.ExplosionInteraction.MOB);
|
||||
- this.discard();
|
||||
+ // CraftBukkit start
|
||||
+ // this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB);
|
||||
+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (!event.isCancelled()) {
|
||||
+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue