Advertisement
jayhillx

butterfly 2

Mar 3rd, 2023 (edited)
1,026
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.34 KB | None | 0 0
  1. package com.mysticsbiomes.client.entity;
  2.  
  3. import com.google.common.collect.Maps;
  4. import com.mysticsbiomes.core.MysticsBiomes;
  5. import com.mysticsbiomes.core.init.MysticEntities;
  6. import net.minecraft.Util;
  7. import net.minecraft.core.BlockPos;
  8. import net.minecraft.core.HolderSet;
  9. import net.minecraft.core.particles.ParticleOptions;
  10. import net.minecraft.core.particles.ParticleTypes;
  11. import net.minecraft.nbt.CompoundTag;
  12. import net.minecraft.nbt.NbtUtils;
  13. import net.minecraft.network.syncher.EntityDataAccessor;
  14. import net.minecraft.network.syncher.EntityDataSerializers;
  15. import net.minecraft.network.syncher.SynchedEntityData;
  16. import net.minecraft.resources.ResourceLocation;
  17. import net.minecraft.server.level.ServerLevel;
  18. import net.minecraft.sounds.SoundEvents;
  19. import net.minecraft.tags.BlockTags;
  20. import net.minecraft.tags.ItemTags;
  21. import net.minecraft.tags.TagKey;
  22. import net.minecraft.util.Mth;
  23. import net.minecraft.world.InteractionHand;
  24. import net.minecraft.world.InteractionResult;
  25. import net.minecraft.world.damagesource.DamageSource;
  26. import net.minecraft.world.entity.*;
  27. import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
  28. import net.minecraft.world.entity.ai.attributes.Attributes;
  29. import net.minecraft.world.entity.ai.control.FlyingMoveControl;
  30. import net.minecraft.world.entity.ai.control.LookControl;
  31. import net.minecraft.world.entity.ai.goal.BreedGoal;
  32. import net.minecraft.world.entity.ai.goal.FloatGoal;
  33. import net.minecraft.world.entity.ai.goal.Goal;
  34. import net.minecraft.world.entity.ai.goal.TemptGoal;
  35. import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation;
  36. import net.minecraft.world.entity.ai.navigation.PathNavigation;
  37. import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos;
  38. import net.minecraft.world.entity.ai.util.HoverRandomPos;
  39. import net.minecraft.world.entity.animal.Animal;
  40. import net.minecraft.world.entity.animal.FlyingAnimal;
  41. import net.minecraft.world.entity.player.Player;
  42. import net.minecraft.world.item.ItemStack;
  43. import net.minecraft.world.item.crafting.Ingredient;
  44. import net.minecraft.world.level.Level;
  45. import net.minecraft.world.level.LevelReader;
  46. import net.minecraft.world.level.block.Block;
  47. import net.minecraft.world.level.block.Blocks;
  48. import net.minecraft.world.level.block.DoublePlantBlock;
  49. import net.minecraft.world.level.block.state.BlockState;
  50. import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
  51. import net.minecraft.world.phys.Vec3;
  52.  
  53. import javax.annotation.Nullable;
  54. import java.util.EnumSet;
  55. import java.util.Map;
  56. import java.util.Optional;
  57. import java.util.function.Predicate;
  58.  
  59. /**
  60.  * Butterflies are ambient friendly bugs, who's main feature is to spread flowers.
  61.  *
  62.  * Locate Nest Goal
  63.  * Go To Nest Goal
  64.  * Enter Nest Goal
  65.  * Pollinate Goal
  66.  * Locate Flower Goal
  67.  * Spread Flower Goal
  68.  *
  69.  * // DAILY LIFE
  70.  *  - Butterflies flutter around in groups of 4.
  71.  *  - They will randomly decide to pollinate nearby flowers.
  72.  *      - If there are different flowers nearby, they will choose those over a flower they just pollinated.
  73.  *  - When they
  74.  *  - If butterflies do not pollinate in 2 days, they will die.
  75.  *  - Butterflies save the location of every last flower they pollinated.
  76.  *
  77.  *  pollinates a few times through the day
  78.  *  they flutter around
  79.  *  they drop off the nectar they collected at their nest
  80.  *  overtime the nest will have an abundance of nectar, nearby Bees will try to steal some.
  81.  */
  82. public class Butterfly extends Animal implements FlyingAnimal {
  83.     private static final EntityDataAccessor<Byte> DATA_FLAGS_ID = SynchedEntityData.defineId(Butterfly.class, EntityDataSerializers.BYTE);
  84.     private static final EntityDataAccessor<Integer> DATA_TYPE_ID = SynchedEntityData.defineId(Butterfly.class, EntityDataSerializers.INT);
  85.     public static final int TICKS_PER_FLAP = Mth.ceil(1.4959966F);
  86.     int ticksSinceLastPollinated;
  87.     int remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60);
  88.     private int underWaterTicks;
  89.     @Nullable
  90.     BlockPos savedFlowerPos;
  91.     @Nullable
  92.     ResourceLocation givenFlower;
  93.     Butterfly.PollinateGoal pollinateGoal;
  94.     public static final Map<Integer, ResourceLocation> TEXTURE_BY_TYPE = Util.make(Maps.newHashMap(), (map) -> {
  95.         map.put(1, MysticsBiomes.modLoc("textures/entity/butterfly/orange.png"));
  96.         map.put(2, MysticsBiomes.modLoc("textures/entity/butterfly/peach.png"));
  97.         map.put(3, MysticsBiomes.modLoc("textures/entity/butterfly/lilac.png"));
  98.         map.put(4, MysticsBiomes.modLoc("textures/entity/butterfly/blue.png"));
  99.         map.put(5, MysticsBiomes.modLoc("textures/entity/butterfly/white.png"));
  100.         map.put(6, MysticsBiomes.modLoc("textures/entity/butterfly/black.png"));
  101.     });
  102.  
  103.     public Butterfly(EntityType<? extends Animal> type, Level level) {
  104.         super(type, level);
  105.         this.moveControl = new FlyingMoveControl(this, 20, true);
  106.         this.lookControl = new LookControl(this);
  107.     }
  108.  
  109.     protected void defineSynchedData() {
  110.         super.defineSynchedData();
  111.         this.entityData.define(DATA_FLAGS_ID, (byte)0);
  112.         this.entityData.define(DATA_TYPE_ID, this.random.nextInt(1, 7));
  113.     }
  114.  
  115.     protected void registerGoals() {
  116.         this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
  117.         this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(ItemTags.FLOWERS), false));
  118.         this.pollinateGoal = new Butterfly.PollinateGoal();
  119.         this.goalSelector.addGoal(4, this.pollinateGoal);
  120.         this.goalSelector.addGoal(7, new Butterfly.WanderGoal());
  121.         this.goalSelector.addGoal(9, new FloatGoal(this));
  122.     }
  123.  
  124.     public static AttributeSupplier.Builder createAttributes() {
  125.         return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FLYING_SPEED, 0.7F).add(Attributes.MOVEMENT_SPEED, 0.3F).add(Attributes.FOLLOW_RANGE, 48.0D);
  126.     }
  127.  
  128.     public void addAdditionalSaveData(CompoundTag tag) {
  129.         super.addAdditionalSaveData(tag);
  130.  
  131.         if (this.hasSavedFlowerPos()) {
  132.             tag.put("FlowerPos", NbtUtils.writeBlockPos(this.getSavedFlowerPos()));
  133.         }
  134.  
  135.         if (this.hasGivenFlower()) {
  136.             tag.putString("GivenFlower", String.valueOf(this.getGivenFlower()));
  137.         }
  138.         tag.putInt("Type", this.getButterflyType());
  139.     }
  140.  
  141.     public void readAdditionalSaveData(CompoundTag tag) {
  142.         this.savedFlowerPos = null;
  143.         if (tag.contains("FlowerPos")) {
  144.             this.savedFlowerPos = NbtUtils.readBlockPos(tag.getCompound("FlowerPos"));
  145.         }
  146.  
  147.         if (tag.contains("GivenFlower")) {
  148.             this.givenFlower = ResourceLocation.tryParse(tag.getString("GivenFlower"));
  149.         }
  150.         super.readAdditionalSaveData(tag);
  151.         this.setButterflyType(tag.getInt("Type"));
  152.     }
  153.  
  154.     public int getButterflyType() {
  155.         return this.entityData.get(DATA_TYPE_ID);
  156.     }
  157.  
  158.     public void setButterflyType(int value) {
  159.         if (value <= 1 || value >= 6) {
  160.             value = this.random.nextInt(6);
  161.         }
  162.         this.entityData.set(DATA_TYPE_ID, value);
  163.     }
  164.  
  165.     public MobType getMobType() {
  166.         return MobType.ARTHROPOD;
  167.     }
  168.  
  169.     public Butterfly getBreedOffspring(ServerLevel level, AgeableMob mob) {
  170.         return MysticEntities.BUTTERFLY.get().create(level);
  171.     }
  172.  
  173.     protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
  174.         return dimensions.height * 0.5F;
  175.     }
  176.  
  177.     ///////////////////////////////////////////////////////////////////////////////////////
  178.  
  179.     public InteractionResult mobInteract(Player player, InteractionHand hand) {
  180.         ItemStack stack = player.getItemInHand(hand);
  181.  
  182.         if (stack.is(ItemTags.FLOWERS)) {
  183.             ResourceLocation location = stack.getItem().getRegistryName();
  184.  
  185.             if (Butterfly.this.hasNectar()) {
  186.  
  187.                 this.setGivenFlower(location);
  188.  
  189.                 return InteractionResult.SUCCESS;
  190.             }
  191.         }
  192.         return InteractionResult.PASS;
  193.     }
  194.  
  195.     public void tick() {
  196.         super.tick();
  197.     }
  198.  
  199.     public void aiStep() {
  200.         super.aiStep();
  201.         if (!this.level.isClientSide) {
  202.  
  203.             if (this.remainingCooldownBeforeLocatingNewFlower > 0) {
  204.                 --this.remainingCooldownBeforeLocatingNewFlower;
  205.             }
  206.         }
  207.     }
  208.  
  209.     protected void customServerAiStep() {
  210.         if (this.isInWaterOrBubble()) {
  211.             ++this.underWaterTicks;
  212.         } else {
  213.             this.underWaterTicks = 0;
  214.         }
  215.  
  216.         if (this.underWaterTicks > 20) {
  217.             this.hurt(DamageSource.DROWN, 1.0F);
  218.         }
  219.     }
  220.  
  221.     public void resetTicksSinceLastPollinated() {
  222.         this.ticksSinceLastPollinated = 0;
  223.     }
  224.  
  225.     ///////////////////////////////////////////////////////////////////////////////////////
  226.  
  227.     /**
  228.      * Butterflies cannot fly if they're wet.
  229.      */
  230.     public boolean isFlying() {
  231.         return !this.onGround || !this.isInWaterRainOrBubble();
  232.     }
  233.  
  234.     public boolean isFlapping() {
  235.         return this.isFlying() && this.tickCount % TICKS_PER_FLAP == 0;
  236.     }
  237.  
  238.     public boolean causeFallDamage(float amount, float height, DamageSource source) {
  239.         return false;
  240.     }
  241.  
  242.     public float getWalkTargetValue(BlockPos pos, LevelReader reader) {
  243.         return reader.getBlockState(pos).isAir() ? 10.0F : 0.0F;
  244.     }
  245.  
  246.     protected PathNavigation createNavigation(Level level) {
  247.         FlyingPathNavigation navigation = new FlyingPathNavigation(this, level) {
  248.             public boolean isStableDestination(BlockPos pos) {
  249.                 return !this.level.getBlockState(pos.below()).isAir();
  250.             }
  251.  
  252.             public void tick() {
  253.                 super.tick();
  254.             }
  255.         };
  256.         navigation.setCanOpenDoors(false);
  257.         navigation.setCanFloat(false);
  258.         navigation.setCanPassDoors(true);
  259.         return navigation;
  260.     }
  261.  
  262.     ///////////////////////////////////////////////////////////////////////////////////////
  263.  
  264.     @Nullable
  265.     public BlockPos getSavedFlowerPos() {
  266.         return this.savedFlowerPos;
  267.     }
  268.  
  269.     public boolean hasSavedFlowerPos() {
  270.         return this.savedFlowerPos != null;
  271.     }
  272.  
  273.     public void setSavedFlowerPos(BlockPos pos) {
  274.         this.savedFlowerPos = pos;
  275.     }
  276.  
  277.     public boolean isFlowerValid(BlockPos pos) {
  278.         return this.level.isLoaded(pos) && this.level.getBlockState(pos).is(BlockTags.FLOWERS);
  279.     }
  280.  
  281.     public ResourceLocation getGivenFlower() {
  282.         return this.givenFlower;
  283.     }
  284.  
  285.     public void setGivenFlower(ResourceLocation flower) {
  286.         this.givenFlower = flower;
  287.     }
  288.  
  289.     public boolean hasGivenFlower() {
  290.         return this.getGivenFlower() != null;
  291.     }
  292.  
  293.     ///////////////////////////////////////////////////////////////////////////////////////
  294.  
  295.     public boolean hasNectar() {
  296.         return (this.entityData.get(DATA_FLAGS_ID) & 8) != 0;
  297.     }
  298.  
  299.     public void setHasNectar(boolean hasNectar) {
  300.         if (hasNectar) {
  301.             this.resetTicksSinceLastPollinated();
  302.  
  303.             this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) | 8));
  304.         } else {
  305.             this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) & ~8));
  306.         }
  307.     }
  308.  
  309.     private class LocateFlowerGoal extends Goal {
  310.         private final Predicate<BlockState> VALID_POLLINATION_BLOCK = (state) -> {
  311.             return true;
  312.         };
  313.  
  314.         public boolean canUse() {
  315.             if (Butterfly.this.hasNectar()) {
  316.                 Optional<BlockPos> optional = this.findGivenFlower();
  317.  
  318.                 if (optional.isPresent()) {
  319.                     Butterfly.this.savedFlowerPos = optional.get();
  320.                     Butterfly.this.navigation.moveTo((double)Butterfly.this.savedFlowerPos.getX() + 0.5D, (double)Butterfly.this.savedFlowerPos.getY() + 0.5D, (double)Butterfly.this.savedFlowerPos.getZ() + 0.5D, 1.2F);
  321.                     return true;
  322.                 } else {
  323.                     Butterfly.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Butterfly.this.random, 20, 60);
  324.                     return false;
  325.                 }
  326.             } else {
  327.                 return false;
  328.             }
  329.         }
  330.  
  331.         private Optional<BlockPos> findGivenFlower() {
  332.             return this.findNearestBlock(this.VALID_POLLINATION_BLOCK, 20.0D);
  333.         }
  334.  
  335.         private Optional<BlockPos> findNearestBlock(Predicate<BlockState> predicate, double distance) {
  336.             BlockPos pos = Butterfly.this.blockPosition();
  337.             BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
  338.  
  339.             for (int i = 0; (double)i <= distance; i = i > 0 ? -i : 1 - i) {
  340.                 for (int j = 0; (double)j < distance; ++j) {
  341.                     for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) {
  342.                         for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) {
  343.                             mutablePos.setWithOffset(pos, k, i - 1, l);
  344.  
  345.                             if (pos.closerThan(mutablePos, distance) && predicate.test(Butterfly.this.level.getBlockState(mutablePos))) {
  346.                                 return Optional.of(mutablePos);
  347.                             }
  348.                         }
  349.                     }
  350.                 }
  351.             }
  352.             return Optional.empty();
  353.         }
  354.     }
  355.  
  356.     private class PollinateGoal extends Goal {
  357.         private final Predicate<BlockState> VALID_POLLINATION_BLOCKS = (state) -> {
  358.             if (state.is(BlockTags.FLOWERS)) {
  359.                 if (state.is(Blocks.SUNFLOWER)) {
  360.                     return state.getValue(DoublePlantBlock.HALF) == DoubleBlockHalf.UPPER;
  361.                 } else {
  362.                     return true;
  363.                 }
  364.             } else {
  365.                 return false;
  366.             }
  367.         };
  368.         private int successfulPollinatingTicks;
  369.         private int lastSoundPlayedTick;
  370.         private boolean pollinating;
  371.         @Nullable
  372.         private Vec3 hoverPos;
  373.         private int pollinatingTicks;
  374.  
  375.         PollinateGoal() {
  376.             this.setFlags(EnumSet.of(Goal.Flag.MOVE));
  377.         }
  378.  
  379.         public boolean canUse() {
  380.             if (Butterfly.this.remainingCooldownBeforeLocatingNewFlower > 0) {
  381.                 return false;
  382.             } else if (Butterfly.this.hasNectar()) {
  383.                 return false;
  384.             } else if (Butterfly.this.level.isRaining()) {
  385.                 return false;
  386.             } else {
  387.                 Optional<BlockPos> optional = this.findNearbyFlower();
  388.  
  389.                 if (optional.isPresent()) {
  390.                     Butterfly.this.savedFlowerPos = optional.get();
  391.                     Butterfly.this.navigation.moveTo((double)Butterfly.this.savedFlowerPos.getX() + 0.5D, (double)Butterfly.this.savedFlowerPos.getY() + 0.5D, (double)Butterfly.this.savedFlowerPos.getZ() + 0.5D, 1.2F);
  392.                     return true;
  393.                 } else {
  394.                     Butterfly.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Butterfly.this.random, 20, 60);
  395.                     return false;
  396.                 }
  397.             }
  398.         }
  399.  
  400.         public boolean canContinueToUse() {
  401.             if (!this.pollinating) {
  402.                 return false;
  403.             } else if (!Butterfly.this.hasSavedFlowerPos()) {
  404.                 return false;
  405.             } else if (Butterfly.this.level.isRaining()) {
  406.                 return false;
  407.             } else if (this.hasPollinatedLongEnough()) {
  408.                 return Butterfly.this.random.nextFloat() < 0.2F;
  409.             } else if (Butterfly.this.tickCount % 20 == 0 && !Butterfly.this.isFlowerValid(Butterfly.this.savedFlowerPos)) {
  410.                 Butterfly.this.savedFlowerPos = null;
  411.                 return false;
  412.             } else {
  413.                 return true;
  414.             }
  415.         }
  416.  
  417.         private boolean hasPollinatedLongEnough() {
  418.             return this.successfulPollinatingTicks > 400;
  419.         }
  420.  
  421.         boolean isPollinating() {
  422.             return this.pollinating;
  423.         }
  424.  
  425.         void stopPollinating() {
  426.             this.pollinating = false;
  427.         }
  428.  
  429.         public void start() {
  430.             this.successfulPollinatingTicks = 0;
  431.             this.pollinatingTicks = 0;
  432.             this.lastSoundPlayedTick = 0;
  433.             this.pollinating = true;
  434.             Butterfly.this.resetTicksSinceLastPollinated();
  435.         }
  436.  
  437.         public void stop() {
  438.             if (this.hasPollinatedLongEnough()) {
  439.                 Butterfly.this.setHasNectar(true);
  440.             }
  441.             this.pollinating = false;
  442.             Butterfly.this.navigation.stop();
  443.             Butterfly.this.remainingCooldownBeforeLocatingNewFlower = 200;
  444.         }
  445.  
  446.         public boolean requiresUpdateEveryTick() {
  447.             return true;
  448.         }
  449.  
  450.         public void tick() {
  451.             ++this.pollinatingTicks;
  452.             if (this.pollinatingTicks > 600) {
  453.                 Butterfly.this.savedFlowerPos = null;
  454.             } else {
  455.                 Vec3 vec3 = Vec3.atBottomCenterOf(Butterfly.this.savedFlowerPos).add(0.0D, (double)0.6F, 0.0D);
  456.                 if (vec3.distanceTo(Butterfly.this.position()) > 1.0D) {
  457.                     this.hoverPos = vec3;
  458.                     this.setWantedPos();
  459.                 } else {
  460.                     if (this.hoverPos == null) {
  461.                         this.hoverPos = vec3;
  462.                     }
  463.                     boolean flag = Butterfly.this.position().distanceTo(this.hoverPos) <= 0.1D;
  464.                     boolean flag1 = true;
  465.  
  466.                     if (!flag && this.pollinatingTicks > 600) {
  467.                         Butterfly.this.savedFlowerPos = null;
  468.                     } else {
  469.                         if (flag) {
  470.                             boolean flag2 = Butterfly.this.random.nextInt(25) == 0;
  471.                             if (flag2) {
  472.                                 this.hoverPos = new Vec3(vec3.x() + (double)this.getOffset(), vec3.y(), vec3.z() + (double)this.getOffset());
  473.                                 Butterfly.this.navigation.stop();
  474.                             } else {
  475.                                 flag1 = false;
  476.                             }
  477.  
  478.                             Butterfly.this.getLookControl().setLookAt(vec3.x(), vec3.y(), vec3.z());
  479.                         }
  480.  
  481.                         if (flag1) {
  482.                             this.setWantedPos();
  483.                         }
  484.  
  485.                         ++this.successfulPollinatingTicks;
  486.                         if (Butterfly.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) {
  487.                             this.lastSoundPlayedTick = this.successfulPollinatingTicks;
  488.                             Butterfly.this.playSound(SoundEvents.BEE_POLLINATE, 1.0F, 1.0F);
  489.                         }
  490.                     }
  491.                 }
  492.             }
  493.         }
  494.  
  495.         private void setWantedPos() {
  496.             Butterfly.this.getMoveControl().setWantedPosition(this.hoverPos.x(), this.hoverPos.y(), this.hoverPos.z(), (double)0.35F);
  497.         }
  498.  
  499.         private float getOffset() {
  500.             return (Butterfly.this.random.nextFloat() * 2.0F - 1.0F) * 0.33333334F;
  501.         }
  502.  
  503.         private Optional<BlockPos> findNearbyFlower() {
  504.             return this.findNearestBlock(this.VALID_POLLINATION_BLOCKS, 5.0D);
  505.         }
  506.  
  507.         private Optional<BlockPos> findNearestBlock(Predicate<BlockState> predicate, double distance) {
  508.             BlockPos pos = Butterfly.this.blockPosition();
  509.             BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
  510.  
  511.             for (int i = 0; (double)i <= distance; i = i > 0 ? -i : 1 - i) {
  512.                 for (int j = 0; (double)j < distance; ++j) {
  513.                     for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) {
  514.                         for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) {
  515.                             mutablePos.setWithOffset(pos, k, i - 1, l);
  516.                            
  517.                             if (pos.closerThan(mutablePos, distance) && predicate.test(Butterfly.this.level.getBlockState(mutablePos))) {
  518.                                 return Optional.of(mutablePos);
  519.                             }
  520.                         }
  521.                     }
  522.                 }
  523.             }
  524.             return Optional.empty();
  525.         }
  526.     }
  527.  
  528.     private class WanderGoal extends Goal {
  529.  
  530.         WanderGoal() {
  531.             this.setFlags(EnumSet.of(Goal.Flag.MOVE));
  532.         }
  533.  
  534.         public boolean canUse() {
  535.             return Butterfly.this.navigation.isDone() && Butterfly.this.random.nextInt(10) == 0;
  536.         }
  537.  
  538.         public boolean canContinueToUse() {
  539.             return Butterfly.this.navigation.isInProgress();
  540.         }
  541.  
  542.         public void start() {
  543.             Vec3 vec3 = this.findPos();
  544.             if (vec3 != null) {
  545.                 Butterfly.this.navigation.moveTo(Butterfly.this.navigation.createPath(new BlockPos(vec3), 1), 1.0D);
  546.             }
  547.         }
  548.  
  549.         private Vec3 findPos() {
  550.             Vec3 vec3;
  551.             vec3 = Butterfly.this.getViewVector(0.0F);
  552.  
  553.             Vec3 vec32 = HoverRandomPos.getPos(Butterfly.this, 8, 7, vec3.x, vec3.z, ((float)Math.PI / 2F), 3, 1);
  554.             return vec32 != null ? vec32 : AirAndWaterRandomPos.getPos(Butterfly.this, 8, 4, -2, vec3.x, vec3.z, ((float)Math.PI / 2F));
  555.         }
  556.     }
  557.  
  558. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement