Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.mysticsbiomes.common.entity.animal;
- import com.mysticsbiomes.common.block.entity.ButterflyNestBlockEntity;
- import com.mysticsbiomes.init.MysticPoiTypes;
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.particles.ParticleOptions;
- import net.minecraft.core.particles.ParticleTypes;
- import net.minecraft.core.registries.Registries;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.NbtUtils;
- 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.tags.BlockTags;
- import net.minecraft.tags.ItemTags;
- import net.minecraft.util.ByIdMap;
- import net.minecraft.util.Mth;
- import net.minecraft.util.StringRepresentable;
- import net.minecraft.world.DifficultyInstance;
- import net.minecraft.world.InteractionHand;
- import net.minecraft.world.InteractionResult;
- import net.minecraft.world.entity.*;
- import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
- import net.minecraft.world.entity.ai.attributes.Attributes;
- import net.minecraft.world.entity.ai.control.FlyingMoveControl;
- import net.minecraft.world.entity.ai.control.LookControl;
- import net.minecraft.world.entity.ai.goal.FloatGoal;
- import net.minecraft.world.entity.ai.goal.Goal;
- import net.minecraft.world.entity.ai.goal.TemptGoal;
- import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation;
- import net.minecraft.world.entity.ai.navigation.PathNavigation;
- import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos;
- import net.minecraft.world.entity.ai.util.AirRandomPos;
- import net.minecraft.world.entity.ai.util.HoverRandomPos;
- import net.minecraft.world.entity.ai.util.RandomPos;
- import net.minecraft.world.entity.ai.village.poi.PoiManager;
- import net.minecraft.world.entity.ai.village.poi.PoiRecord;
- import net.minecraft.world.entity.animal.FlyingAnimal;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.item.crafting.Ingredient;
- import net.minecraft.world.level.Level;
- import net.minecraft.world.level.LevelReader;
- import net.minecraft.world.level.ServerLevelAccessor;
- import net.minecraft.world.level.block.Block;
- import net.minecraft.world.level.block.Blocks;
- import net.minecraft.world.level.block.entity.BlockEntity;
- import net.minecraft.world.level.block.state.BlockState;
- import net.minecraft.world.level.gameevent.GameEvent;
- import net.minecraft.world.level.pathfinder.Path;
- import net.minecraft.world.phys.Vec3;
- import org.jetbrains.annotations.Nullable;
- import java.util.*;
- import java.util.function.IntFunction;
- import java.util.function.Predicate;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- /**
- * Butterflies are friendly ambient anthropoids, useful for growing flowers.
- */
- public class Butterfly extends TamableAnimal implements FlyingAnimal {
- private static final EntityDataAccessor<Integer> DATA_TYPE_ID = SynchedEntityData.defineId(Butterfly.class, EntityDataSerializers.INT);
- public final AnimationState flyingAnimationState = new AnimationState();
- private int remainingCooldownBeforeLocatingNewNest;
- private boolean wantsToEnterNest;
- @Nullable
- private BlockPos nestPos;
- private int ticksSincePlantedFlowers;
- @Nullable
- private Block flower;
- private boolean wasGivenFlower;
- @Nullable
- private BlockPos flowerPos;
- @Nullable
- private BlockPos emptyPos;
- Butterfly.PollinateFlowerGoal pollinateFlowerGoal;
- Butterfly.PlantFlowerGoal plantFlowerGoal;
- private int underWaterTicks;
- public Butterfly(EntityType<? extends Butterfly> type, Level level) {
- super(type, level);
- this.moveControl = new FlyingMoveControl(this, 20, true);
- this.lookControl = new LookControl(this);
- }
- //DATA & TYPES
- protected void defineSynchedData() {
- super.defineSynchedData();
- this.entityData.define(DATA_TYPE_ID, 0);
- }
- protected void registerGoals() {
- this.pollinateFlowerGoal = new PollinateFlowerGoal();
- this.goalSelector.addGoal(0, this.pollinateFlowerGoal);
- this.plantFlowerGoal = new PlantFlowerGoal();
- this.goalSelector.addGoal(0, this.plantFlowerGoal);
- this.goalSelector.addGoal(1, new Butterfly.EnterNestGoal());
- this.goalSelector.addGoal(2, new TemptGoal(this, 1.25D, Ingredient.of(ItemTags.FLOWERS), false));
- this.goalSelector.addGoal(3, new Butterfly.LocateNestGoal());
- this.goalSelector.addGoal(3, new Butterfly.GoToNestGoal());
- this.goalSelector.addGoal(4, new Butterfly.WanderGoal());
- this.goalSelector.addGoal(5, new FloatGoal(this));
- }
- public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FLYING_SPEED, 0.6F).add(Attributes.MOVEMENT_SPEED, 0.3F).add(Attributes.FOLLOW_RANGE, 48.0D);
- }
- @Override
- public void addAdditionalSaveData(CompoundTag tag) {
- super.addAdditionalSaveData(tag);
- if (this.nestPos != null) {
- tag.put("NestPos", NbtUtils.writeBlockPos(this.nestPos));
- }
- if (this.flower != null) {
- tag.putString("Flower", this.flower.getDescriptionId());
- }
- tag.putString("Type", this.getVariant().name);
- tag.putInt("TicksSincePlantedFlowers", this.ticksSincePlantedFlowers);
- }
- @Override
- public void readAdditionalSaveData(CompoundTag tag) {
- this.nestPos = null;
- if (tag.contains("NestPos")) {
- this.nestPos = NbtUtils.readBlockPos(tag.getCompound("NestPos"));
- }
- this.flower = null;
- if (tag.contains("Flower")) {
- this.flower = NbtUtils.readBlockState(this.level().holderLookup(Registries.BLOCK), tag.getCompound("Flower")).getBlock();
- }
- super.readAdditionalSaveData(tag);
- this.setVariant(Type.byName(tag.getString("Type")));
- this.ticksSincePlantedFlowers = tag.getInt("TicksSincePlantedFlowers");
- }
- @Override
- public SpawnGroupData finalizeSpawn(ServerLevelAccessor accessor, DifficultyInstance instance, MobSpawnType type, @Nullable SpawnGroupData data, @Nullable CompoundTag tag) {
- data = super.finalizeSpawn(accessor, instance, type, data, tag);
- this.setVariant(Type.byId(random.nextInt(3)));
- return data;
- }
- @Nullable
- @Override
- public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob mob) {
- return null;
- }
- public MobType getMobType() {
- return MobType.ARTHROPOD;
- }
- public Type getVariant() {
- return Type.byId(this.entityData.get(DATA_TYPE_ID));
- }
- public void setVariant(Type type) {
- this.entityData.set(DATA_TYPE_ID, type.id);
- }
- //TICK
- public void tick() {
- if (this.level().isClientSide()) {
- this.flyingAnimationState.animateWhen(this.isFlying(), this.tickCount);
- }
- super.tick();
- }
- public void aiStep() {
- super.aiStep();
- if (!this.level().isClientSide) {
- if (this.remainingCooldownBeforeLocatingNewNest > 0) {
- --this.remainingCooldownBeforeLocatingNewNest;
- }
- ++this.ticksSincePlantedFlowers;
- if (this.tickCount % 20 == 0 && !this.isNestValid()) {
- this.nestPos = null;
- }
- }
- }
- protected void customServerAiStep() {
- if (this.isInWaterOrBubble()) {
- ++this.underWaterTicks;
- } else {
- this.underWaterTicks = 0;
- }
- if (this.underWaterTicks > 20) {
- this.hurt(this.damageSources().drown(), 1.0F);
- }
- boolean flag = this.level().isRaining() || this.level().isNight();
- if (flag && !this.isNestNearFire()) {
- this.wantsToEnterNest = true;
- }
- }
- //PARTICLES
- protected void addParticlesAroundSelf(ParticleOptions options) {
- for (int i = 0; i < 5; ++i) {
- double d0 = this.random.nextGaussian() * 0.02D;
- double d1 = this.random.nextGaussian() * 0.02D;
- double d2 = this.random.nextGaussian() * 0.02D;
- this.level().addParticle(options, this.getRandomX(1.0D), this.getRandomY() + 1.0D, this.getRandomZ(1.0D), d0, d1, d2);
- }
- }
- //MOVEMENT
- protected PathNavigation createNavigation(Level level) {
- FlyingPathNavigation navigation = new FlyingPathNavigation(this, level) {
- public boolean isStableDestination(BlockPos pos) {
- return !this.level.getBlockState(pos.below()).isAir();
- }
- };
- navigation.setCanOpenDoors(false);
- navigation.setCanFloat(false);
- navigation.setCanPassDoors(true);
- return navigation;
- }
- protected void checkFallDamage(double distance, boolean b, BlockState state, BlockPos pos) {
- }
- public float getWalkTargetValue(BlockPos pos, LevelReader reader) {
- return reader.getBlockState(pos).isAir() ? 10.0F : 0.0F;
- }
- public boolean isFlying() {
- return !this.onGround();
- }
- //DISTANCE
- private void pathfindRandomlyTowards(BlockPos pos) {
- Vec3 vec3 = Vec3.atBottomCenterOf(pos);
- int i = 0;
- BlockPos pos1 = this.blockPosition();
- int j = (int)vec3.y - pos1.getY();
- if (j > 2) {
- i = 4;
- } else if (j < -2) {
- i = -4;
- }
- int k = 6;
- int l = 8;
- int i1 = pos1.distManhattan(pos);
- if (i1 < 15) {
- k = i1 / 2;
- l = i1 / 2;
- }
- Vec3 vec31 = AirRandomPos.getPosTowards(this, k, l, i, vec3, (float)Math.PI / 10F);
- if (vec31 != null) {
- this.navigation.setMaxVisitedNodesMultiplier(0.5F);
- this.navigation.moveTo(vec31.x, vec31.y, vec31.z, 1.0D);
- }
- }
- private boolean pathfindDirectlyTowards(BlockPos pos) {
- Butterfly.this.navigation.setMaxVisitedNodesMultiplier(10.0F);
- Butterfly.this.navigation.moveTo(pos.getX(), pos.getY(), pos.getZ(), 1.0D);
- return Butterfly.this.navigation.getPath() != null && Butterfly.this.navigation.getPath().canReach();
- }
- private boolean hasReachedTarget(BlockPos pos) {
- if (Butterfly.this.closerThan(pos, 0)) {
- return true;
- } else {
- Path path = Butterfly.this.navigation.getPath();
- return path != null && path.getTarget().equals(pos) && path.canReach() && path.isDone();
- }
- }
- private boolean isTooFarAway(BlockPos pos) {
- return !this.closerThan(pos, 32);
- }
- private boolean closerThan(BlockPos pos, int distance) {
- return pos != null && pos.closerThan(this.blockPosition(), distance);
- }
- //POSITION
- @Nullable
- private Vec3 hoverPos;
- private void setPollinatingPos(BlockPos pos) {
- Vec3 vec3 = Vec3.atBottomCenterOf(pos).add(0.0D, 0.6F, 0.0D);
- if (vec3.distanceTo(Butterfly.this.position()) > 1.0D) {
- this.hoverPos = vec3;
- this.setWantedPos();
- } else {
- if (this.hoverPos == null) {
- this.hoverPos = vec3;
- }
- boolean flag = Butterfly.this.position().distanceTo(this.hoverPos) <= 0.1D;
- boolean flag1 = true;
- if (flag) {
- boolean flag2 = Butterfly.this.random.nextInt(100) < 5;
- if (flag2) {
- this.hoverPos = new Vec3(vec3.x() + (double)this.getOffset(), vec3.y(), vec3.z() + (double)this.getOffset());
- Butterfly.this.navigation.stop();
- } else {
- flag1 = false;
- }
- Butterfly.this.getLookControl().setLookAt(vec3.x(), vec3.y(), vec3.z());
- }
- if (flag1) {
- this.setWantedPos();
- }
- }
- }
- private void setWantedPos() {
- if (this.hoverPos != null) {
- Butterfly.this.getMoveControl().setWantedPosition(this.hoverPos.x(), this.hoverPos.y(), this.hoverPos.z(), 0.35F);
- }
- }
- private float getOffset() {
- return (Butterfly.this.random.nextFloat() * 2.0F - 1.0F) * 0.33333334F;
- }
- //NEST
- private boolean isNestValid() {
- if (this.nestPos == null) {
- return false;
- } else if (this.isTooFarAway(this.nestPos)) {
- return false;
- } else {
- BlockEntity blockEntity = this.level().getBlockEntity(this.nestPos);
- return blockEntity instanceof ButterflyNestBlockEntity;
- }
- }
- private boolean isNestNearFire() {
- if (this.nestPos == null) {
- return false;
- } else {
- BlockEntity blockEntity = this.level().getBlockEntity(this.nestPos);
- return blockEntity instanceof ButterflyNestBlockEntity && ((ButterflyNestBlockEntity)blockEntity).isFireNearby();
- }
- }
- private boolean doesNestHaveSpace(BlockPos pos) {
- BlockEntity blockEntity = this.level().getBlockEntity(pos);
- if (blockEntity instanceof ButterflyNestBlockEntity entity) {
- return !entity.isFull();
- } else {
- return false;
- }
- }
- public boolean wantsToEnterNest() {
- return this.wantsToEnterNest;
- }
- //FLOWER BREEDING
- private Optional<BlockPos> findNearestBlock(Block block, double distance) {
- return this.findNearestBlock((b) -> b.defaultBlockState().is(block), distance);
- }
- private Optional<BlockPos> findNearestBlock(Predicate<Block> predicate, double distance) {
- BlockPos pos = Butterfly.this.blockPosition();
- BlockPos.MutableBlockPos mutablePos = 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) {
- mutablePos.setWithOffset(pos, k, i - 1, l);
- if (pos.closerThan(mutablePos, distance) && predicate.test(Butterfly.this.level().getBlockState(mutablePos).getBlock())) {
- return Optional.of(mutablePos);
- }
- }
- }
- }
- }
- return Optional.empty();
- }
- private void resetTicksSincePlantedFlowers() {
- this.ticksSincePlantedFlowers = 0;
- }
- private boolean wantsToPlantFlowers() {
- return this.ticksSincePlantedFlowers > 100;
- }
- /** @return sends a butterfly to the same given flower nearby them. */
- @Override
- public InteractionResult mobInteract(Player player, InteractionHand hand) {
- Block block = Block.byItem(player.getItemInHand(hand).getItem());
- if (block.defaultBlockState().is(BlockTags.SMALL_FLOWERS)) {
- if (this.wantsToPlantFlowers()) {
- this.flower = block;
- this.wasGivenFlower = true;
- this.addParticlesAroundSelf(ParticleTypes.HAPPY_VILLAGER);
- return InteractionResult.SUCCESS;
- } else {
- this.addParticlesAroundSelf(ParticleTypes.ANGRY_VILLAGER);
- return InteractionResult.FAIL;
- }
- }
- return super.mobInteract(player, hand);
- }
- /**
- *
- */
- class LocateNestGoal extends Goal {
- public boolean canUse() {
- return Butterfly.this.remainingCooldownBeforeLocatingNewNest == 0 && Butterfly.this.nestPos == null && Butterfly.this.wantsToEnterNest();
- }
- public boolean canContinueToUse() {
- return false;
- }
- public void start() {
- Butterfly.this.remainingCooldownBeforeLocatingNewNest = 200;
- List<BlockPos> list = this.findNearbyNestsWithSpace();
- if (!list.isEmpty()) {
- for (BlockPos pos : list) {
- Butterfly.this.nestPos = pos;
- return;
- }
- Butterfly.this.nestPos = list.get(0);
- }
- }
- private List<BlockPos> findNearbyNestsWithSpace() {
- BlockPos pos = Butterfly.this.blockPosition();
- PoiManager poi = ((ServerLevel)Butterfly.this.level()).getPoiManager();
- Stream<PoiRecord> stream = poi.getInRange((holder) -> holder.is(MysticPoiTypes.BUTTERFLY_NEST.getId()), pos, 20, PoiManager.Occupancy.ANY);
- return stream.map(PoiRecord::getPos).filter(Butterfly.this::doesNestHaveSpace).sorted(Comparator.comparingDouble((pos1) -> pos1.distSqr(pos))).collect(Collectors.toList());
- }
- }
- class EnterNestGoal extends Goal {
- public boolean canUse() {
- if (Butterfly.this.nestPos != null && Butterfly.this.wantsToEnterNest() && Butterfly.this.nestPos.closerToCenterThan(Butterfly.this.position(), 2.0D)) {
- BlockEntity entity = Butterfly.this.level().getBlockEntity(Butterfly.this.nestPos);
- if (entity instanceof ButterflyNestBlockEntity blockEntity) {
- return !blockEntity.isFull();
- }
- }
- return false;
- }
- public boolean canContinueToUse() {
- return false;
- }
- public void start() {
- if (Butterfly.this.nestPos != null) {
- BlockEntity entity = Butterfly.this.level().getBlockEntity(Butterfly.this.nestPos);
- if (entity instanceof ButterflyNestBlockEntity blockEntity) {
- blockEntity.addOccupant(Butterfly.this);
- }
- }
- }
- }
- class GoToNestGoal extends Goal {
- @Nullable
- private Path lastPath;
- GoToNestGoal() {
- this.setFlags(EnumSet.of(Goal.Flag.MOVE));
- }
- public boolean canUse() {
- return Butterfly.this.nestPos != null && !Butterfly.this.hasRestriction() && Butterfly.this.wantsToEnterNest() && !Butterfly.this.hasReachedTarget(Butterfly.this.nestPos);
- }
- public boolean canContinueToUse() {
- return this.canUse();
- }
- public void stop() {
- Butterfly.this.navigation.stop();
- Butterfly.this.navigation.resetMaxVisitedNodesMultiplier();
- }
- public void tick() {
- if (Butterfly.this.nestPos != null) {
- if (!Butterfly.this.navigation.isInProgress()) {
- if (!Butterfly.this.closerThan(Butterfly.this.nestPos, 16)) {
- Butterfly.this.pathfindRandomlyTowards(Butterfly.this.nestPos);
- } else {
- boolean flag = Butterfly.this.pathfindDirectlyTowards(Butterfly.this.nestPos);
- if (flag) {
- if (this.lastPath != null) {
- this.lastPath = Butterfly.this.navigation.getPath();
- }
- }
- }
- }
- }
- }
- }
- abstract class SpreadFlowersGoal extends Goal {
- int flowersPlanted;
- SpreadFlowersGoal() {
- this.setFlags(EnumSet.of(Goal.Flag.MOVE));
- }
- public boolean canUse() {
- return this.flowersPlanted < 4 && Butterfly.this.wantsToPlantFlowers() && !Butterfly.this.level().isRaining();
- }
- public boolean canContinueToUse() {
- return this.canUse();
- }
- public void start() {
- this.flowersPlanted = 0;
- }
- public void stop() {
- Butterfly.this.navigation.stop();
- }
- public boolean requiresUpdateEveryTick() {
- return true;
- }
- }
- class PollinateFlowerGoal extends SpreadFlowersGoal {
- private int pollinatingTicks;
- private boolean hasPollinatedFlower;
- PollinateFlowerGoal() {
- super();
- }
- public boolean canUse() {
- return Butterfly.this.wasGivenFlower;
- }
- public boolean canContinueToUse() {
- return this.canUse();
- }
- public void start() {
- this.pollinatingTicks = 0;
- this.hasPollinatedFlower = false;
- Optional<BlockPos> optional = Butterfly.this.findNearestBlock(Butterfly.this.flower, 16.0D);
- if (optional.isPresent() && Butterfly.this.flowerPos == null) {
- Butterfly.this.flowerPos = optional.get();
- }
- }
- public void stop() {
- super.stop();
- this.hasPollinatedFlower = true;
- }
- public void tick() {
- ++this.pollinatingTicks;
- if (this.pollinatingTicks > 100) {
- Butterfly.this.wasGivenFlower = false;
- } else {
- if (Butterfly.this.flowerPos != null) {
- if (!Butterfly.this.hasReachedTarget(Butterfly.this.flowerPos)) {
- Butterfly.this.navigation.moveTo((double)Butterfly.this.flowerPos.getX() + 0.5D, (double)Butterfly.this.flowerPos.getY() + 0.5D, (double)Butterfly.this.flowerPos.getZ() + 0.5D, 1.2F);
- } else {
- Butterfly.this.setPollinatingPos(Butterfly.this.flowerPos);
- }
- }
- }
- }
- }
- class PlantFlowerGoal extends SpreadFlowersGoal {
- private int plantingFlowerTicks;
- PlantFlowerGoal() {
- super();
- }
- public boolean canUse() {
- return super.canUse() && Butterfly.this.pollinateFlowerGoal.hasPollinatedFlower;
- }
- public boolean canContinueToUse() {
- return this.canUse();
- }
- public void start() {
- this.plantingFlowerTicks = 0;
- Optional<BlockPos> optional = Butterfly.this.findNearestBlock(Blocks.GRASS_BLOCK, 4.0D);
- if (optional.isPresent()) {
- int x = optional.get().getX() + Mth.floor(random.nextBoolean() ? random.nextInt(4) : -random.nextInt(4));
- int y = optional.get().above().getY();
- int z = optional.get().getZ() + Mth.floor(random.nextBoolean() ? random.nextInt(4) : -random.nextInt(4));
- Butterfly.this.emptyPos = new BlockPos(x, y, z);
- }
- }
- public void stop() {
- super.stop();
- this.flowersPlanted = this.flowersPlanted + 1;
- if (this.flowersPlanted < 4) {
- this.repeat();
- } else {
- this.flowersPlanted = 0;
- Butterfly.this.resetTicksSincePlantedFlowers();
- }
- }
- public void tick() {
- ++this.plantingFlowerTicks;
- if (Butterfly.this.emptyPos != null) {
- if (!Butterfly.this.hasReachedTarget(Butterfly.this.emptyPos)) {
- Butterfly.this.navigation.moveTo(Butterfly.this.emptyPos.getX(), Butterfly.this.emptyPos.getY() + 0.5D, Butterfly.this.emptyPos.getZ(), 1.2F);
- } else {
- Butterfly.this.setPollinatingPos(Butterfly.this.emptyPos);
- Butterfly.this.navigation.stop();
- if (this.plantingFlowerTicks > 100) {
- Butterfly.this.pollinateFlowerGoal.hasPollinatedFlower = false;
- if (!Butterfly.this.level().isClientSide) {
- int x = Mth.floor(Butterfly.this.getX());
- int y = Mth.floor(Butterfly.this.getY());
- int z = Mth.floor(Butterfly.this.getZ());
- BlockPos butterflyPos = new BlockPos(x, y, z);
- if (Butterfly.this.flower != null) {
- BlockState flowerState = Butterfly.this.flower.defaultBlockState();
- if (Butterfly.this.level().isEmptyBlock(butterflyPos) && flowerState.canSurvive(Butterfly.this.level(), butterflyPos)) {
- Butterfly.this.level().setBlockAndUpdate(butterflyPos, flowerState);
- Butterfly.this.level().gameEvent(GameEvent.BLOCK_PLACE, butterflyPos, GameEvent.Context.of(Butterfly.this, flowerState));
- }
- }
- }
- }
- }
- }
- }
- /** Reset to repeat until butterfly has planted 3 flowers. */
- private void repeat() {
- Butterfly.this.wasGivenFlower = true;
- Butterfly.this.emptyPos = null;
- }
- }
- class WanderGoal extends Goal {
- WanderGoal() {
- this.setFlags(EnumSet.of(Goal.Flag.MOVE));
- }
- public boolean canUse() {
- return Butterfly.this.navigation.isDone() && Butterfly.this.random.nextInt(10) == 0;
- }
- public boolean canContinueToUse() {
- return Butterfly.this.navigation.isInProgress();
- }
- public void start() {
- Vec3 vec3 = this.findPos();
- if (vec3 != null) {
- Butterfly.this.navigation.moveTo(Butterfly.this.navigation.createPath(BlockPos.containing(vec3), 1), 1.0D);
- }
- }
- @Nullable
- private Vec3 findPos() {
- Vec3 vec3;
- if (Butterfly.this.isNestValid() && Butterfly.this.nestPos != null && !Butterfly.this.closerThan(Butterfly.this.nestPos, 22)) {
- Vec3 vec31 = Vec3.atCenterOf(Butterfly.this.nestPos);
- vec3 = vec31.subtract(Butterfly.this.position()).normalize();
- } else {
- vec3 = Butterfly.this.getViewVector(0.0F);
- }
- Vec3 vec32 = HoverRandomPos.getPos(Butterfly.this, 8, 7, vec3.x, vec3.z, ((float)Math.PI / 2F), 3, 1);
- return vec32 != null ? vec32 : AirAndWaterRandomPos.getPos(Butterfly.this, 8, 4, -2, vec3.x, vec3.z, ((float)Math.PI / 2F));
- }
- }
- public enum Type implements StringRepresentable {
- APRICOT(0, "apricot"),
- CITRUS(1, "citrus"),
- MYSTIC(2, "mystic"),
- VALENTINE(3, "valentine"),
- JELLY(4, "jelly"),
- AUGUST(5, "august");
- @SuppressWarnings("deprecation")
- public static final StringRepresentable.EnumCodec<Type> CODEC = StringRepresentable.fromEnum(Type::values);
- private static final IntFunction<Type> BY_ID = ByIdMap.continuous(Type::getId, values(), ByIdMap.OutOfBoundsStrategy.ZERO);
- private final int id;
- private final String name;
- Type(int id, String name) {
- this.id = id;
- this.name = name;
- }
- public String getSerializedName() {
- return this.name;
- }
- public int getId() {
- return this.id;
- }
- public static Type byName(String name) {
- return CODEC.byName(name, APRICOT);
- }
- public static Type byId(int id) {
- return BY_ID.apply(id);
- }
- }
- }
Add Comment
Please, Sign In to add comment