diff options
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/entity/animal/Bee.java.patch')
-rw-r--r-- | patch-remap/mache-vineflower/net/minecraft/world/entity/animal/Bee.java.patch | 1484 |
1 files changed, 1484 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/entity/animal/Bee.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/entity/animal/Bee.java.patch new file mode 100644 index 0000000000..aeb2d13642 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/entity/animal/Bee.java.patch @@ -0,0 +1,1484 @@ +--- a/net/minecraft/world/entity/animal/Bee.java ++++ b/net/minecraft/world/entity/animal/Bee.java +@@ -3,7 +3,9 @@ + import com.google.common.collect.Lists; + import java.util.Comparator; + import java.util.EnumSet; ++import java.util.Iterator; + import java.util.List; ++import java.util.Objects; + import java.util.Optional; + import java.util.UUID; + import java.util.function.Predicate; +@@ -11,7 +13,6 @@ + import java.util.stream.Stream; + import javax.annotation.Nullable; + import net.minecraft.core.BlockPos; +-import net.minecraft.core.Holder; + import net.minecraft.core.particles.ParticleOptions; + import net.minecraft.core.particles.ParticleTypes; + import net.minecraft.nbt.CompoundTag; +@@ -38,13 +39,13 @@ + import net.minecraft.world.entity.AgeableMob; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityDimensions; ++import net.minecraft.world.entity.EntityPose; + import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.EnumMonsterType; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.Mob; +-import net.minecraft.world.entity.MobType; + import net.minecraft.world.entity.NeutralMob; + import net.minecraft.world.entity.PathfinderMob; +-import net.minecraft.world.entity.Pose; + import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + import net.minecraft.world.entity.ai.attributes.Attributes; + import net.minecraft.world.entity.ai.control.FlyingMoveControl; +@@ -81,15 +82,21 @@ + import net.minecraft.world.level.block.entity.BeehiveBlockEntity; + import net.minecraft.world.level.block.entity.BlockEntity; + import net.minecraft.world.level.block.entity.BlockEntityType; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; ++import net.minecraft.world.level.block.state.properties.BlockPropertyDoubleBlockHalf; + import net.minecraft.world.level.block.state.properties.BlockStateProperties; +-import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; + import net.minecraft.world.level.material.Fluid; + import net.minecraft.world.level.pathfinder.BlockPathTypes; + import net.minecraft.world.level.pathfinder.Path; + import net.minecraft.world.phys.Vec3; ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityPotionEffectEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end + +-public class Bee extends Animal implements NeutralMob, FlyingAnimal { ++public class Bee extends Animal implements NeutralMob, EntityBird { ++ + public static final float FLAP_DEGREES_PER_TICK = 120.32113F; + public static final int TICKS_PER_FLAP = Mth.ceil(1.4959966F); + private static final EntityDataAccessor<Byte> DATA_FLAGS_ID = SynchedEntityData.defineId(Bee.class, EntityDataSerializers.BYTE); +@@ -122,16 +129,16 @@ + private float rollAmountO; + private int timeSinceSting; + int ticksWithoutNectarSinceExitingHive; +- private int stayOutOfHiveCountdown; ++ public int stayOutOfHiveCountdown; + private int numCropsGrownSincePollination; + private static final int COOLDOWN_BEFORE_LOCATING_NEW_HIVE = 200; + int remainingCooldownBeforeLocatingNewHive; + private static final int COOLDOWN_BEFORE_LOCATING_NEW_FLOWER = 200; +- int remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); ++ int remainingCooldownBeforeLocatingNewFlower; + @Nullable + BlockPos savedFlowerPos; + @Nullable +- BlockPos hivePos; ++ public BlockPos hivePos; + Bee.BeePollinateGoal beePollinateGoal; + Bee.BeeGoToHiveGoal goToHiveGoal; + private Bee.BeeGoToKnownFlowerGoal goToKnownFlowerGoal; +@@ -139,6 +146,7 @@ + + public Bee(EntityType<? extends Bee> entityType, Level level) { + super(entityType, level); ++ this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); + this.moveControl = new FlyingMoveControl(this, 20, true); + this.lookControl = new Bee.BeeLookControl(this); + this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); +@@ -151,8 +159,8 @@ + @Override + protected void defineSynchedData() { + super.defineSynchedData(); +- this.entityData.define(DATA_FLAGS_ID, (byte)0); +- this.entityData.define(DATA_REMAINING_ANGER_TIME, 0); ++ this.entityData.define(Bee.DATA_FLAGS_ID, (byte) 0); ++ this.entityData.define(Bee.DATA_REMAINING_ANGER_TIME, 0); + } + + @Override +@@ -162,13 +170,13 @@ + + @Override + protected void registerGoals() { +- this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.4F, true)); ++ this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.399999976158142D, true)); + this.goalSelector.addGoal(1, new Bee.BeeEnterHiveGoal()); +- this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); +- this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, Ingredient.of(ItemTags.FLOWERS), false)); ++ this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); ++ this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(ItemTags.FLOWERS), false)); + this.beePollinateGoal = new Bee.BeePollinateGoal(); + this.goalSelector.addGoal(4, this.beePollinateGoal); +- this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.25)); ++ this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.25D)); + this.goalSelector.addGoal(5, new Bee.BeeLocateHiveGoal()); + this.goToHiveGoal = new Bee.BeeGoToHiveGoal(); + this.goalSelector.addGoal(5, this.goToHiveGoal); +@@ -177,28 +185,35 @@ + this.goalSelector.addGoal(7, new Bee.BeeGrowCropGoal()); + this.goalSelector.addGoal(8, new Bee.BeeWanderGoal()); + this.goalSelector.addGoal(9, new FloatGoal(this)); +- this.targetSelector.addGoal(1, new Bee.BeeHurtByOtherGoal(this).setAlertOthers(new Class[0])); ++ this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(new Class[0])); + this.targetSelector.addGoal(2, new Bee.BeeBecomeAngryTargetGoal(this)); + this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); + } + + @Override + public void addAdditionalSaveData(CompoundTag compound) { +- super.addAdditionalSaveData(compound); +- if (this.hasHive()) { +- compound.put("HivePos", NbtUtils.writeBlockPos(this.getHivePos())); ++ // CraftBukkit start - selectively save data ++ addAdditionalSaveData(compound, true); ++ } ++ ++ @Override ++ public void addAdditionalSaveData(CompoundTag nbttagcompound, boolean includeAll) { ++ // CraftBukkit end ++ super.addAdditionalSaveData(nbttagcompound); ++ if (includeAll && this.hasHive()) { // CraftBukkit - selectively save hive ++ nbttagcompound.put("HivePos", NbtUtils.writeBlockPos(this.getHivePos())); + } + +- if (this.hasSavedFlowerPos()) { +- compound.put("FlowerPos", NbtUtils.writeBlockPos(this.getSavedFlowerPos())); ++ if (includeAll && this.hasSavedFlowerPos()) { // CraftBukkit - selectively save flower ++ nbttagcompound.put("FlowerPos", NbtUtils.writeBlockPos(this.getSavedFlowerPos())); + } + +- compound.putBoolean("HasNectar", this.hasNectar()); +- compound.putBoolean("HasStung", this.hasStung()); +- compound.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); +- compound.putInt("CannotEnterHiveTicks", this.stayOutOfHiveCountdown); +- compound.putInt("CropsGrownSincePollination", this.numCropsGrownSincePollination); +- this.addPersistentAngerSaveData(compound); ++ nbttagcompound.putBoolean("HasNectar", this.hasNectar()); ++ nbttagcompound.putBoolean("HasStung", this.hasStung()); ++ nbttagcompound.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); ++ nbttagcompound.putInt("CannotEnterHiveTicks", this.stayOutOfHiveCountdown); ++ nbttagcompound.putInt("CropsGrownSincePollination", this.numCropsGrownSincePollination); ++ this.addPersistentAngerSaveData(nbttagcompound); + } + + @Override +@@ -224,20 +239,22 @@ + + @Override + public boolean doHurtTarget(Entity entity) { +- boolean flag = entity.hurt(this.damageSources().sting(this), (float)((int)this.getAttributeValue(Attributes.ATTACK_DAMAGE))); ++ boolean flag = entity.hurt(this.damageSources().sting(this), (float) ((int) this.getAttributeValue(Attributes.ATTACK_DAMAGE))); ++ + if (flag) { + this.doEnchantDamageEffects(this, entity); + if (entity instanceof LivingEntity) { +- ((LivingEntity)entity).setStingerCount(((LivingEntity)entity).getStingerCount() + 1); +- int i = 0; ++ ((LivingEntity) entity).setStingerCount(((LivingEntity) entity).getStingerCount() + 1); ++ byte b0 = 0; ++ + if (this.level().getDifficulty() == Difficulty.NORMAL) { +- i = 10; ++ b0 = 10; + } else if (this.level().getDifficulty() == Difficulty.HARD) { +- i = 18; ++ b0 = 18; + } + +- if (i > 0) { +- ((LivingEntity)entity).addEffect(new MobEffectInstance(MobEffects.POISON, i * 20, 0), this); ++ if (b0 > 0) { ++ ((LivingEntity) entity).addEffect(new MobEffectInstance(MobEffects.POISON, b0 * 20, 0), this, EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + } + } + +@@ -253,45 +270,44 @@ + public void tick() { + super.tick(); + if (this.hasNectar() && this.getCropsGrownSincePollination() < 10 && this.random.nextFloat() < 0.05F) { +- for (int i = 0; i < this.random.nextInt(2) + 1; i++) { +- this.spawnFluidParticle( +- this.level(), this.getX() - 0.3F, this.getX() + 0.3F, this.getZ() - 0.3F, this.getZ() + 0.3F, this.getY(0.5), ParticleTypes.FALLING_NECTAR +- ); ++ for (int i = 0; i < this.random.nextInt(2) + 1; ++i) { ++ this.spawnFluidParticle(this.level(), this.getX() - 0.30000001192092896D, this.getX() + 0.30000001192092896D, this.getZ() - 0.30000001192092896D, this.getZ() + 0.30000001192092896D, this.getY(0.5D), ParticleTypes.FALLING_NECTAR); + } + } + + this.updateRollAmount(); + } + +- private void spawnFluidParticle(Level level, double startX, double endX, double startZ, double endZ, double posY, ParticleOptions particleOption) { +- level.addParticle( +- particleOption, Mth.lerp(level.random.nextDouble(), startX, endX), posY, Mth.lerp(level.random.nextDouble(), startZ, endZ), 0.0, 0.0, 0.0 +- ); ++ private void spawnFluidParticle(Level level, double startX, double d1, double endX, double d3, double startZ, ParticleOptions particleparam) { ++ level.addParticle(particleparam, Mth.lerp(level.random.nextDouble(), startX, d1), startZ, Mth.lerp(level.random.nextDouble(), endX, d3), 0.0D, 0.0D, 0.0D); + } + + void pathfindRandomlyTowards(BlockPos pos) { +- Vec3 vec3 = Vec3.atBottomCenterOf(pos); +- int i = 0; +- BlockPos blockPos = this.blockPosition(); +- int i1 = (int)vec3.y - blockPos.getY(); +- if (i1 > 2) { +- i = 4; +- } else if (i1 < -2) { +- i = -4; ++ Vec3 vec3d = Vec3.atBottomCenterOf(pos); ++ byte b0 = 0; ++ BlockPos blockposition1 = this.blockPosition(); ++ int i = (int) vec3d.y - blockposition1.getY(); ++ ++ if (i > 2) { ++ b0 = 4; ++ } else if (i < -2) { ++ b0 = -4; + } + +- int i2 = 6; +- int i3 = 8; +- int i4 = blockPos.distManhattan(pos); +- if (i4 < 15) { +- i2 = i4 / 2; +- i3 = i4 / 2; ++ int j = 6; ++ int k = 8; ++ int l = blockposition1.distManhattan(pos); ++ ++ if (l < 15) { ++ j = l / 2; ++ k = l / 2; + } + +- Vec3 posTowards = AirRandomPos.getPosTowards(this, i2, i3, i, vec3, (float) (Math.PI / 10)); +- if (posTowards != null) { ++ Vec3 vec3d1 = AirRandomPos.getPosTowards(this, j, k, b0, vec3d, 0.3141592741012573D); ++ ++ if (vec3d1 != null) { + this.navigation.setMaxVisitedNodesMultiplier(0.5F); +- this.navigation.moveTo(posTowards.x, posTowards.y, posTowards.z, 1.0); ++ this.navigation.moveTo(vec3d1.x, vec3d1.y, vec3d1.z, 1.0D); + } + } + +@@ -325,6 +341,7 @@ + boolean wantsToEnterHive() { + if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { + boolean flag = this.isTiredOfLookingForNectar() || this.level().isRaining() || this.level().isNight() || this.hasNectar(); ++ + return flag && !this.isHiveNearFire(); + } else { + return false; +@@ -346,13 +363,15 @@ + } else { + this.rollAmount = Math.max(0.0F, this.rollAmount - 0.24F); + } ++ + } + + @Override + protected void customServerAiStep() { +- boolean hasStung = this.hasStung(); ++ boolean flag = this.hasStung(); ++ + if (this.isInWaterOrBubble()) { +- this.underWaterTicks++; ++ ++this.underWaterTicks; + } else { + this.underWaterTicks = 0; + } +@@ -361,20 +380,21 @@ + this.hurt(this.damageSources().drown(), 1.0F); + } + +- if (hasStung) { +- this.timeSinceSting++; ++ if (flag) { ++ ++this.timeSinceSting; + if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { + this.hurt(this.damageSources().generic(), this.getHealth()); + } + } + + if (!this.hasNectar()) { +- this.ticksWithoutNectarSinceExitingHive++; ++ ++this.ticksWithoutNectarSinceExitingHive; + } + + if (!this.level().isClientSide) { +- this.updatePersistentAnger((ServerLevel)this.level(), false); ++ this.updatePersistentAnger((ServerLevel) this.level(), false); + } ++ + } + + public void resetTicksWithoutNectarSinceExitingHive() { +@@ -385,19 +405,20 @@ + if (this.hivePos == null) { + return false; + } else { +- BlockEntity blockEntity = this.level().getBlockEntity(this.hivePos); +- return blockEntity instanceof BeehiveBlockEntity && ((BeehiveBlockEntity)blockEntity).isFireNearby(); ++ BlockEntity tileentity = this.level().getBlockEntity(this.hivePos); ++ ++ return tileentity instanceof BeehiveBlockEntity && ((BeehiveBlockEntity) tileentity).isFireNearby(); + } + } + + @Override + public int getRemainingPersistentAngerTime() { +- return this.entityData.get(DATA_REMAINING_ANGER_TIME); ++ return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME); + } + + @Override + public void setRemainingPersistentAngerTime(int time) { +- this.entityData.set(DATA_REMAINING_ANGER_TIME, time); ++ this.entityData.set(Bee.DATA_REMAINING_ANGER_TIME, time); + } + + @Nullable +@@ -413,12 +434,13 @@ + + @Override + public void startPersistentAngerTimer() { +- this.setRemainingPersistentAngerTime(PERSISTENT_ANGER_TIME.sample(this.random)); ++ this.setRemainingPersistentAngerTime(Bee.PERSISTENT_ANGER_TIME.sample(this.random)); + } + + private boolean doesHiveHaveSpace(BlockPos hivePos) { +- BlockEntity blockEntity = this.level().getBlockEntity(hivePos); +- return blockEntity instanceof BeehiveBlockEntity && !((BeehiveBlockEntity)blockEntity).isFull(); ++ BlockEntity tileentity = this.level().getBlockEntity(hivePos); ++ ++ return tileentity instanceof BeehiveBlockEntity ? !((BeehiveBlockEntity) tileentity).isFull() : false; + } + + @VisibleForDebug +@@ -452,7 +474,7 @@ + } + + void incrementNumCropsGrownSincePollination() { +- this.numCropsGrownSincePollination++; ++ ++this.numCropsGrownSincePollination; + } + + @Override +@@ -460,23 +482,25 @@ + super.aiStep(); + if (!this.level().isClientSide) { + if (this.stayOutOfHiveCountdown > 0) { +- this.stayOutOfHiveCountdown--; ++ --this.stayOutOfHiveCountdown; + } + + if (this.remainingCooldownBeforeLocatingNewHive > 0) { +- this.remainingCooldownBeforeLocatingNewHive--; ++ --this.remainingCooldownBeforeLocatingNewHive; + } + + if (this.remainingCooldownBeforeLocatingNewFlower > 0) { +- this.remainingCooldownBeforeLocatingNewFlower--; ++ --this.remainingCooldownBeforeLocatingNewFlower; + } + +- boolean flag = this.isAngry() && !this.hasStung() && this.getTarget() != null && this.getTarget().distanceToSqr(this) < 4.0; ++ boolean flag = this.isAngry() && !this.hasStung() && this.getTarget() != null && this.getTarget().distanceToSqr((Entity) this) < 4.0D; ++ + this.setRolling(flag); + if (this.tickCount % 20 == 0 && !this.isHiveValid()) { + this.hivePos = null; + } + } ++ + } + + boolean isHiveValid() { +@@ -485,8 +509,9 @@ + } else if (this.isTooFarAway(this.hivePos)) { + return false; + } else { +- BlockEntity blockEntity = this.level().getBlockEntity(this.hivePos); +- return blockEntity != null && blockEntity.getType() == BlockEntityType.BEEHIVE; ++ BlockEntity tileentity = this.level().getBlockEntity(this.hivePos); ++ ++ return tileentity != null && tileentity.getType() == BlockEntityType.BEEHIVE; + } + } + +@@ -494,7 +519,7 @@ + return this.getFlag(8); + } + +- void setHasNectar(boolean hasNectar) { ++ public void setHasNectar(boolean hasNectar) { + if (hasNectar) { + this.resetTicksWithoutNectarSinceExitingHive(); + } +@@ -506,7 +531,7 @@ + return this.getFlag(4); + } + +- private void setHasStung(boolean hasStung) { ++ public void setHasStung(boolean hasStung) { + this.setFlag(4, hasStung); + } + +@@ -524,28 +549,24 @@ + + private void setFlag(int flagId, boolean value) { + if (value) { +- this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) | flagId)); ++ this.entityData.set(Bee.DATA_FLAGS_ID, (byte) ((Byte) this.entityData.get(Bee.DATA_FLAGS_ID) | flagId)); + } else { +- this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) & ~flagId)); ++ this.entityData.set(Bee.DATA_FLAGS_ID, (byte) ((Byte) this.entityData.get(Bee.DATA_FLAGS_ID) & ~flagId)); + } ++ + } + + private boolean getFlag(int flagId) { +- return (this.entityData.get(DATA_FLAGS_ID) & flagId) != 0; ++ return ((Byte) this.entityData.get(Bee.DATA_FLAGS_ID) & flagId) != 0; + } + + public static AttributeSupplier.Builder createAttributes() { +- return Mob.createMobAttributes() +- .add(Attributes.MAX_HEALTH, 10.0) +- .add(Attributes.FLYING_SPEED, 0.6F) +- .add(Attributes.MOVEMENT_SPEED, 0.3F) +- .add(Attributes.ATTACK_DAMAGE, 2.0) +- .add(Attributes.FOLLOW_RANGE, 48.0); ++ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FLYING_SPEED, 0.6000000238418579D).add(Attributes.MOVEMENT_SPEED, 0.30000001192092896D).add(Attributes.ATTACK_DAMAGE, 2.0D).add(Attributes.FOLLOW_RANGE, 48.0D); + } + + @Override + protected PathNavigation createNavigation(Level level) { +- FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, level) { ++ FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, level) { + @Override + public boolean isStableDestination(BlockPos pos) { + return !this.level.getBlockState(pos.below()).isAir(); +@@ -558,10 +579,11 @@ + } + } + }; +- flyingPathNavigation.setCanOpenDoors(false); +- flyingPathNavigation.setCanFloat(false); +- flyingPathNavigation.setCanPassDoors(true); +- return flyingPathNavigation; ++ ++ navigationflying.setCanOpenDoors(false); ++ navigationflying.setCanFloat(false); ++ navigationflying.setCanPassDoors(true); ++ return navigationflying; + } + + @Override +@@ -574,8 +596,7 @@ + } + + @Override +- protected void playStepSound(BlockPos pos, BlockState block) { +- } ++ protected void playStepSound(BlockPos pos, IBlockData block) {} + + @Override + protected SoundEvent getAmbientSound() { +@@ -600,21 +621,20 @@ + @Nullable + @Override + public Bee getBreedOffspring(ServerLevel level, AgeableMob otherParent) { +- return EntityType.BEE.create(level); ++ return (Bee) EntityType.BEE.create(level); + } + + @Override +- protected float getStandingEyeHeight(Pose pose, EntityDimensions size) { ++ protected float getStandingEyeHeight(EntityPose pose, EntityDimensions size) { + return this.isBaby() ? size.height * 0.5F : size.height * 0.5F; + } + + @Override +- protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) { +- } ++ protected void checkFallDamage(double y, boolean flag, IBlockData onGround, BlockPos state) {} + + @Override + public boolean isFlapping() { +- return this.isFlying() && this.tickCount % TICKS_PER_FLAP == 0; ++ return this.isFlying() && this.tickCount % Bee.TICKS_PER_FLAP == 0; + } + + @Override +@@ -632,104 +652,278 @@ + if (this.isInvulnerableTo(source)) { + return false; + } else { +- if (!this.level().isClientSide) { ++ // CraftBukkit start - Only stop pollinating if entity was damaged ++ boolean result = super.hurt(source, amount); ++ if (result && !this.level().isClientSide) { ++ // CraftBukkit end + this.beePollinateGoal.stopPollinating(); + } + +- return super.hurt(source, amount); ++ return result; // CraftBukkit + } + } + + @Override +- public MobType getMobType() { +- return MobType.ARTHROPOD; ++ public EnumMonsterType getMobType() { ++ return EnumMonsterType.ARTHROPOD; + } + + @Override + protected void jumpInLiquid(TagKey<Fluid> fluidTag) { +- this.setDeltaMovement(this.getDeltaMovement().add(0.0, 0.01, 0.0)); ++ this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.01D, 0.0D)); + } + + @Override + public Vec3 getLeashOffset() { +- return new Vec3(0.0, (double)(0.5F * this.getEyeHeight()), (double)(this.getBbWidth() * 0.2F)); ++ return new Vec3(0.0D, (double) (0.5F * this.getEyeHeight()), (double) (this.getBbWidth() * 0.2F)); + } + + boolean closerThan(BlockPos pos, int distance) { +- return pos.closerThan(this.blockPosition(), (double)distance); ++ return pos.closerThan(this.blockPosition(), (double) distance); + } + +- abstract class BaseBeeGoal extends Goal { +- public abstract boolean canBeeUse(); ++ private class BeePollinateGoal extends Bee.BaseBeeGoal { + +- public abstract boolean canBeeContinueToUse(); ++ private static final int MIN_POLLINATION_TICKS = 400; ++ private static final int MIN_FIND_FLOWER_RETRY_COOLDOWN = 20; ++ private static final int MAX_FIND_FLOWER_RETRY_COOLDOWN = 60; ++ private final Predicate<IBlockData> VALID_POLLINATION_BLOCKS = (iblockdata) -> { ++ return iblockdata.hasProperty(BlockStateProperties.WATERLOGGED) && (Boolean) iblockdata.getValue(BlockStateProperties.WATERLOGGED) ? false : (iblockdata.is(BlockTags.FLOWERS) ? (iblockdata.is(Blocks.SUNFLOWER) ? iblockdata.getValue(DoublePlantBlock.HALF) == BlockPropertyDoubleBlockHalf.UPPER : true) : false); ++ }; ++ private static final double ARRIVAL_THRESHOLD = 0.1D; ++ private static final int POSITION_CHANGE_CHANCE = 25; ++ private static final float SPEED_MODIFIER = 0.35F; ++ private static final float HOVER_HEIGHT_WITHIN_FLOWER = 0.6F; ++ private static final float HOVER_POS_OFFSET = 0.33333334F; ++ private int successfulPollinatingTicks; ++ private int lastSoundPlayedTick; ++ private boolean pollinating; ++ @Nullable ++ private Vec3 hoverPos; ++ private int pollinatingTicks; ++ private static final int MAX_POLLINATING_TICKS = 600; + ++ BeePollinateGoal() { ++ super(); ++ this.setFlags(EnumSet.of(Goal.Type.MOVE)); ++ } ++ + @Override +- public boolean canUse() { +- return this.canBeeUse() && !Bee.this.isAngry(); ++ public boolean canBeeUse() { ++ if (Bee.this.remainingCooldownBeforeLocatingNewFlower > 0) { ++ return false; ++ } else if (Bee.this.hasNectar()) { ++ return false; ++ } else if (Bee.this.level().isRaining()) { ++ return false; ++ } else { ++ Optional<BlockPos> optional = this.findNearbyFlower(); ++ ++ if (optional.isPresent()) { ++ Bee.this.savedFlowerPos = (BlockPos) optional.get(); ++ Bee.this.navigation.moveTo((double) Bee.this.savedFlowerPos.getX() + 0.5D, (double) Bee.this.savedFlowerPos.getY() + 0.5D, (double) Bee.this.savedFlowerPos.getZ() + 0.5D, 1.2000000476837158D); ++ return true; ++ } else { ++ Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); ++ return false; ++ } ++ } + } + + @Override +- public boolean canContinueToUse() { +- return this.canBeeContinueToUse() && !Bee.this.isAngry(); ++ public boolean canBeeContinueToUse() { ++ if (!this.pollinating) { ++ return false; ++ } else if (!Bee.this.hasSavedFlowerPos()) { ++ return false; ++ } else if (Bee.this.level().isRaining()) { ++ return false; ++ } else if (this.hasPollinatedLongEnough()) { ++ return Bee.this.random.nextFloat() < 0.2F; ++ } else if (Bee.this.tickCount % 20 == 0 && !Bee.this.isFlowerValid(Bee.this.savedFlowerPos)) { ++ Bee.this.savedFlowerPos = null; ++ return false; ++ } else { ++ return true; ++ } + } ++ ++ private boolean hasPollinatedLongEnough() { ++ return this.successfulPollinatingTicks > 400; ++ } ++ ++ boolean isPollinating() { ++ return this.pollinating; ++ } ++ ++ void stopPollinating() { ++ this.pollinating = false; ++ } ++ ++ @Override ++ public void start() { ++ this.successfulPollinatingTicks = 0; ++ this.pollinatingTicks = 0; ++ this.lastSoundPlayedTick = 0; ++ this.pollinating = true; ++ Bee.this.resetTicksWithoutNectarSinceExitingHive(); ++ } ++ ++ @Override ++ public void stop() { ++ if (this.hasPollinatedLongEnough()) { ++ Bee.this.setHasNectar(true); ++ } ++ ++ this.pollinating = false; ++ Bee.this.navigation.stop(); ++ Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; ++ } ++ ++ @Override ++ public boolean requiresUpdateEveryTick() { ++ return true; ++ } ++ ++ @Override ++ public void tick() { ++ ++this.pollinatingTicks; ++ if (this.pollinatingTicks > 600) { ++ Bee.this.savedFlowerPos = null; ++ } else { ++ Vec3 vec3d = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0D, 0.6000000238418579D, 0.0D); ++ ++ if (vec3d.distanceTo(Bee.this.position()) > 1.0D) { ++ this.hoverPos = vec3d; ++ this.setWantedPos(); ++ } else { ++ if (this.hoverPos == null) { ++ this.hoverPos = vec3d; ++ } ++ ++ boolean flag = Bee.this.position().distanceTo(this.hoverPos) <= 0.1D; ++ boolean flag1 = true; ++ ++ if (!flag && this.pollinatingTicks > 600) { ++ Bee.this.savedFlowerPos = null; ++ } else { ++ if (flag) { ++ boolean flag2 = Bee.this.random.nextInt(25) == 0; ++ ++ if (flag2) { ++ this.hoverPos = new Vec3(vec3d.x() + (double) this.getOffset(), vec3d.y(), vec3d.z() + (double) this.getOffset()); ++ Bee.this.navigation.stop(); ++ } else { ++ flag1 = false; ++ } ++ ++ Bee.this.getLookControl().setLookAt(vec3d.x(), vec3d.y(), vec3d.z()); ++ } ++ ++ if (flag1) { ++ this.setWantedPos(); ++ } ++ ++ ++this.successfulPollinatingTicks; ++ if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { ++ this.lastSoundPlayedTick = this.successfulPollinatingTicks; ++ Bee.this.playSound(SoundEvents.BEE_POLLINATE, 1.0F, 1.0F); ++ } ++ ++ } ++ } ++ } ++ } ++ ++ private void setWantedPos() { ++ Bee.this.getMoveControl().setWantedPosition(this.hoverPos.x(), this.hoverPos.y(), this.hoverPos.z(), 0.3499999940395355D); ++ } ++ ++ private float getOffset() { ++ return (Bee.this.random.nextFloat() * 2.0F - 1.0F) * 0.33333334F; ++ } ++ ++ private Optional<BlockPos> findNearbyFlower() { ++ return this.findNearestBlock(this.VALID_POLLINATION_BLOCKS, 5.0D); ++ } ++ ++ private Optional<BlockPos> findNearestBlock(Predicate<IBlockData> predicate, double distance) { ++ BlockPos blockposition = Bee.this.blockPosition(); ++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); ++ ++ for (int i = 0; (double) i <= distance; i = i > 0 ? -i : 1 - i) { ++ for (int j = 0; (double) j < distance; ++j) { ++ for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { ++ for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { ++ blockposition_mutableblockposition.setWithOffset(blockposition, k, i - 1, l); ++ if (blockposition.closerThan(blockposition_mutableblockposition, distance) && predicate.test(Bee.this.level().getBlockState(blockposition_mutableblockposition))) { ++ return Optional.of(blockposition_mutableblockposition); ++ } ++ } ++ } ++ } ++ } ++ ++ return Optional.empty(); ++ } + } + +- class BeeAttackGoal extends MeleeAttackGoal { +- BeeAttackGoal(PathfinderMob mob, double speedModifier, boolean followingTargetEvenIfNotSeen) { +- super(mob, speedModifier, followingTargetEvenIfNotSeen); ++ private class BeeLookControl extends LookControl { ++ ++ BeeLookControl(Mob mob) { ++ super(mob); + } + + @Override +- public boolean canUse() { +- return super.canUse() && Bee.this.isAngry() && !Bee.this.hasStung(); ++ public void tick() { ++ if (!Bee.this.isAngry()) { ++ super.tick(); ++ } + } + + @Override +- public boolean canContinueToUse() { +- return super.canContinueToUse() && Bee.this.isAngry() && !Bee.this.hasStung(); ++ protected boolean resetXRotOnTick() { ++ return !Bee.this.beePollinateGoal.isPollinating(); + } + } + +- static class BeeBecomeAngryTargetGoal extends NearestAttackableTargetGoal<Player> { +- BeeBecomeAngryTargetGoal(Bee mob) { +- super(mob, Player.class, 10, true, false, mob::isAngryAt); ++ private class BeeAttackGoal extends MeleeAttackGoal { ++ ++ BeeAttackGoal(PathfinderMob mob, double speedModifier, boolean flag) { ++ super(mob, speedModifier, flag); + } + + @Override + public boolean canUse() { +- return this.beeCanTarget() && super.canUse(); ++ return super.canUse() && Bee.this.isAngry() && !Bee.this.hasStung(); + } + + @Override + public boolean canContinueToUse() { +- boolean flag = this.beeCanTarget(); +- if (flag && this.mob.getTarget() != null) { +- return super.canContinueToUse(); +- } else { +- this.targetMob = null; +- return false; +- } ++ return super.canContinueToUse() && Bee.this.isAngry() && !Bee.this.hasStung(); + } ++ } + +- private boolean beeCanTarget() { +- Bee bee = (Bee)this.mob; +- return bee.isAngry() && !bee.hasStung(); ++ private class BeeEnterHiveGoal extends Bee.BaseBeeGoal { ++ ++ BeeEnterHiveGoal() { ++ super(); + } +- } + +- class BeeEnterHiveGoal extends Bee.BaseBeeGoal { + @Override + public boolean canBeeUse() { +- if (Bee.this.hasHive() +- && Bee.this.wantsToEnterHive() +- && Bee.this.hivePos.closerToCenterThan(Bee.this.position(), 2.0) +- && Bee.this.level().getBlockEntity(Bee.this.hivePos) instanceof BeehiveBlockEntity beehiveBlockEntity) { +- if (!beehiveBlockEntity.isFull()) { +- return true; +- } ++ if (Bee.this.hasHive() && Bee.this.wantsToEnterHive() && Bee.this.hivePos.closerToCenterThan(Bee.this.position(), 2.0D)) { ++ BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); + +- Bee.this.hivePos = null; ++ if (tileentity instanceof BeehiveBlockEntity) { ++ BeehiveBlockEntity tileentitybeehive = (BeehiveBlockEntity) tileentity; ++ ++ if (!tileentitybeehive.isFull()) { ++ return true; ++ } ++ ++ Bee.this.hivePos = null; ++ } + } + + return false; +@@ -742,34 +936,92 @@ + + @Override + public void start() { +- if (Bee.this.level().getBlockEntity(Bee.this.hivePos) instanceof BeehiveBlockEntity beehiveBlockEntity) { +- beehiveBlockEntity.addOccupant(Bee.this, Bee.this.hasNectar()); ++ BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); ++ ++ if (tileentity instanceof BeehiveBlockEntity) { ++ BeehiveBlockEntity tileentitybeehive = (BeehiveBlockEntity) tileentity; ++ ++ tileentitybeehive.addOccupant(Bee.this, Bee.this.hasNectar()); + } ++ + } + } + ++ private class BeeLocateHiveGoal extends Bee.BaseBeeGoal { ++ ++ BeeLocateHiveGoal() { ++ super(); ++ } ++ ++ @Override ++ public boolean canBeeUse() { ++ return Bee.this.remainingCooldownBeforeLocatingNewHive == 0 && !Bee.this.hasHive() && Bee.this.wantsToEnterHive(); ++ } ++ ++ @Override ++ public boolean canBeeContinueToUse() { ++ return false; ++ } ++ ++ @Override ++ public void start() { ++ Bee.this.remainingCooldownBeforeLocatingNewHive = 200; ++ List<BlockPos> list = this.findNearbyHivesWithSpace(); ++ ++ if (!list.isEmpty()) { ++ Iterator iterator = list.iterator(); ++ ++ BlockPos blockposition; ++ ++ do { ++ if (!iterator.hasNext()) { ++ Bee.this.goToHiveGoal.clearBlacklist(); ++ Bee.this.hivePos = (BlockPos) list.get(0); ++ return; ++ } ++ ++ blockposition = (BlockPos) iterator.next(); ++ } while (Bee.this.goToHiveGoal.isTargetBlacklisted(blockposition)); ++ ++ Bee.this.hivePos = blockposition; ++ } ++ } ++ ++ private List<BlockPos> findNearbyHivesWithSpace() { ++ BlockPos blockposition = Bee.this.blockPosition(); ++ PoiManager villageplace = ((ServerLevel) Bee.this.level()).getPoiManager(); ++ Stream<PoiRecord> stream = villageplace.getInRange((holder) -> { ++ return holder.is(PoiTypeTags.BEE_HOME); ++ }, blockposition, 20, PoiManager.Occupancy.ANY); ++ ++ return (List) stream.map(PoiRecord::getPos).filter(Bee.this::doesHiveHaveSpace).sorted(Comparator.comparingDouble((blockposition1) -> { ++ return blockposition1.distSqr(blockposition); ++ })).collect(Collectors.toList()); ++ } ++ } ++ + @VisibleForDebug + public class BeeGoToHiveGoal extends Bee.BaseBeeGoal { ++ + public static final int MAX_TRAVELLING_TICKS = 600; +- int travellingTicks = Bee.this.level().random.nextInt(10); ++ int travellingTicks; + private static final int MAX_BLACKLISTED_TARGETS = 3; +- final List<BlockPos> blacklistedTargets = Lists.newArrayList(); ++ final List<BlockPos> blacklistedTargets; + @Nullable + private Path lastPath; + private static final int TICKS_BEFORE_HIVE_DROP = 60; + private int ticksStuck; + + BeeGoToHiveGoal() { +- this.setFlags(EnumSet.of(Goal.Flag.MOVE)); ++ super(); ++ this.travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues ++ this.blacklistedTargets = Lists.newArrayList(); ++ this.setFlags(EnumSet.of(Goal.Type.MOVE)); + } + + @Override + public boolean canBeeUse() { +- return Bee.this.hivePos != null +- && !Bee.this.hasRestriction() +- && Bee.this.wantsToEnterHive() +- && !this.hasReachedTarget(Bee.this.hivePos) +- && Bee.this.level().getBlockState(Bee.this.hivePos).is(BlockTags.BEEHIVES); ++ return Bee.this.hivePos != null && !Bee.this.hasRestriction() && Bee.this.wantsToEnterHive() && !this.hasReachedTarget(Bee.this.hivePos) && Bee.this.level().getBlockState(Bee.this.hivePos).is(BlockTags.BEEHIVES); + } + + @Override +@@ -795,7 +1047,7 @@ + @Override + public void tick() { + if (Bee.this.hivePos != null) { +- this.travellingTicks++; ++ ++this.travellingTicks; + if (this.travellingTicks > this.adjustedTickDelay(600)) { + this.dropAndBlacklistHive(); + } else if (!Bee.this.navigation.isInProgress()) { +@@ -807,10 +1059,11 @@ + } + } else { + boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos); ++ + if (!flag) { + this.dropAndBlacklistHive(); + } else if (this.lastPath != null && Bee.this.navigation.getPath().sameAs(this.lastPath)) { +- this.ticksStuck++; ++ ++this.ticksStuck; + if (this.ticksStuck > 60) { + this.dropHive(); + this.ticksStuck = 0; +@@ -818,6 +1071,7 @@ + } else { + this.lastPath = Bee.this.navigation.getPath(); + } ++ + } + } + } +@@ -825,7 +1079,7 @@ + + private boolean pathfindDirectlyTowards(BlockPos pos) { + Bee.this.navigation.setMaxVisitedNodesMultiplier(10.0F); +- Bee.this.navigation.moveTo((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), 1.0); ++ Bee.this.navigation.moveTo((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 1.0D); + return Bee.this.navigation.getPath() != null && Bee.this.navigation.getPath().canReach(); + } + +@@ -839,6 +1093,7 @@ + while (this.blacklistedTargets.size() > 3) { + this.blacklistedTargets.remove(0); + } ++ + } + + void clearBlacklist() { +@@ -862,27 +1117,27 @@ + if (Bee.this.closerThan(pos, 2)) { + return true; + } else { +- Path path = Bee.this.navigation.getPath(); +- return path != null && path.getTarget().equals(pos) && path.canReach() && path.isDone(); ++ Path pathentity = Bee.this.navigation.getPath(); ++ ++ return pathentity != null && pathentity.getTarget().equals(pos) && pathentity.canReach() && pathentity.isDone(); + } + } + } + + public class BeeGoToKnownFlowerGoal extends Bee.BaseBeeGoal { ++ + private static final int MAX_TRAVELLING_TICKS = 600; +- int travellingTicks = Bee.this.level().random.nextInt(10); ++ int travellingTicks; + + BeeGoToKnownFlowerGoal() { +- this.setFlags(EnumSet.of(Goal.Flag.MOVE)); ++ super(); ++ this.travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues ++ this.setFlags(EnumSet.of(Goal.Type.MOVE)); + } + + @Override + public boolean canBeeUse() { +- return Bee.this.savedFlowerPos != null +- && !Bee.this.hasRestriction() +- && this.wantsToGoToKnownFlower() +- && Bee.this.isFlowerValid(Bee.this.savedFlowerPos) +- && !Bee.this.closerThan(Bee.this.savedFlowerPos, 2); ++ return Bee.this.savedFlowerPos != null && !Bee.this.hasRestriction() && this.wantsToGoToKnownFlower() && Bee.this.isFlowerValid(Bee.this.savedFlowerPos) && !Bee.this.closerThan(Bee.this.savedFlowerPos, 2); + } + + @Override +@@ -906,7 +1161,7 @@ + @Override + public void tick() { + if (Bee.this.savedFlowerPos != null) { +- this.travellingTicks++; ++ ++this.travellingTicks; + if (this.travellingTicks > this.adjustedTickDelay(600)) { + Bee.this.savedFlowerPos = null; + } else if (!Bee.this.navigation.isInProgress()) { +@@ -924,12 +1179,17 @@ + } + } + +- class BeeGrowCropGoal extends Bee.BaseBeeGoal { ++ private class BeeGrowCropGoal extends Bee.BaseBeeGoal { ++ + static final int GROW_CHANCE = 30; + ++ BeeGrowCropGoal() { ++ super(); ++ } ++ + @Override + public boolean canBeeUse() { +- return Bee.this.getCropsGrownSincePollination() < 10 && !(Bee.this.random.nextFloat() < 0.3F) && Bee.this.hasNectar() && Bee.this.isHiveValid(); ++ return Bee.this.getCropsGrownSincePollination() >= 10 ? false : (Bee.this.random.nextFloat() < 0.3F ? false : Bee.this.hasNectar() && Bee.this.isHiveValid()); + } + + @Override +@@ -940,342 +1200,163 @@ + @Override + public void tick() { + if (Bee.this.random.nextInt(this.adjustedTickDelay(30)) == 0) { +- for (int i = 1; i <= 2; i++) { +- BlockPos blockPos = Bee.this.blockPosition().below(i); +- BlockState blockState = Bee.this.level().getBlockState(blockPos); +- Block block = blockState.getBlock(); +- BlockState blockState1 = null; +- if (blockState.is(BlockTags.BEE_GROWABLES)) { ++ for (int i = 1; i <= 2; ++i) { ++ BlockPos blockposition = Bee.this.blockPosition().below(i); ++ IBlockData iblockdata = Bee.this.level().getBlockState(blockposition); ++ Block block = iblockdata.getBlock(); ++ IBlockData iblockdata1 = null; ++ ++ if (iblockdata.is(BlockTags.BEE_GROWABLES)) { + if (block instanceof CropBlock) { +- CropBlock cropBlock = (CropBlock)block; +- if (!cropBlock.isMaxAge(blockState)) { +- blockState1 = cropBlock.getStateForAge(cropBlock.getAge(blockState) + 1); ++ CropBlock blockcrops = (CropBlock) block; ++ ++ if (!blockcrops.isMaxAge(iblockdata)) { ++ iblockdata1 = blockcrops.getStateForAge(blockcrops.getAge(iblockdata) + 1); + } +- } else if (block instanceof StemBlock) { +- int i1 = blockState.getValue(StemBlock.AGE); +- if (i1 < 7) { +- blockState1 = blockState.setValue(StemBlock.AGE, Integer.valueOf(i1 + 1)); ++ } else { ++ int j; ++ ++ if (block instanceof StemBlock) { ++ j = (Integer) iblockdata.getValue(StemBlock.AGE); ++ if (j < 7) { ++ iblockdata1 = (IBlockData) iblockdata.setValue(StemBlock.AGE, j + 1); ++ } ++ } else if (iblockdata.is(Blocks.SWEET_BERRY_BUSH)) { ++ j = (Integer) iblockdata.getValue(SweetBerryBushBlock.AGE); ++ if (j < 3) { ++ iblockdata1 = (IBlockData) iblockdata.setValue(SweetBerryBushBlock.AGE, j + 1); ++ } ++ } else if (iblockdata.is(Blocks.CAVE_VINES) || iblockdata.is(Blocks.CAVE_VINES_PLANT)) { ++ ((BonemealableBlock) iblockdata.getBlock()).performBonemeal((ServerLevel) Bee.this.level(), Bee.this.random, blockposition, iblockdata); + } +- } else if (blockState.is(Blocks.SWEET_BERRY_BUSH)) { +- int i1 = blockState.getValue(SweetBerryBushBlock.AGE); +- if (i1 < 3) { +- blockState1 = blockState.setValue(SweetBerryBushBlock.AGE, Integer.valueOf(i1 + 1)); +- } +- } else if (blockState.is(Blocks.CAVE_VINES) || blockState.is(Blocks.CAVE_VINES_PLANT)) { +- ((BonemealableBlock)blockState.getBlock()).performBonemeal((ServerLevel)Bee.this.level(), Bee.this.random, blockPos, blockState); + } + +- if (blockState1 != null) { +- Bee.this.level().levelEvent(2005, blockPos, 0); +- Bee.this.level().setBlockAndUpdate(blockPos, blockState1); ++ if (iblockdata1 != null && CraftEventFactory.callEntityChangeBlockEvent(Bee.this, blockposition, iblockdata1)) { // CraftBukkit ++ Bee.this.level().levelEvent(2005, blockposition, 0); ++ Bee.this.level().setBlockAndUpdate(blockposition, iblockdata1); + Bee.this.incrementNumCropsGrownSincePollination(); + } + } + } ++ + } + } + } + +- class BeeHurtByOtherGoal extends HurtByTargetGoal { +- BeeHurtByOtherGoal(Bee mob) { +- super(mob); +- } ++ private class BeeWanderGoal extends Goal { + +- @Override +- public boolean canContinueToUse() { +- return Bee.this.isAngry() && super.canContinueToUse(); +- } ++ private static final int WANDER_THRESHOLD = 22; + +- @Override +- protected void alertOther(Mob mob, LivingEntity target) { +- if (mob instanceof Bee && this.mob.hasLineOfSight(target)) { +- mob.setTarget(target); +- } ++ BeeWanderGoal() { ++ this.setFlags(EnumSet.of(Goal.Type.MOVE)); + } +- } + +- class BeeLocateHiveGoal extends Bee.BaseBeeGoal { + @Override +- public boolean canBeeUse() { +- return Bee.this.remainingCooldownBeforeLocatingNewHive == 0 && !Bee.this.hasHive() && Bee.this.wantsToEnterHive(); ++ public boolean canUse() { ++ return Bee.this.navigation.isDone() && Bee.this.random.nextInt(10) == 0; + } + + @Override +- public boolean canBeeContinueToUse() { +- return false; ++ public boolean canContinueToUse() { ++ return Bee.this.navigation.isInProgress(); + } + + @Override + public void start() { +- Bee.this.remainingCooldownBeforeLocatingNewHive = 200; +- List<BlockPos> list = this.findNearbyHivesWithSpace(); +- if (!list.isEmpty()) { +- for (BlockPos blockPos : list) { +- if (!Bee.this.goToHiveGoal.isTargetBlacklisted(blockPos)) { +- Bee.this.hivePos = blockPos; +- return; +- } +- } ++ Vec3 vec3d = this.findPos(); + +- Bee.this.goToHiveGoal.clearBlacklist(); +- Bee.this.hivePos = list.get(0); ++ if (vec3d != null) { ++ Bee.this.navigation.moveTo(Bee.this.navigation.createPath(BlockPos.containing(vec3d), 1), 1.0D); + } +- } + +- private List<BlockPos> findNearbyHivesWithSpace() { +- BlockPos blockPos = Bee.this.blockPosition(); +- PoiManager poiManager = ((ServerLevel)Bee.this.level()).getPoiManager(); +- Stream<PoiRecord> inRange = poiManager.getInRange(holder -> holder.is(PoiTypeTags.BEE_HOME), blockPos, 20, PoiManager.Occupancy.ANY); +- return inRange.map(PoiRecord::getPos) +- .filter(Bee.this::doesHiveHaveSpace) +- .sorted(Comparator.comparingDouble(pos -> pos.distSqr(blockPos))) +- .collect(Collectors.toList()); + } +- } + +- class BeeLookControl extends LookControl { +- BeeLookControl(Mob mob) { +- super(mob); +- } ++ @Nullable ++ private Vec3 findPos() { ++ Vec3 vec3d; + +- @Override +- public void tick() { +- if (!Bee.this.isAngry()) { +- super.tick(); ++ if (Bee.this.isHiveValid() && !Bee.this.closerThan(Bee.this.hivePos, 22)) { ++ Vec3 vec3d1 = Vec3.atCenterOf(Bee.this.hivePos); ++ ++ vec3d = vec3d1.subtract(Bee.this.position()).normalize(); ++ } else { ++ vec3d = Bee.this.getViewVector(0.0F); + } +- } + +- @Override +- protected boolean resetXRotOnTick() { +- return !Bee.this.beePollinateGoal.isPollinating(); ++ boolean flag = true; ++ Vec3 vec3d2 = HoverRandomPos.getPos(Bee.this, 8, 7, vec3d.x, vec3d.z, 1.5707964F, 3, 1); ++ ++ return vec3d2 != null ? vec3d2 : AirAndWaterRandomPos.getPos(Bee.this, 8, 4, -2, vec3d.x, vec3d.z, 1.5707963705062866D); + } + } + +- class BeePollinateGoal extends Bee.BaseBeeGoal { +- private static final int MIN_POLLINATION_TICKS = 400; +- private static final int MIN_FIND_FLOWER_RETRY_COOLDOWN = 20; +- private static final int MAX_FIND_FLOWER_RETRY_COOLDOWN = 60; +- private final Predicate<BlockState> VALID_POLLINATION_BLOCKS = state -> ( +- !state.hasProperty(BlockStateProperties.WATERLOGGED) || !state.getValue(BlockStateProperties.WATERLOGGED) +- ) +- && state.is(BlockTags.FLOWERS) +- && (!state.is(Blocks.SUNFLOWER) || state.getValue(DoublePlantBlock.HALF) == DoubleBlockHalf.UPPER); +- private static final double ARRIVAL_THRESHOLD = 0.1; +- private static final int POSITION_CHANGE_CHANCE = 25; +- private static final float SPEED_MODIFIER = 0.35F; +- private static final float HOVER_HEIGHT_WITHIN_FLOWER = 0.6F; +- private static final float HOVER_POS_OFFSET = 0.33333334F; +- private int successfulPollinatingTicks; +- private int lastSoundPlayedTick; +- private boolean pollinating; +- @Nullable +- private Vec3 hoverPos; +- private int pollinatingTicks; +- private static final int MAX_POLLINATING_TICKS = 600; ++ private class BeeHurtByOtherGoal extends HurtByTargetGoal { + +- BeePollinateGoal() { +- this.setFlags(EnumSet.of(Goal.Flag.MOVE)); ++ BeeHurtByOtherGoal(Bee entitybee) { ++ super(entitybee); + } + + @Override +- public boolean canBeeUse() { +- if (Bee.this.remainingCooldownBeforeLocatingNewFlower > 0) { +- return false; +- } else if (Bee.this.hasNectar()) { +- return false; +- } else if (Bee.this.level().isRaining()) { +- return false; +- } else { +- Optional<BlockPos> optional = this.findNearbyFlower(); +- if (optional.isPresent()) { +- Bee.this.savedFlowerPos = optional.get(); +- Bee.this.navigation +- .moveTo( +- (double)Bee.this.savedFlowerPos.getX() + 0.5, +- (double)Bee.this.savedFlowerPos.getY() + 0.5, +- (double)Bee.this.savedFlowerPos.getZ() + 0.5, +- 1.2F +- ); +- return true; +- } else { +- Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); +- return false; +- } +- } ++ public boolean canContinueToUse() { ++ return Bee.this.isAngry() && super.canContinueToUse(); + } + + @Override +- public boolean canBeeContinueToUse() { +- if (!this.pollinating) { +- return false; +- } else if (!Bee.this.hasSavedFlowerPos()) { +- return false; +- } else if (Bee.this.level().isRaining()) { +- return false; +- } else if (this.hasPollinatedLongEnough()) { +- return Bee.this.random.nextFloat() < 0.2F; +- } else if (Bee.this.tickCount % 20 == 0 && !Bee.this.isFlowerValid(Bee.this.savedFlowerPos)) { +- Bee.this.savedFlowerPos = null; +- return false; +- } else { +- return true; ++ protected void alertOther(Mob mob, LivingEntity target) { ++ if (mob instanceof Bee && this.mob.hasLineOfSight(target)) { ++ mob.setTarget(target, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason + } +- } + +- private boolean hasPollinatedLongEnough() { +- return this.successfulPollinatingTicks > 400; + } ++ } + +- boolean isPollinating() { +- return this.pollinating; +- } ++ private static class BeeBecomeAngryTargetGoal extends NearestAttackableTargetGoal<Player> { + +- void stopPollinating() { +- this.pollinating = false; ++ BeeBecomeAngryTargetGoal(Bee mob) { ++ // Objects.requireNonNull(entitybee); // CraftBukkit - decompile error ++ super(mob, Player.class, 10, true, false, mob::isAngryAt); + } + + @Override +- public void start() { +- this.successfulPollinatingTicks = 0; +- this.pollinatingTicks = 0; +- this.lastSoundPlayedTick = 0; +- this.pollinating = true; +- Bee.this.resetTicksWithoutNectarSinceExitingHive(); ++ public boolean canUse() { ++ return this.beeCanTarget() && super.canUse(); + } + + @Override +- public void stop() { +- if (this.hasPollinatedLongEnough()) { +- Bee.this.setHasNectar(true); +- } ++ public boolean canContinueToUse() { ++ boolean flag = this.beeCanTarget(); + +- this.pollinating = false; +- Bee.this.navigation.stop(); +- Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; +- } +- +- @Override +- public boolean requiresUpdateEveryTick() { +- return true; +- } +- +- @Override +- public void tick() { +- this.pollinatingTicks++; +- if (this.pollinatingTicks > 600) { +- Bee.this.savedFlowerPos = null; ++ if (flag && this.mob.getTarget() != null) { ++ return super.canContinueToUse(); + } else { +- Vec3 vec3 = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0, 0.6F, 0.0); +- if (vec3.distanceTo(Bee.this.position()) > 1.0) { +- this.hoverPos = vec3; +- this.setWantedPos(); +- } else { +- if (this.hoverPos == null) { +- this.hoverPos = vec3; +- } +- +- boolean flag = Bee.this.position().distanceTo(this.hoverPos) <= 0.1; +- boolean flag1 = true; +- if (!flag && this.pollinatingTicks > 600) { +- Bee.this.savedFlowerPos = null; +- } else { +- if (flag) { +- boolean flag2 = Bee.this.random.nextInt(25) == 0; +- if (flag2) { +- this.hoverPos = new Vec3(vec3.x() + (double)this.getOffset(), vec3.y(), vec3.z() + (double)this.getOffset()); +- Bee.this.navigation.stop(); +- } else { +- flag1 = false; +- } +- +- Bee.this.getLookControl().setLookAt(vec3.x(), vec3.y(), vec3.z()); +- } +- +- if (flag1) { +- this.setWantedPos(); +- } +- +- this.successfulPollinatingTicks++; +- if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { +- this.lastSoundPlayedTick = this.successfulPollinatingTicks; +- Bee.this.playSound(SoundEvents.BEE_POLLINATE, 1.0F, 1.0F); +- } +- } +- } ++ this.targetMob = null; ++ return false; + } + } + +- private void setWantedPos() { +- Bee.this.getMoveControl().setWantedPosition(this.hoverPos.x(), this.hoverPos.y(), this.hoverPos.z(), 0.35F); +- } ++ private boolean beeCanTarget() { ++ Bee entitybee = (Bee) this.mob; + +- private float getOffset() { +- return (Bee.this.random.nextFloat() * 2.0F - 1.0F) * 0.33333334F; ++ return entitybee.isAngry() && !entitybee.hasStung(); + } ++ } + +- private Optional<BlockPos> findNearbyFlower() { +- return this.findNearestBlock(this.VALID_POLLINATION_BLOCKS, 5.0); +- } ++ private abstract class BaseBeeGoal extends Goal { + +- private Optional<BlockPos> findNearestBlock(Predicate<BlockState> predicate, double distance) { +- BlockPos blockPos = Bee.this.blockPosition(); +- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ++ BaseBeeGoal() {} + +- for (int i = 0; (double)i <= distance; i = i > 0 ? -i : 1 - i) { +- for (int i1 = 0; (double)i1 < distance; i1++) { +- for (int i2 = 0; i2 <= i1; i2 = i2 > 0 ? -i2 : 1 - i2) { +- for (int i3 = i2 < i1 && i2 > -i1 ? i1 : 0; i3 <= i1; i3 = i3 > 0 ? -i3 : 1 - i3) { +- mutableBlockPos.setWithOffset(blockPos, i2, i - 1, i3); +- if (blockPos.closerThan(mutableBlockPos, distance) && predicate.test(Bee.this.level().getBlockState(mutableBlockPos))) { +- return Optional.of(mutableBlockPos); +- } +- } +- } +- } +- } ++ public abstract boolean canBeeUse(); + +- return Optional.empty(); +- } +- } ++ public abstract boolean canBeeContinueToUse(); + +- class BeeWanderGoal extends Goal { +- private static final int WANDER_THRESHOLD = 22; +- +- BeeWanderGoal() { +- this.setFlags(EnumSet.of(Goal.Flag.MOVE)); +- } +- + @Override + public boolean canUse() { +- return Bee.this.navigation.isDone() && Bee.this.random.nextInt(10) == 0; ++ return this.canBeeUse() && !Bee.this.isAngry(); + } + + @Override + public boolean canContinueToUse() { +- return Bee.this.navigation.isInProgress(); ++ return this.canBeeContinueToUse() && !Bee.this.isAngry(); + } +- +- @Override +- public void start() { +- Vec3 vec3 = this.findPos(); +- if (vec3 != null) { +- Bee.this.navigation.moveTo(Bee.this.navigation.createPath(BlockPos.containing(vec3), 1), 1.0); +- } +- } +- +- @Nullable +- private Vec3 findPos() { +- Vec3 vec31; +- if (Bee.this.isHiveValid() && !Bee.this.closerThan(Bee.this.hivePos, 22)) { +- Vec3 vec3 = Vec3.atCenterOf(Bee.this.hivePos); +- vec31 = vec3.subtract(Bee.this.position()).normalize(); +- } else { +- vec31 = Bee.this.getViewVector(0.0F); +- } +- +- int i = 8; +- Vec3 pos = HoverRandomPos.getPos(Bee.this, 8, 7, vec31.x, vec31.z, (float) (Math.PI / 2), 3, 1); +- return pos != null ? pos : AirAndWaterRandomPos.getPos(Bee.this, 8, 4, -2, vec31.x, vec31.z, (float) (Math.PI / 2)); +- } + } + } |