aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch')
-rw-r--r--patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch693
1 files changed, 693 insertions, 0 deletions
diff --git a/patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch b/patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch
new file mode 100644
index 0000000000..1931ef0c75
--- /dev/null
+++ b/patch-remap/mache-spigotflower/net/minecraft/world/entity/monster/Zombie.java.patch
@@ -0,0 +1,693 @@
+--- a/net/minecraft/world/entity/monster/Zombie.java
++++ b/net/minecraft/world/entity/monster/Zombie.java
+@@ -6,18 +6,6 @@
+ import java.util.UUID;
+ import java.util.function.Predicate;
+ import javax.annotation.Nullable;
+-import net.minecraft.core.BlockPos;
+-import net.minecraft.nbt.CompoundTag;
+-import net.minecraft.nbt.NbtOps;
+-import net.minecraft.nbt.Tag;
+-import net.minecraft.network.syncher.EntityDataAccessor;
+-import net.minecraft.network.syncher.EntityDataSerializers;
+-import net.minecraft.network.syncher.SynchedEntityData;
+-import net.minecraft.server.level.ServerLevel;
+-import net.minecraft.sounds.SoundEvent;
+-import net.minecraft.sounds.SoundEvents;
+-import net.minecraft.sounds.SoundSource;
+-import net.minecraft.tags.FluidTags;
+ import net.minecraft.util.Mth;
+ import net.minecraft.util.RandomSource;
+ import net.minecraft.world.Difficulty;
+@@ -25,15 +13,15 @@
+ import net.minecraft.world.damagesource.DamageSource;
+ import net.minecraft.world.entity.Entity;
+ import net.minecraft.world.entity.EntityDimensions;
++import net.minecraft.world.entity.EntityPose;
+ import net.minecraft.world.entity.EntitySelector;
+ import net.minecraft.world.entity.EntityType;
++import net.minecraft.world.entity.EnumMobSpawn;
++import net.minecraft.world.entity.EnumMonsterType;
+ import net.minecraft.world.entity.EquipmentSlot;
++import net.minecraft.world.entity.GroupDataEntity;
+ import net.minecraft.world.entity.LivingEntity;
+-import net.minecraft.world.entity.MobSpawnType;
+-import net.minecraft.world.entity.MobType;
+ import net.minecraft.world.entity.PathfinderMob;
+-import net.minecraft.world.entity.Pose;
+-import net.minecraft.world.entity.SpawnGroupData;
+ import net.minecraft.world.entity.SpawnPlacements;
+ import net.minecraft.world.entity.ai.attributes.AttributeInstance;
+ import net.minecraft.world.entity.ai.attributes.AttributeModifier;
+@@ -64,8 +52,27 @@
+ import net.minecraft.world.level.NaturalSpawner;
+ import net.minecraft.world.level.ServerLevelAccessor;
+ import net.minecraft.world.level.block.Blocks;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import org.joml.Vector3f;
++import net.minecraft.core.BlockPos;
++import net.minecraft.nbt.CompoundTag;
++import net.minecraft.nbt.NbtOps;
++import net.minecraft.nbt.Tag;
++import net.minecraft.network.syncher.EntityDataAccessor;
++import net.minecraft.network.syncher.EntityDataSerializers;
++import net.minecraft.network.syncher.SynchedEntityData;
++// CraftBukkit start
++import net.minecraft.server.MinecraftServer;
++import net.minecraft.server.level.ServerLevel;
++import net.minecraft.sounds.SoundEvent;
++import net.minecraft.sounds.SoundEvents;
++import net.minecraft.sounds.SoundSource;
++import net.minecraft.tags.FluidTags;
++import org.bukkit.event.entity.CreatureSpawnEvent;
++import org.bukkit.event.entity.EntityCombustByEntityEvent;
++import org.bukkit.event.entity.EntityTargetEvent;
++import org.bukkit.event.entity.EntityTransformEvent;
++// CraftBukkit end
+
+ public class Zombie extends Monster {
+
+@@ -73,23 +80,24 @@
+ private static final AttributeModifier SPEED_MODIFIER_BABY = new AttributeModifier(Zombie.SPEED_MODIFIER_BABY_UUID, "Baby speed boost", 0.5D, AttributeModifier.Operation.MULTIPLY_BASE);
+ private static final EntityDataAccessor<Boolean> DATA_BABY_ID = SynchedEntityData.defineId(Zombie.class, EntityDataSerializers.BOOLEAN);
+ private static final EntityDataAccessor<Integer> DATA_SPECIAL_TYPE_ID = SynchedEntityData.defineId(Zombie.class, EntityDataSerializers.INT);
+- private static final EntityDataAccessor<Boolean> DATA_DROWNED_CONVERSION_ID = SynchedEntityData.defineId(Zombie.class, EntityDataSerializers.BOOLEAN);
++ public static final EntityDataAccessor<Boolean> DATA_DROWNED_CONVERSION_ID = SynchedEntityData.defineId(Zombie.class, EntityDataSerializers.BOOLEAN);
+ public static final float ZOMBIE_LEADER_CHANCE = 0.05F;
+ public static final int REINFORCEMENT_ATTEMPTS = 50;
+ public static final int REINFORCEMENT_RANGE_MAX = 40;
+ public static final int REINFORCEMENT_RANGE_MIN = 7;
+ protected static final float BABY_EYE_HEIGHT_ADJUSTMENT = 0.81F;
+ private static final float BREAK_DOOR_CHANCE = 0.1F;
+- private static final Predicate<Difficulty> DOOR_BREAKING_PREDICATE = (difficulty) -> {
+- return difficulty == Difficulty.HARD;
++ private static final Predicate<Difficulty> DOOR_BREAKING_PREDICATE = (enumdifficulty) -> {
++ return enumdifficulty == Difficulty.HARD;
+ };
+ private final BreakDoorGoal breakDoorGoal;
+ private boolean canBreakDoors;
+ private int inWaterTime;
+- private int conversionTime;
++ public int conversionTime;
++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field
+
+- public Zombie(EntityType<? extends Zombie> entitytype, Level level) {
+- super(entitytype, level);
++ public Zombie(EntityType<? extends Zombie> entityType, Level level) {
++ super(entityType, level);
+ this.breakDoorGoal = new BreakDoorGoal(this, Zombie.DOOR_BREAKING_PREDICATE);
+ }
+
+@@ -98,7 +106,6 @@
+ }
+
+ @Override
+- @Override
+ protected void registerGoals() {
+ this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3));
+ this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F));
+@@ -122,7 +129,6 @@
+ }
+
+ @Override
+- @Override
+ protected void defineSynchedData() {
+ super.defineSynchedData();
+ this.getEntityData().define(Zombie.DATA_BABY_ID, false);
+@@ -138,12 +144,12 @@
+ return this.canBreakDoors;
+ }
+
+- public void setCanBreakDoors(boolean flag) {
++ public void setCanBreakDoors(boolean canBreakDoors) {
+ if (this.supportsBreakDoorGoal() && GoalUtils.hasGroundPathNavigation(this)) {
+- if (this.canBreakDoors != flag) {
+- this.canBreakDoors = flag;
+- ((GroundPathNavigation) this.getNavigation()).setCanOpenDoors(flag);
+- if (flag) {
++ if (this.canBreakDoors != canBreakDoors) {
++ this.canBreakDoors = canBreakDoors;
++ ((GroundPathNavigation) this.getNavigation()).setCanOpenDoors(canBreakDoors);
++ if (canBreakDoors) {
+ this.goalSelector.addGoal(1, this.breakDoorGoal);
+ } else {
+ this.goalSelector.removeGoal(this.breakDoorGoal);
+@@ -161,13 +167,11 @@
+ }
+
+ @Override
+- @Override
+ public boolean isBaby() {
+ return (Boolean) this.getEntityData().get(Zombie.DATA_BABY_ID);
+ }
+
+ @Override
+- @Override
+ public int getExperienceReward() {
+ if (this.isBaby()) {
+ this.xpReward = (int) ((double) this.xpReward * 2.5D);
+@@ -177,28 +181,26 @@
+ }
+
+ @Override
+- @Override
+- public void setBaby(boolean flag) {
+- this.getEntityData().set(Zombie.DATA_BABY_ID, flag);
++ public void setBaby(boolean childZombie) {
++ this.getEntityData().set(Zombie.DATA_BABY_ID, childZombie);
+ if (this.level() != null && !this.level().isClientSide) {
+- AttributeInstance attributeinstance = this.getAttribute(Attributes.MOVEMENT_SPEED);
++ AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED);
+
+- attributeinstance.removeModifier(Zombie.SPEED_MODIFIER_BABY.getId());
+- if (flag) {
+- attributeinstance.addTransientModifier(Zombie.SPEED_MODIFIER_BABY);
++ attributemodifiable.removeModifier(Zombie.SPEED_MODIFIER_BABY.getId());
++ if (childZombie) {
++ attributemodifiable.addTransientModifier(Zombie.SPEED_MODIFIER_BABY);
+ }
+ }
+
+ }
+
+ @Override
+- @Override
+- public void onSyncedDataUpdated(EntityDataAccessor<?> entitydataaccessor) {
+- if (Zombie.DATA_BABY_ID.equals(entitydataaccessor)) {
++ public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
++ if (Zombie.DATA_BABY_ID.equals(key)) {
+ this.refreshDimensions();
+ }
+
+- super.onSyncedDataUpdated(entitydataaccessor);
++ super.onSyncedDataUpdated(key);
+ }
+
+ protected boolean convertsInWater() {
+@@ -206,11 +208,13 @@
+ }
+
+ @Override
+- @Override
+ public void tick() {
+ if (!this.level().isClientSide && this.isAlive() && !this.isNoAi()) {
+ if (this.isUnderWaterConverting()) {
+- --this.conversionTime;
++ // CraftBukkit start - Use wall time instead of ticks for conversion
++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
++ this.conversionTime -= elapsedTicks;
++ // CraftBukkit end
+ if (this.conversionTime < 0) {
+ this.doUnderWaterConversion();
+ }
+@@ -227,10 +231,10 @@
+ }
+
+ super.tick();
++ this.lastTick = MinecraftServer.currentTick; // CraftBukkit
+ }
+
+ @Override
+- @Override
+ public void aiStep() {
+ if (this.isAlive()) {
+ boolean flag = this.isSunSensitive() && this.isSunBurnTick();
+@@ -259,8 +263,9 @@
+ super.aiStep();
+ }
+
+- private void startUnderWaterConversion(int i) {
+- this.conversionTime = i;
++ public void startUnderWaterConversion(int conversionTime) {
++ this.lastTick = MinecraftServer.currentTick; // CraftBukkit
++ this.conversionTime = conversionTime;
+ this.getEntityData().set(Zombie.DATA_DROWNED_CONVERSION_ID, true);
+ }
+
+@@ -272,12 +277,16 @@
+
+ }
+
+- protected void convertToZombieType(EntityType<? extends Zombie> entitytype) {
+- Zombie zombie = (Zombie) this.convertTo(entitytype, true);
++ protected void convertToZombieType(EntityType<? extends Zombie> entityType) {
++ Zombie entityzombie = (Zombie) this.convertTo(entityType, true, EntityTransformEvent.TransformReason.DROWNED, CreatureSpawnEvent.SpawnReason.DROWNED);
+
+- if (zombie != null) {
+- zombie.handleAttributes(zombie.level().getCurrentDifficultyAt(zombie.blockPosition()).getSpecialMultiplier());
+- zombie.setCanBreakDoors(zombie.supportsBreakDoorGoal() && this.canBreakDoors());
++ if (entityzombie != null) {
++ entityzombie.handleAttributes(entityzombie.level().getCurrentDifficultyAt(entityzombie.blockPosition()).getSpecialMultiplier());
++ entityzombie.setCanBreakDoors(entityzombie.supportsBreakDoorGoal() && this.canBreakDoors());
++ // CraftBukkit start - SPIGOT-5208: End conversion to stop event spam
++ } else {
++ ((org.bukkit.entity.Zombie) getBukkitEntity()).setConversionTime(-1);
++ // CraftBukkit end
+ }
+
+ }
+@@ -287,42 +296,41 @@
+ }
+
+ @Override
+- @Override
+- public boolean hurt(DamageSource damagesource, float f) {
+- if (!super.hurt(damagesource, f)) {
++ public boolean hurt(DamageSource source, float amount) {
++ if (!super.hurt(source, amount)) {
+ return false;
+ } else if (!(this.level() instanceof ServerLevel)) {
+ return false;
+ } else {
+- ServerLevel serverlevel = (ServerLevel) this.level();
+- LivingEntity livingentity = this.getTarget();
++ ServerLevel worldserver = (ServerLevel) this.level();
++ LivingEntity entityliving = this.getTarget();
+
+- if (livingentity == null && damagesource.getEntity() instanceof LivingEntity) {
+- livingentity = (LivingEntity) damagesource.getEntity();
++ if (entityliving == null && source.getEntity() instanceof LivingEntity) {
++ entityliving = (LivingEntity) source.getEntity();
+ }
+
+- if (livingentity != null && this.level().getDifficulty() == Difficulty.HARD && (double) this.random.nextFloat() < this.getAttributeValue(Attributes.SPAWN_REINFORCEMENTS_CHANCE) && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
++ if (entityliving != null && this.level().getDifficulty() == Difficulty.HARD && (double) this.random.nextFloat() < this.getAttributeValue(Attributes.SPAWN_REINFORCEMENTS_CHANCE) && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
+ int i = Mth.floor(this.getX());
+ int j = Mth.floor(this.getY());
+ int k = Mth.floor(this.getZ());
+- Zombie zombie = new Zombie(this.level());
++ Zombie entityzombie = new Zombie(this.level());
+
+ for (int l = 0; l < 50; ++l) {
+ int i1 = i + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
+ int j1 = j + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
+ int k1 = k + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
+- BlockPos blockpos = new BlockPos(i1, j1, k1);
+- EntityType<?> entitytype = zombie.getType();
+- SpawnPlacements.Type spawnplacements_type = SpawnPlacements.getPlacementType(entitytype);
++ BlockPos blockposition = new BlockPos(i1, j1, k1);
++ EntityType<?> entitytypes = entityzombie.getType();
++ SpawnPlacements.Surface entitypositiontypes_surface = SpawnPlacements.getPlacementType(entitytypes);
+
+- if (NaturalSpawner.isSpawnPositionOk(spawnplacements_type, this.level(), blockpos, entitytype) && SpawnPlacements.checkSpawnRules(entitytype, serverlevel, MobSpawnType.REINFORCEMENT, blockpos, this.level().random)) {
+- zombie.setPos((double) i1, (double) j1, (double) k1);
+- if (!this.level().hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(zombie) && this.level().noCollision((Entity) zombie) && !this.level().containsAnyLiquid(zombie.getBoundingBox())) {
+- zombie.setTarget(livingentity);
+- zombie.finalizeSpawn(serverlevel, this.level().getCurrentDifficultyAt(zombie.blockPosition()), MobSpawnType.REINFORCEMENT, (SpawnGroupData) null, (CompoundTag) null);
+- serverlevel.addFreshEntityWithPassengers(zombie);
++ if (NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, this.level(), blockposition, entitytypes) && SpawnPlacements.checkSpawnRules(entitytypes, worldserver, EnumMobSpawn.REINFORCEMENT, blockposition, this.level().random)) {
++ entityzombie.setPos((double) i1, (double) j1, (double) k1);
++ if (!this.level().hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(entityzombie) && this.level().noCollision((Entity) entityzombie) && !this.level().containsAnyLiquid(entityzombie.getBoundingBox())) {
++ entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit
++ entityzombie.finalizeSpawn(worldserver, this.level().getCurrentDifficultyAt(entityzombie.blockPosition()), EnumMobSpawn.REINFORCEMENT, (GroupDataEntity) null, (CompoundTag) null);
++ worldserver.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit
+ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).addPermanentModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, AttributeModifier.Operation.ADDITION));
+- zombie.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).addPermanentModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, AttributeModifier.Operation.ADDITION));
++ entityzombie.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).addPermanentModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, AttributeModifier.Operation.ADDITION));
+ break;
+ }
+ }
+@@ -334,7 +342,6 @@
+ }
+
+ @Override
+- @Override
+ public boolean doHurtTarget(Entity entity) {
+ boolean flag = super.doHurtTarget(entity);
+
+@@ -342,7 +349,14 @@
+ float f = this.level().getCurrentDifficultyAt(this.blockPosition()).getEffectiveDifficulty();
+
+ if (this.getMainHandItem().isEmpty() && this.isOnFire() && this.random.nextFloat() < f * 0.3F) {
+- entity.setSecondsOnFire(2 * (int) f);
++ // CraftBukkit start
++ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 2 * (int) f); // PAIL: fixme
++ this.level().getCraftServer().getPluginManager().callEvent(event);
++
++ if (!event.isCancelled()) {
++ entity.setSecondsOnFire(event.getDuration(), false);
++ }
++ // CraftBukkit end
+ }
+ }
+
+@@ -350,19 +364,16 @@
+ }
+
+ @Override
+- @Override
+ protected SoundEvent getAmbientSound() {
+ return SoundEvents.ZOMBIE_AMBIENT;
+ }
+
+ @Override
+- @Override
+- protected SoundEvent getHurtSound(DamageSource damagesource) {
++ protected SoundEvent getHurtSound(DamageSource damageSource) {
+ return SoundEvents.ZOMBIE_HURT;
+ }
+
+ @Override
+- @Override
+ protected SoundEvent getDeathSound() {
+ return SoundEvents.ZOMBIE_DEATH;
+ }
+@@ -372,23 +383,20 @@
+ }
+
+ @Override
+- @Override
+- protected void playStepSound(BlockPos blockpos, BlockState blockstate) {
++ protected void playStepSound(BlockPos pos, IBlockData block) {
+ this.playSound(this.getStepSound(), 0.15F, 1.0F);
+ }
+
+ @Override
+- @Override
+- public MobType getMobType() {
+- return MobType.UNDEAD;
++ public EnumMonsterType getMobType() {
++ return EnumMonsterType.UNDEAD;
+ }
+
+ @Override
+- @Override
+- protected void populateDefaultEquipmentSlots(RandomSource randomsource, DifficultyInstance difficultyinstance) {
+- super.populateDefaultEquipmentSlots(randomsource, difficultyinstance);
+- if (randomsource.nextFloat() < (this.level().getDifficulty() == Difficulty.HARD ? 0.05F : 0.01F)) {
+- int i = randomsource.nextInt(3);
++ protected void populateDefaultEquipmentSlots(RandomSource random, DifficultyInstance difficulty) {
++ super.populateDefaultEquipmentSlots(random, difficulty);
++ if (random.nextFloat() < (this.level().getDifficulty() == Difficulty.HARD ? 0.05F : 0.01F)) {
++ int i = random.nextInt(3);
+
+ if (i == 0) {
+ this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.IRON_SWORD));
+@@ -400,84 +408,88 @@
+ }
+
+ @Override
+- @Override
+- public void addAdditionalSaveData(CompoundTag compoundtag) {
+- super.addAdditionalSaveData(compoundtag);
+- compoundtag.putBoolean("IsBaby", this.isBaby());
+- compoundtag.putBoolean("CanBreakDoors", this.canBreakDoors());
+- compoundtag.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
+- compoundtag.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
++ public void addAdditionalSaveData(CompoundTag compound) {
++ super.addAdditionalSaveData(compound);
++ compound.putBoolean("IsBaby", this.isBaby());
++ compound.putBoolean("CanBreakDoors", this.canBreakDoors());
++ compound.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
++ compound.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
+ }
+
+ @Override
+- @Override
+- public void readAdditionalSaveData(CompoundTag compoundtag) {
+- super.readAdditionalSaveData(compoundtag);
+- this.setBaby(compoundtag.getBoolean("IsBaby"));
+- this.setCanBreakDoors(compoundtag.getBoolean("CanBreakDoors"));
+- this.inWaterTime = compoundtag.getInt("InWaterTime");
+- if (compoundtag.contains("DrownedConversionTime", 99) && compoundtag.getInt("DrownedConversionTime") > -1) {
+- this.startUnderWaterConversion(compoundtag.getInt("DrownedConversionTime"));
++ public void readAdditionalSaveData(CompoundTag compound) {
++ super.readAdditionalSaveData(compound);
++ this.setBaby(compound.getBoolean("IsBaby"));
++ this.setCanBreakDoors(compound.getBoolean("CanBreakDoors"));
++ this.inWaterTime = compound.getInt("InWaterTime");
++ if (compound.contains("DrownedConversionTime", 99) && compound.getInt("DrownedConversionTime") > -1) {
++ this.startUnderWaterConversion(compound.getInt("DrownedConversionTime"));
+ }
+
+ }
+
+ @Override
+- @Override
+- public boolean killedEntity(ServerLevel serverlevel, LivingEntity livingentity) {
+- boolean flag = super.killedEntity(serverlevel, livingentity);
++ public boolean killedEntity(ServerLevel level, LivingEntity entity) {
++ boolean flag = super.killedEntity(level, entity);
+
+- if ((serverlevel.getDifficulty() == Difficulty.NORMAL || serverlevel.getDifficulty() == Difficulty.HARD) && livingentity instanceof Villager) {
+- Villager villager = (Villager) livingentity;
++ if ((level.getDifficulty() == Difficulty.NORMAL || level.getDifficulty() == Difficulty.HARD) && entity instanceof Villager) {
++ Villager entityvillager = (Villager) entity;
+
+- if (serverlevel.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
++ if (level.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
+ return flag;
+ }
++ // CraftBukkit start
++ flag = zombifyVillager(level, entityvillager, this.blockPosition(), this.isSilent(), CreatureSpawnEvent.SpawnReason.INFECTION) == null;
++ }
+
+- ZombieVillager zombievillager = (ZombieVillager) villager.convertTo(EntityType.ZOMBIE_VILLAGER, false);
++ return flag;
++ }
+
+- if (zombievillager != null) {
+- zombievillager.finalizeSpawn(serverlevel, serverlevel.getCurrentDifficultyAt(zombievillager.blockPosition()), MobSpawnType.CONVERSION, new Zombie.ZombieGroupData(false, true), (CompoundTag) null);
+- zombievillager.setVillagerData(villager.getVillagerData());
+- zombievillager.setGossips((Tag) villager.getGossips().store(NbtOps.INSTANCE));
+- zombievillager.setTradeOffers(villager.getOffers().createTag());
+- zombievillager.setVillagerXp(villager.getVillagerXp());
+- if (!this.isSilent()) {
+- serverlevel.levelEvent((Player) null, 1026, this.blockPosition(), 0);
++ public static ZombieVillager zombifyVillager(ServerLevel worldserver, Villager entityvillager, net.minecraft.core.BlockPos blockPosition, boolean silent, CreatureSpawnEvent.SpawnReason spawnReason) {
++ {
++ ZombieVillager entityzombievillager = (ZombieVillager) entityvillager.convertTo(EntityType.ZOMBIE_VILLAGER, false, EntityTransformEvent.TransformReason.INFECTION, spawnReason);
++ // CraftBukkit end
++
++ if (entityzombievillager != null) {
++ entityzombievillager.finalizeSpawn(worldserver, worldserver.getCurrentDifficultyAt(entityzombievillager.blockPosition()), EnumMobSpawn.CONVERSION, new Zombie.ZombieGroupData(false, true), (CompoundTag) null);
++ entityzombievillager.setVillagerData(entityvillager.getVillagerData());
++ entityzombievillager.setGossips((Tag) entityvillager.getGossips().store(NbtOps.INSTANCE));
++ entityzombievillager.setTradeOffers(entityvillager.getOffers().createTag());
++ entityzombievillager.setVillagerXp(entityvillager.getVillagerXp());
++ // CraftBukkit start
++ if (!silent) {
++ worldserver.levelEvent((Player) null, 1026, blockPosition, 0);
+ }
+
+- flag = false;
++ // flag = false;
+ }
+- }
+
+- return flag;
++ return entityzombievillager;
++ }
++ // CraftBukkit end
+ }
+
+ @Override
+- @Override
+- protected float getStandingEyeHeight(Pose pose, EntityDimensions entitydimensions) {
++ protected float getStandingEyeHeight(EntityPose pose, EntityDimensions size) {
+ return this.isBaby() ? 0.93F : 1.74F;
+ }
+
+ @Override
+- @Override
+- public boolean canHoldItem(ItemStack itemstack) {
+- return itemstack.is(Items.EGG) && this.isBaby() && this.isPassenger() ? false : super.canHoldItem(itemstack);
++ public boolean canHoldItem(ItemStack stack) {
++ return stack.is(Items.EGG) && this.isBaby() && this.isPassenger() ? false : super.canHoldItem(stack);
+ }
+
+ @Override
+- @Override
+- public boolean wantsToPickUp(ItemStack itemstack) {
+- return itemstack.is(Items.GLOW_INK_SAC) ? false : super.wantsToPickUp(itemstack);
++ public boolean wantsToPickUp(ItemStack stack) {
++ return stack.is(Items.GLOW_INK_SAC) ? false : super.wantsToPickUp(stack);
+ }
+
+ @Nullable
+ @Override
+- @Override
+- public SpawnGroupData finalizeSpawn(ServerLevelAccessor serverlevelaccessor, DifficultyInstance difficultyinstance, MobSpawnType mobspawntype, @Nullable SpawnGroupData spawngroupdata, @Nullable CompoundTag compoundtag) {
+- RandomSource randomsource = serverlevelaccessor.getRandom();
+- Object object = super.finalizeSpawn(serverlevelaccessor, difficultyinstance, mobspawntype, spawngroupdata, compoundtag);
+- float f = difficultyinstance.getSpecialMultiplier();
++ public GroupDataEntity finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, EnumMobSpawn reason, @Nullable GroupDataEntity spawnData, @Nullable CompoundTag dataTag) {
++ RandomSource randomsource = level.getRandom();
++ Object object = super.finalizeSpawn(level, difficulty, reason, spawnData, dataTag);
++ float f = difficulty.getSpecialMultiplier();
+
+ this.setCanPickUpLoot(randomsource.nextFloat() < 0.55F * f);
+ if (object == null) {
+@@ -485,37 +497,37 @@
+ }
+
+ if (object instanceof Zombie.ZombieGroupData) {
+- Zombie.ZombieGroupData zombie_zombiegroupdata = (Zombie.ZombieGroupData) object;
++ Zombie.ZombieGroupData entityzombie_groupdatazombie = (Zombie.ZombieGroupData) object;
+
+- if (zombie_zombiegroupdata.isBaby) {
++ if (entityzombie_groupdatazombie.isBaby) {
+ this.setBaby(true);
+- if (zombie_zombiegroupdata.canSpawnJockey) {
++ if (entityzombie_groupdatazombie.canSpawnJockey) {
+ if ((double) randomsource.nextFloat() < 0.05D) {
+- List<Chicken> list = serverlevelaccessor.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN);
++ List<Chicken> list = level.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN);
+
+ if (!list.isEmpty()) {
+- Chicken chicken = (Chicken) list.get(0);
++ Chicken entitychicken = (Chicken) list.get(0);
+
+- chicken.setChickenJockey(true);
+- this.startRiding(chicken);
++ entitychicken.setChickenJockey(true);
++ this.startRiding(entitychicken);
+ }
+ } else if ((double) randomsource.nextFloat() < 0.05D) {
+- Chicken chicken1 = (Chicken) EntityType.CHICKEN.create(this.level());
++ Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level());
+
+- if (chicken1 != null) {
+- chicken1.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
+- chicken1.finalizeSpawn(serverlevelaccessor, difficultyinstance, MobSpawnType.JOCKEY, (SpawnGroupData) null, (CompoundTag) null);
+- chicken1.setChickenJockey(true);
+- this.startRiding(chicken1);
+- serverlevelaccessor.addFreshEntity(chicken1);
++ if (entitychicken1 != null) {
++ entitychicken1.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
++ entitychicken1.finalizeSpawn(level, difficulty, EnumMobSpawn.JOCKEY, (GroupDataEntity) null, (CompoundTag) null);
++ entitychicken1.setChickenJockey(true);
++ this.startRiding(entitychicken1);
++ level.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
+ }
+ }
+ }
+ }
+
+ this.setCanBreakDoors(this.supportsBreakDoorGoal() && randomsource.nextFloat() < f * 0.1F);
+- this.populateDefaultEquipmentSlots(randomsource, difficultyinstance);
+- this.populateDefaultEquipmentEnchantments(randomsource, difficultyinstance);
++ this.populateDefaultEquipmentSlots(randomsource, difficulty);
++ this.populateDefaultEquipmentEnchantments(randomsource, difficulty);
+ }
+
+ if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
+@@ -530,23 +542,23 @@
+ }
+
+ this.handleAttributes(f);
+- return (SpawnGroupData) object;
++ return (GroupDataEntity) object;
+ }
+
+- public static boolean getSpawnAsBabyOdds(RandomSource randomsource) {
+- return randomsource.nextFloat() < 0.05F;
++ public static boolean getSpawnAsBabyOdds(RandomSource random) {
++ return random.nextFloat() < 0.05F;
+ }
+
+- protected void handleAttributes(float f) {
++ protected void handleAttributes(float difficulty) {
+ this.randomizeReinforcementsChance();
+ this.getAttribute(Attributes.KNOCKBACK_RESISTANCE).addPermanentModifier(new AttributeModifier("Random spawn bonus", this.random.nextDouble() * 0.05000000074505806D, AttributeModifier.Operation.ADDITION));
+- double d0 = this.random.nextDouble() * 1.5D * (double) f;
++ double d0 = this.random.nextDouble() * 1.5D * (double) difficulty;
+
+ if (d0 > 1.0D) {
+ this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random zombie-spawn bonus", d0, AttributeModifier.Operation.MULTIPLY_TOTAL));
+ }
+
+- if (this.random.nextFloat() < f * 0.05F) {
++ if (this.random.nextFloat() < difficulty * 0.05F) {
+ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).addPermanentModifier(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 0.25D + 0.5D, AttributeModifier.Operation.ADDITION));
+ this.getAttribute(Attributes.MAX_HEALTH).addPermanentModifier(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 3.0D + 1.0D, AttributeModifier.Operation.MULTIPLY_TOTAL));
+ this.setCanBreakDoors(this.supportsBreakDoorGoal());
+@@ -559,31 +571,28 @@
+ }
+
+ @Override
+- @Override
+- protected Vector3f getPassengerAttachmentPoint(Entity entity, EntityDimensions entitydimensions, float f) {
+- return new Vector3f(0.0F, entitydimensions.height + 0.0625F * f, 0.0F);
++ protected Vector3f getPassengerAttachmentPoint(Entity entity, EntityDimensions entitysize, float f) {
++ return new Vector3f(0.0F, entitysize.height + 0.0625F * f, 0.0F);
+ }
+
+ @Override
+- @Override
+ protected float ridingOffset(Entity entity) {
+ return -0.7F;
+ }
+
+ @Override
+- @Override
+- protected void dropCustomDeathLoot(DamageSource damagesource, int i, boolean flag) {
+- super.dropCustomDeathLoot(damagesource, i, flag);
+- Entity entity = damagesource.getEntity();
++ protected void dropCustomDeathLoot(DamageSource source, int looting, boolean recentlyHit) {
++ super.dropCustomDeathLoot(source, looting, recentlyHit);
++ Entity entity = source.getEntity();
+
+ if (entity instanceof Creeper) {
+- Creeper creeper = (Creeper) entity;
++ Creeper entitycreeper = (Creeper) entity;
+
+- if (creeper.canDropMobsSkull()) {
++ if (entitycreeper.canDropMobsSkull()) {
+ ItemStack itemstack = this.getSkull();
+
+ if (!itemstack.isEmpty()) {
+- creeper.increaseDroppedSkulls();
++ entitycreeper.increaseDroppedSkulls();
+ this.spawnAtLocation(itemstack);
+ }
+ }
+@@ -597,37 +606,34 @@
+
+ private class ZombieAttackTurtleEggGoal extends RemoveBlockGoal {
+
+- ZombieAttackTurtleEggGoal(PathfinderMob pathfindermob, double d0, int i) {
+- super(Blocks.TURTLE_EGG, pathfindermob, d0, i);
++ ZombieAttackTurtleEggGoal(PathfinderMob mob, double speedModifier, int i) {
++ super(Blocks.TURTLE_EGG, mob, speedModifier, i);
+ }
+
+ @Override
+- @Override
+- public void playDestroyProgressSound(LevelAccessor levelaccessor, BlockPos blockpos) {
+- levelaccessor.playSound((Player) null, blockpos, SoundEvents.ZOMBIE_DESTROY_EGG, SoundSource.HOSTILE, 0.5F, 0.9F + Zombie.this.random.nextFloat() * 0.2F);
++ public void playDestroyProgressSound(LevelAccessor level, BlockPos pos) {
++ level.playSound((Player) null, pos, SoundEvents.ZOMBIE_DESTROY_EGG, SoundSource.HOSTILE, 0.5F, 0.9F + Zombie.this.random.nextFloat() * 0.2F);
+ }
+
+ @Override
+- @Override
+- public void playBreakSound(Level level, BlockPos blockpos) {
+- level.playSound((Player) null, blockpos, SoundEvents.TURTLE_EGG_BREAK, SoundSource.BLOCKS, 0.7F, 0.9F + level.random.nextFloat() * 0.2F);
++ public void playBreakSound(Level level, BlockPos pos) {
++ level.playSound((Player) null, pos, SoundEvents.TURTLE_EGG_BREAK, SoundSource.BLOCKS, 0.7F, 0.9F + level.random.nextFloat() * 0.2F);
+ }
+
+ @Override
+- @Override
+ public double acceptedDistance() {
+ return 1.14D;
+ }
+ }
+
+- public static class ZombieGroupData implements SpawnGroupData {
++ public static class ZombieGroupData implements GroupDataEntity {
+
+ public final boolean isBaby;
+ public final boolean canSpawnJockey;
+
+- public ZombieGroupData(boolean flag, boolean flag1) {
+- this.isBaby = flag;
+- this.canSpawnJockey = flag1;
++ public ZombieGroupData(boolean isBaby, boolean canSpawnJockey) {
++ this.isBaby = isBaby;
++ this.canSpawnJockey = canSpawnJockey;
+ }
+ }
+ }