net.minecraft.world.entity.boss.wither

This commit is contained in:
Jake Potrebic
2024-12-14 10:48:01 -08:00
parent ca35cc216e
commit 7b75c1b42e
2 changed files with 123 additions and 165 deletions

View File

@@ -0,0 +1,123 @@
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -77,6 +_,12 @@
&& entity.attackable();
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR);
+ // Paper start
+ private boolean canPortal = false;
+
+ public void setCanTravelThroughPortals(boolean canPortal) { this.canPortal = canPortal; }
+ // Paper end
+
public WitherBoss(EntityType<? extends WitherBoss> entityType, Level level) {
super(entityType, level);
this.moveControl = new FlyingMoveControl(this, 10, false);
@@ -260,15 +_,40 @@
int i = this.getInvulnerableTicks() - 1;
this.bossEvent.setProgress(1.0F - i / 220.0F);
if (i <= 0) {
- level.explode(this, this.getX(), this.getEyeY(), this.getZ(), 7.0F, false, Level.ExplosionInteraction.MOB);
+ // CraftBukkit start
+ org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ level.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
+ }
+ // CraftBukkit end
if (!this.isSilent()) {
- level.globalLevelEvent(1023, this.blockPosition(), 0);
+ // CraftBukkit start - Use relative location for far away sounds
+ // level.globalLevelEvent(1023, this.blockPosition(), 0);
+ int viewDistance = level.getCraftServer().getViewDistance() * 16;
+ for (ServerPlayer player : level.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule
+ double deltaX = this.getX() - player.getX();
+ double deltaZ = this.getZ() - player.getZ();
+ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
+ final double soundRadiusSquared = level.getGlobalSoundRangeSquared(config -> config.witherSpawnSoundRadius); // Paper - respect global sound events gamerule
+ if (!level.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared) continue; // Spigot // Paper - respect global sound events gamerule
+ if (distanceSquared > viewDistance * viewDistance) {
+ double deltaLength = Math.sqrt(distanceSquared);
+ double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance;
+ double relativeZ = player.getZ() + (deltaZ / deltaLength) * viewDistance;
+ player.connection.send(new ClientboundLevelEventPacket(1023, new BlockPos((int) relativeX, (int) this.getY(), (int) relativeZ), 0, true));
+ } else {
+ player.connection.send(new ClientboundLevelEventPacket(1023, this.blockPosition(), 0, true));
+ }
+ }
+ // CraftBukkit end
}
}
this.setInvulnerableTicks(i);
if (this.tickCount % 10 == 0) {
- this.heal(10.0F);
+ this.heal(10.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit
}
} else {
super.customServerAiStep(level);
@@ -305,6 +_,7 @@
);
if (!nearbyEntities.isEmpty()) {
LivingEntity livingEntity1 = nearbyEntities.get(this.random.nextInt(nearbyEntities.size()));
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(this, livingEntity1, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled()) continue; // CraftBukkit
this.setAlternativeTarget(ix, livingEntity1.getId());
}
}
@@ -334,6 +_,11 @@
)) {
BlockState blockState = level.getBlockState(blockPos);
if (canDestroy(blockState)) {
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockPos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
+ continue;
+ }
+ // CraftBukkit end
flag = level.destroyBlock(blockPos, true, this) || flag;
}
}
@@ -345,7 +_,7 @@
}
if (this.tickCount % 20 == 0) {
- this.heal(1.0F);
+ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
@@ -483,16 +_,16 @@
@Override
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
super.dropCustomDeathLoot(level, damageSource, recentlyHit);
- ItemEntity itemEntity = this.spawnAtLocation(level, Items.NETHER_STAR);
+ ItemEntity itemEntity = this.spawnAtLocation(level, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
if (itemEntity != null) {
- itemEntity.setExtendedLifetime();
+ itemEntity.setExtendedLifetime(); // Paper - diff on change
}
}
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
this.noActionTime = 0;
}
@@ -547,12 +_,12 @@
@Override
public boolean canUsePortal(boolean allowPassengers) {
- return false;
+ return this.canPortal; // Paper
}
@Override
public boolean canBeAffected(MobEffectInstance potioneffect) {
- return !potioneffect.is(MobEffects.WITHER) && super.canBeAffected(potioneffect);
+ return (!potioneffect.is(MobEffects.WITHER) || !this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither) && super.canBeAffected(potioneffect);
}
class WitherDoNothingGoal extends Goal {