13
0
geforkt von Mirrors/Paper

net.minecraft.world.entity.boss.wither

Dieser Commit ist enthalten in:
Jake Potrebic 2024-12-14 10:48:01 -08:00
Ursprung ca35cc216e
Commit 7b75c1b42e
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: ECE0B3C133C016C5
2 geänderte Dateien mit 123 neuen und 165 gelöschten Zeilen

Datei anzeigen

@ -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 {

Datei anzeigen

@ -1,165 +0,0 @@
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -10,14 +10,10 @@
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
+import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
-import net.minecraft.server.level.ServerBossEvent;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.sounds.SoundEvent;
-import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.tags.EntityTypeTags;
@@ -54,8 +50,21 @@
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerBossEvent;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundEvents;
+import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.ExplosionPrimeEvent;
+// CraftBukkit end
public class WitherBoss extends Monster implements RangedAttackMob {
@@ -77,7 +86,12 @@
return !entityliving.getType().is(EntityTypeTags.WITHER_FRIENDS) && entityliving.attackable();
};
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR);
+ // Paper start
+ private boolean canPortal = false;
+ public void setCanTravelThroughPortals(boolean canPortal) { this.canPortal = canPortal; }
+ // Paper end
+
public WitherBoss(EntityType<? extends WitherBoss> type, Level world) {
super(type, world);
this.bossEvent = (ServerBossEvent) (new ServerBossEvent(this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS)).setDarkenScreen(true);
@@ -252,15 +266,42 @@
i = this.getInvulnerableTicks() - 1;
this.bossEvent.setProgress(1.0F - (float) i / 220.0F);
if (i <= 0) {
- world.explode(this, this.getX(), this.getEyeY(), this.getZ(), 7.0F, false, Level.ExplosionInteraction.MOB);
+ // CraftBukkit start
+ // worldserver.explode(this, this.getX(), this.getEyeY(), this.getZ(), 7.0F, false, World.a.MOB);
+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
+ world.getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ world.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
+ }
+ // CraftBukkit end
+
if (!this.isSilent()) {
- world.globalLevelEvent(1023, this.blockPosition(), 0);
+ // CraftBukkit start - Use relative location for far away sounds
+ // worldserver.globalLevelEvent(1023, new BlockPosition(this), 0);
+ int viewDistance = world.getCraftServer().getViewDistance() * 16;
+ for (ServerPlayer player : world.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 = world.getGlobalSoundRangeSquared(config -> config.witherSpawnSoundRadius); // Paper - respect global sound events gamerule
+ if ( !world.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, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit
}
} else {
@@ -305,6 +346,7 @@
if (!list.isEmpty()) {
LivingEntity entityliving1 = (LivingEntity) list.get(this.random.nextInt(list.size()));
+ if (CraftEventFactory.callEntityTargetLivingEvent(this, entityliving1, EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled()) continue; // CraftBukkit
this.setAlternativeTarget(i, entityliving1.getId());
}
}
@@ -331,6 +373,11 @@
BlockState iblockdata = world.getBlockState(blockposition);
if (WitherBoss.canDestroy(iblockdata)) {
+ // CraftBukkit start
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
+ continue;
+ }
+ // CraftBukkit end
flag = world.destroyBlock(blockposition, true, this) || flag;
}
}
@@ -342,7 +389,7 @@
}
if (this.tickCount % 20 == 0) {
- this.heal(1.0F);
+ this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
@@ -488,10 +535,10 @@
@Override
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {
super.dropCustomDeathLoot(world, source, causedByPlayer);
- ItemEntity entityitem = this.spawnAtLocation(world, (ItemLike) Items.NETHER_STAR);
+ ItemEntity entityitem = this.spawnAtLocation(world, 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 (entityitem != null) {
- entityitem.setExtendedLifetime();
+ entityitem.setExtendedLifetime(); // Paper - diff on change
}
}
@@ -499,7 +546,7 @@
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
this.noActionTime = 0;
}
@@ -549,12 +596,12 @@
@Override
public boolean canUsePortal(boolean allowVehicles) {
- return false;
+ return this.canPortal; // Paper
}
@Override
public boolean canBeAffected(MobEffectInstance effect) {
- return effect.is(MobEffects.WITHER) ? false : super.canBeAffected(effect);
+ return effect.is(MobEffects.WITHER) && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
}
private class WitherDoNothingGoal extends Goal {