Jump to content

I wanna to make AI for my whale


OrcaWorld

Recommended Posts

Hello , everyone. OrcaWorld is here again. Today I comes with not a problem. I wanna to make a whale with very powerful AI , but I need help from you. I can make AI for mobs , but somewhere I need a help (for a example making whale swimming to warm ocean to born baby , and then return to frozen and etc). I'm waiting for you , with most of parts of whale's AI I'm already but I need to a lot of others tasks and your help.

Link to comment
Share on other sites

Well, you could start by showing us some of the code you tried.. Also, to start with the example you provided:

Quote

(for a example making whale swimming to warm ocean to born baby , and then return to frozen and etc

You see that there is a minecraft entity that has a behaviour very similar to what you need, and its the turtle entity. It has a home position which it remembers always, no matter how far the turtle goes, and will return to that position to lay eggs. Take a look at the code for the turtle entity and see if you can adapt it to your whale entity

Edited by Beethoven92

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Link to comment
Share on other sites

Yes , I'm finished my whales's AI. But for some reason it doesn't summoned. I'm tried spawn eggs and commands but it don't want to summon.

 

Here's code (I combined Wolf's , Cat's , Dolphin's , Turtle's and Horse's AI to make it):

 

package com.orca.whales;

import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.TurtleEggBlock;
import net.minecraft.entity.AgeableEntity;
import net.minecraft.entity.CreatureAttribute;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPredicate;
import net.minecraft.entity.EntitySize;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.IAngerable;
import net.minecraft.entity.IJumpingMount;
import net.minecraft.entity.ILivingEntityData;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MobEntity;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.Pose;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
import net.minecraft.entity.ai.attributes.Attributes;
import net.minecraft.entity.ai.controller.MovementController;
import net.minecraft.entity.ai.goal.BreatheAirGoal;
import net.minecraft.entity.ai.goal.BreedGoal;
import net.minecraft.entity.ai.goal.FindWaterGoal;
import net.minecraft.entity.ai.goal.FollowOwnerGoal;
import net.minecraft.entity.ai.goal.FollowParentGoal;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.goal.HurtByTargetGoal;
import net.minecraft.entity.ai.goal.LeapAtTargetGoal;
import net.minecraft.entity.ai.goal.LookAtGoal;
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.entity.ai.goal.MoveToBlockGoal;
import net.minecraft.entity.ai.goal.NearestAttackableTargetGoal;
import net.minecraft.entity.ai.goal.OwnerHurtByTargetGoal;
import net.minecraft.entity.ai.goal.OwnerHurtTargetGoal;
import net.minecraft.entity.ai.goal.RandomSwimmingGoal;
import net.minecraft.entity.ai.goal.ResetAngerGoal;
import net.minecraft.entity.ai.goal.SitGoal;
import net.minecraft.entity.item.ExperienceOrbEntity;
import net.minecraft.entity.monster.CreeperEntity;
import net.minecraft.entity.monster.GhastEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.passive.FoxEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.IInventoryChangedListener;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.pathfinding.PathNavigator;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.pathfinding.SwimmerPathNavigator;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.HandSide;
import net.minecraft.util.RangedInteger;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.TickRangeConverter;
import net.minecraft.util.TransportationHelper;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.GameRules;
import net.minecraft.world.IServerWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.wrapper.InvWrapper;

import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import java.util.function.Predicate;

public class WhaleEntity extends TameableEntity implements IAngerable, IInventoryChangedListener, IJumpingMount {
    private static final Ingredient BREEDING_ITEMS = Ingredient.fromItems(Items.TROPICAL_FISH, Items.SALMON);
    private static final DataParameter<Integer> field_234232_bz_ = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.VARINT);
    private static final EntityPredicate field_213810_bA = (new EntityPredicate()).setDistance(10.0D).allowFriendlyFire().allowInvulnerable().setLineOfSiteRequired();
    private static final Predicate<LivingEntity> IS_WHALE_BREEDING = (p_213617_0_) -> {
        return p_213617_0_ instanceof WhaleEntity && ((WhaleEntity) p_213617_0_).isBreeding();
    };

    private static final EntityPredicate MOMMY_TARGETING = (new EntityPredicate()).setDistance(16.0D).allowInvulnerable().allowFriendlyFire().setLineOfSiteRequired().setCustomPredicate(IS_WHALE_BREEDING);
    private static final DataParameter<BlockPos> HOME_POS = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BLOCK_POS);
    private static final DataParameter<BlockPos> TRAVEL_POS = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BLOCK_POS);
    private static final DataParameter<Boolean> IS_BORNING = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BOOLEAN);
    private static final DataParameter<Boolean> GOING_HOME = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BOOLEAN);
    private static final DataParameter<Boolean> TRAVELLING = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BOOLEAN);
    protected static final DataParameter<Byte> TAMED = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BYTE);
    protected static final DataParameter<Optional<UUID>> OWNER_UNIQUE_ID = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.OPTIONAL_UNIQUE_ID);
    private static final RangedInteger field_234230_bG_ = TickRangeConverter.func_233037_a_(20, 39);
    private static final DataParameter<Byte> STATUS = EntityDataManager.createKey(AbstractHorseEntity.class, DataSerializers.BYTE);
    private static final DataParameter<Boolean> HAS_BABY = EntityDataManager.createKey(WhaleEntity.class, DataSerializers.BOOLEAN);
    protected boolean whaleJumping;
    private int isBorning;
    protected int temper;
    protected int gallopTime;
    protected Inventory whaleChest;
    protected float jumpPower;
    private float rearingAmount;
    private boolean allowStandSliding;
    private UUID field_234231_bH_;
    private boolean field_233683_bw_;
    public static final Predicate<LivingEntity> TARGET_DRY_BABY = (p_213616_0_) -> {
        return p_213616_0_.isChild() && !p_213616_0_.isInWater();
    };

    public WhaleEntity(EntityType<? extends WhaleEntity> type, World worldIn) {
        super(type, worldIn);
        this.setPathPriority(PathNodeType.WATER, 0.0F);
        this.moveController = new WhaleEntity.MoveHelperController(this);
        this.stepHeight = 1.0F;
        this.initWhaleChest();
        this.setTamed(false);
    }

    private void initWhaleChest() {
        Inventory inventory = this.whaleChest;
        this.whaleChest = new Inventory(this.getInventorySize());
        if (inventory != null) {
            inventory.removeListener(this);
            int i = Math.min(inventory.getSizeInventory(), this.whaleChest.getSizeInventory());

            for(int j = 0; j < i; ++j) {
                ItemStack itemstack = inventory.getStackInSlot(j);
                if (!itemstack.isEmpty()) {
                    this.whaleChest.setInventorySlotContents(j, itemstack.copy());
                }
            }
        }

        this.whaleChest.addListener(this);
        this.func_230275_fc_();
        this.itemHandler = LazyOptional.of(() -> new InvWrapper(this.whaleChest));
    }

    protected void func_230275_fc_() {
        if (!this.world.isRemote) {
            this.setWhaleWatchableBoolean(4, !this.whaleChest.getStackInSlot(0).isEmpty());
        }
    }

    public void setHome(BlockPos position) {
        this.dataManager.set(HOME_POS, position);
    }

    private BlockPos getHome() {
        return this.dataManager.get(HOME_POS);
    }

    private void setTravelPos(BlockPos position) {
        this.dataManager.set(TRAVEL_POS, position);
    }

    private BlockPos getTravelPos() {
        return this.dataManager.get(TRAVEL_POS);
    }

    public boolean hasBaby() {
        return this.dataManager.get(HAS_BABY);
    }

    private void setHasBaby(boolean hasBaby) {
        this.dataManager.set(HAS_BABY, hasBaby);
    }

    public boolean isBorning() {
        return this.dataManager.get(IS_BORNING);
    }

    private void setBorning(boolean isBorning) {
        this.isBorning = isBorning ? 1 : 0;
        this.dataManager.set(IS_BORNING, isBorning);
    }

    protected void registerGoals() {
        this.goalSelector.addGoal(0, new BreatheAirGoal(this));
        this.goalSelector.addGoal(0, new FindWaterGoal(this));
        this.goalSelector.addGoal(1, new WhaleEntity.BornBabyGoal(this, 1.0D));
        this.goalSelector.addGoal(1, new WhaleEntity.MateGoal(this, 1.0D));
        this.goalSelector.addGoal(2, new SitGoal(this));
        this.goalSelector.addGoal(2, new WhaleEntity.SwimWithPlayerGoal(this, 4.0D));
        this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F));
        this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.0D));
        this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true));
        this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false));
        this.goalSelector.addGoal(7, new BreedGoal(this, 1.0D));
        this.goalSelector.addGoal(10, new LookAtGoal(this, PlayerEntity.class, 8.0F));
        this.goalSelector.addGoal(10, new RandomSwimmingGoal(this, 1.0D, 10));
        this.targetSelector.addGoal(1, new OwnerHurtByTargetGoal(this));
        this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this));
        this.targetSelector.addGoal(3, (new HurtByTargetGoal(this)).setCallsForHelp());
        this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, FoxEntity.class, false));
        this.targetSelector.addGoal(8, new ResetAngerGoal<>(this, true));
    }

    public static AttributeModifierMap.MutableAttribute func_234233_eS_() {
        return MobEntity.func_233666_p_().func_233815_a_(Attributes.field_233821_d_, (double)0.3F).func_233815_a_(Attributes.field_233818_a_, 200.0D).func_233815_a_(Attributes.field_233823_f_, 19.0D);
    }

    /**
     * Returns new PathNavigateGround instance
     */
    protected PathNavigator createNavigator(World worldIn) {
        return new SwimmerPathNavigator(this, worldIn);
    }

    public int getMaxAir() {
        return 4800;
    }

    public int getMaxTemper() {
        return 100;    
    }

    protected int determineNextAir(int currentAir) {
        return this.getMaxAir();
    }

    protected float getStandingEyeHeight(Pose poseIn, EntitySize sizeIn) {
        return 0.95F;
    }

    /**
     * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
     * use in wolves.
     */
    public int getVerticalFaceSpeed() {
        return 1;
    }

    public int getHorizontalFaceSpeed() {
        return 1;
    }

    protected void registerData() {
        super.registerData();
        this.dataManager.register(HOME_POS, BlockPos.ZERO);
        this.dataManager.register(HAS_BABY, false);
        this.dataManager.register(TRAVEL_POS, BlockPos.ZERO);
        this.dataManager.register(GOING_HOME, false);
        this.dataManager.register(TRAVELLING, false);
        this.dataManager.register(IS_BORNING, false);
        this.dataManager.register(TAMED, (byte)0);
        this.dataManager.register(STATUS, (byte)0);
        this.dataManager.register(OWNER_UNIQUE_ID, Optional.empty());
        this.dataManager.register(field_234232_bz_, 0);
    }

    protected boolean getWhaleWatchableBoolean(int p_110233_1_) {
        return (this.dataManager.get(STATUS) & p_110233_1_) != 0;
    }

    protected void setWhaleWatchableBoolean(int p_110208_1_, boolean p_110208_2_) {
        byte b0 = this.dataManager.get(STATUS);
        if (p_110208_2_) {
            this.dataManager.set(STATUS, (byte)(b0 | p_110208_1_));
        } else {
            this.dataManager.set(STATUS, (byte)(b0 & ~p_110208_1_));
        }
    }

    protected void playStepSound(BlockPos pos, BlockState blockIn) {
        this.playSound(SoundEvents.ENTITY_WOLF_STEP, 0.15F, 1.0F);
    }

    public void writeAdditional(CompoundNBT compound) {
        super.writeAdditional(compound);
        compound.putBoolean("Bred", this.isBreeding());
        compound.putInt("HomePosX", this.getHome().getX());
        compound.putInt("HomePosY", this.getHome().getY());
        compound.putInt("HomePosZ", this.getHome().getZ());
        compound.putInt("TravelPosX", this.getTravelPos().getX());
        compound.putInt("TravelPosY", this.getTravelPos().getY());
        compound.putInt("TravelPosZ", this.getTravelPos().getZ());
    }

    /**
     * (abstract) Protected helper method to read subclass entity data from NBT.
     */
    public void readAdditional(CompoundNBT compound) {
        int i = compound.getInt("HomePosX");
        int j = compound.getInt("HomePosY");
        int k = compound.getInt("HomePosZ");
        this.setHome(new BlockPos(i, j, k));
        super.readAdditional(compound);
        int l = compound.getInt("TravelPosX");
        int i1 = compound.getInt("TravelPosY");
        int j1 = compound.getInt("TravelPosZ");
        this.setTravelPos(new BlockPos(l, i1, j1));
    }

    @Nullable
    public ILivingEntityData onInitialSpawn(IServerWorld worldIn, DifficultyInstance difficultyIn, SpawnReason reason, @Nullable ILivingEntityData spawnDataIn, @Nullable CompoundNBT dataTag) {
        this.setAir(this.getMaxAir());
        this.rotationPitch = 0.0F;
        return super.onInitialSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag);
    }

    private net.minecraftforge.common.util.LazyOptional<?> itemHandler = null;

    @Override
    public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.Direction facing) {
        if (this.isAlive() && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && itemHandler != null)
            return itemHandler.cast();
        return super.getCapability(capability, facing);
    }

    @Override
    public void remove(boolean keepData) {
        super.remove(keepData);
        if (!keepData && itemHandler != null) {
            itemHandler.invalidate();
            itemHandler = null;
        }
    }

    public boolean isPushedByWater() {
        return false;
    }

    public boolean canBreatheUnderwater() {
        return false;
    }

    protected void updateAir(int p_209207_1_) {
    }

    public CreatureAttribute getCreatureAttribute() {
        return CreatureAttribute.WATER;
    }

    /**
     * Get number of ticks, at least during which the living entity will be silent.
     */
    public int getTalkInterval() {
        return 200;
    }

    @Nullable
    protected SoundEvent getAmbientSound() {
        return !this.isInWater() && this.onGround && !this.isChild() ? SoundEvents.ENTITY_DOLPHIN_AMBIENT : super.getAmbientSound();
    }

    protected void playSwimSound(float volume) {
        super.playSwimSound(volume * 1.5F);
    }

    protected SoundEvent getSwimSound() {
        return SoundEvents.ENTITY_DOLPHIN_SWIM;
    }

    @Nullable
    protected SoundEvent getHurtSound(DamageSource damageSourceIn) {
       return SoundEvents.ENTITY_DOLPHIN_HURT;
    }

    @Nullable
    protected SoundEvent getDeathSound() {
        return SoundEvents.ENTITY_DOLPHIN_DEATH;
    }

    protected SoundEvent getSplashSound() {
        return SoundEvents.ENTITY_DOLPHIN_SPLASH;
    }

    protected boolean closeToTarget() {
        BlockPos blockpos = this.getNavigator().getTargetPos();
        return blockpos != null ? blockpos.withinDistance(this.getPositionVec(), 12.0D) : false;
    }

    public void travel(Vector3d p_213352_1_) {
        if (this.isServerWorld() && this.isInWater()) {
            this.moveRelative(this.getAIMoveSpeed(), p_213352_1_);
            this.move(MoverType.SELF, this.getMotion());
            this.setMotion(this.getMotion().scale(0.9D));
            if (this.getAttackTarget() == null) {
                this.setMotion(this.getMotion().add(0.0D, -0.005D, 0.0D));
            }
        } else {
            super.travel(p_213352_1_);
        }
    }

    public boolean canBeLeashedTo(PlayerEntity player) {
        return true;
    }

    @Override
    public void setJumpPower(int jumpPowerIn) {

    }

    @Override
    public boolean canJump() {
        return false;
    }

    @Override
    public void handleStartJump(int p_184775_1_) {

    }

    @Override
    public void handleStopJump() {

    }

    @Override
    public void onInventoryChanged(IInventory invBasic) {
    }

    /**
     * Called when the entity is attacked.
     */
    public boolean attackEntityFrom(DamageSource source, float amount) {
        if (this.isInvulnerableTo(source)) {
            return false;
        } else {
            Entity entity = source.getTrueSource();
            this.func_233687_w_(false);
            if (entity != null && !(entity instanceof PlayerEntity) && !(entity instanceof AbstractArrowEntity)) {
                amount = (amount + 1.0F) / 2.0F;
            }

            return super.attackEntityFrom(source, amount);
        }
    }

    public boolean attackEntityAsMob(Entity entityIn) {
        boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), (float)((int)this.func_233637_b_(Attributes.field_233823_f_)));
        if (flag) {
            this.applyEnchantments(this, entityIn);
        }

        return flag;
    }

    public void setTamed(boolean tamed) {
        super.setTamed(tamed);
        if (tamed) {
            this.getAttribute(Attributes.field_233818_a_).setBaseValue(300.0D);
        } else {
            this.getAttribute(Attributes.field_233818_a_).setBaseValue(250.0D);
        }

        this.getAttribute(Attributes.field_233823_f_).setBaseValue(20.0D);
    }

    public ActionResultType func_230254_b_(PlayerEntity p_230254_1_, Hand p_230254_2_) {
        ItemStack itemstack = p_230254_1_.getHeldItem(p_230254_2_);
        Item item = itemstack.getItem();
        if (this.world.isRemote) {
            boolean flag = this.isOwner(p_230254_1_) || this.isTamed() || item == Items.COD && !this.isTamed() && !this.func_233678_J__();
            return flag ? ActionResultType.CONSUME : ActionResultType.PASS;
        } else {
            if (this.isTamed()) {
                if (this.isBreedingItem(itemstack) && this.getHealth() < this.getMaxHealth()) {
                    if (!p_230254_1_.abilities.isCreativeMode) {
                        itemstack.shrink(1);
                    }

                    this.heal((float)item.getFood().getHealing());
                    return ActionResultType.SUCCESS;
                }
            } else if (item == Items.COD && !this.func_233678_J__()) {
                if (!p_230254_1_.abilities.isCreativeMode) {
                    itemstack.shrink(1);
                }

                if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, p_230254_1_)) {
                    this.setTamedBy(p_230254_1_);
                    this.navigator.clearPath();
                    this.setAttackTarget((LivingEntity)null);
                    this.func_233687_w_(true);
                    this.world.setEntityState(this, (byte)7);
                } else {
                    this.world.setEntityState(this, (byte)6);
                }

                return ActionResultType.SUCCESS;
            }

            return super.func_230254_b_(p_230254_1_, p_230254_2_);
        }
    }

    public boolean isTame() {
        return this.getWhaleWatchableBoolean(2);
    }

    @Nullable
    public UUID getOwnerUniqueId() {
        return this.dataManager.get(OWNER_UNIQUE_ID).orElse((UUID)null);
    }

    public void setOwnerUniqueId(@Nullable UUID uniqueId) {
        this.dataManager.set(OWNER_UNIQUE_ID, Optional.ofNullable(uniqueId));

    }

    protected int getInventorySize() {
        return 2;
    }

    /**
     * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
     * the animal type)
     */
    public boolean isBreedingItem(ItemStack stack) {
        return BREEDING_ITEMS.test(stack);
    }

    /**
     * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
     * use this to react to sunlight and start to burn.
     */
    public void livingTick() {
        super.livingTick();
        if (this.isAlive() && this.isBorning() && this.isBorning >= 1 && this.isBorning % 5 == 0) {
            BlockPos blockpos = this.func_233580_cy_();
            if (WhaleEntity.hasProperHabitat(this.world, blockpos)) {
                this.world.playEvent(2001, blockpos, Block.getStateId(Blocks.SAND.getDefaultState()));
            }
        }
        
    }

    private static boolean hasProperHabitat(World world, BlockPos blockpos) {
        return true;
    }

    public boolean isEatingHaystack() {
        return this.getWhaleWatchableBoolean(16);
    }

    public boolean isBreeding() {
        return this.getWhaleWatchableBoolean(8);
    }

    public void setBreeding(boolean breeding) {
        this.setWhaleWatchableBoolean(8, breeding);
    }

    public boolean func_230264_L__() {
        return this.isAlive() && !this.isChild() && this.isTame();
    }

    public void func_230266_a_(@Nullable SoundCategory p_230266_1_) {
        this.whaleChest.setInventorySlotContents(0, new ItemStack(Items.SADDLE));
        if (p_230266_1_ != null) {
            this.world.playMovingSound((PlayerEntity)null, this, SoundEvents.ENTITY_HORSE_SADDLE, p_230266_1_, 0.5F, 1.0F);
        }

    }

    public double getWhaleJumpStrength() {
        return this.func_233637_b_(Attributes.field_233830_m_);

    }

    public boolean isWhaleSaddled() {
        return this.getWhaleWatchableBoolean(4);
    }

    public int getTemper() {
        return this.temper;
    }

    public void setTemper(int temperIn) {
        this.temper = temperIn;
    }

    public int increaseTemper(int p_110198_1_) {
        int i = MathHelper.clamp(this.getTemper() + p_110198_1_, 0, this.getMaxTemper());
        this.setTemper(i);
        return i;
    }

    public boolean isWhaleJumping() {
        return this.whaleJumping;
    }

    public void setWhaleTamed(boolean tamed) {
        this.setWhaleWatchableBoolean(2, tamed);
    }

    public void setWhaleJumping(boolean jumping) {
        this.whaleJumping = jumping;
    }

    public boolean isRearing() {
        return this.getWhaleWatchableBoolean(32);
    }

    public int func_230256_F__() {
        return this.dataManager.get(field_234232_bz_);
    }

    public void func_230260_a__(int p_230260_1_) {
        this.dataManager.set(field_234232_bz_, p_230260_1_);
    }

    public void func_230258_H__() {
        this.func_230260_a__(field_234230_bG_.func_233018_a_(this.rand));
    }

    @Nullable
    public UUID func_230257_G__() {
        return this.field_234231_bH_;
    }

    public void func_230259_a_(@Nullable UUID p_230259_1_) {
        this.field_234231_bH_ = p_230259_1_;
    }

    public boolean canBreed() {
        return super.canBreed() && !this.hasBaby();
    }

    public WhaleEntity func_241840_a(ServerWorld p_241840_1_, AgeableEntity p_241840_2_) {
        WhaleEntity whaleentity = EntityInit.WHALE.get().create(p_241840_1_);
        UUID uuid = this.getOwnerId();
        if (uuid != null) {
            whaleentity.setOwnerId(uuid);
            whaleentity.setTamed(true);
        }

        return whaleentity;
    }

    /**
     * For vehicles, the first passenger is generally considered the controller and "drives" the vehicle. For example,
     * Pigs, Horses, and Boats are generally "steered" by the controlling passenger.
     */
    @Nullable
    public Entity getControllingPassenger() {
        return this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
    }

    @Nullable
    private Vector3d func_234236_a_(Vector3d p_234236_1_, LivingEntity p_234236_2_) {
        double d0 = this.getPosX() + p_234236_1_.x;
        double d1 = this.getBoundingBox().minY;
        double d2 = this.getPosZ() + p_234236_1_.z;
        BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();

        for(Pose pose : p_234236_2_.func_230297_ef_()) {
            blockpos$mutable.setPos(d0, d1, d2);
            double d3 = this.getBoundingBox().maxY + 0.75D;

            while(true) {
                double d4 = this.world.func_242403_h(blockpos$mutable);
                if ((double)blockpos$mutable.getY() + d4 > d3) {
                    break;
                }

                if (TransportationHelper.func_234630_a_(d4)) {
                    AxisAlignedBB axisalignedbb = p_234236_2_.func_233648_f_(pose);
                    Vector3d vector3d = new Vector3d(d0, (double)blockpos$mutable.getY() + d4, d2);
                    if (TransportationHelper.func_234631_a_(this.world, p_234236_2_, axisalignedbb.offset(vector3d))) {
                        p_234236_2_.setPose(pose);
                        return vector3d;
                    }
                }

                blockpos$mutable.move(Direction.UP);
                if (!((double)blockpos$mutable.getY() < d3)) {
                    break;
                }
            }
        }

        return null;
    }

    public Vector3d func_230268_c_(LivingEntity p_230268_1_) {
        Vector3d vector3d = func_233559_a_((double)this.getWidth(), (double)p_230268_1_.getWidth(), this.rotationYaw + (p_230268_1_.getPrimaryHand() == HandSide.RIGHT ? 90.0F : -90.0F));
        Vector3d vector3d1 = this.func_234236_a_(vector3d, p_230268_1_);
        if (vector3d1 != null) {
            return vector3d1;
        } else {
            Vector3d vector3d2 = func_233559_a_((double)this.getWidth(), (double)p_230268_1_.getWidth(), this.rotationYaw + (p_230268_1_.getPrimaryHand() == HandSide.LEFT ? 90.0F : -90.0F));
            Vector3d vector3d3 = this.func_234236_a_(vector3d2, p_230268_1_);
            return vector3d3 != null ? vector3d3 : this.getPositionVec();
        }
    }

    protected void func_230273_eI_() {
    }

    /**
     * Returns true if the mob is currently able to mate with the specified mob.
     */
    public boolean canMateWith(AnimalEntity otherAnimal) {
        if (otherAnimal == this) {
            return false;
        } else if (!this.isTamed()) {
            return false;
        } else if (!(otherAnimal instanceof WhaleEntity)) {
            return false;
        } else {
            WhaleEntity whaleentity = (WhaleEntity)otherAnimal;
            if (!whaleentity.isTamed()) {
                return false;
            } else if (whaleentity.func_233684_eK_()) {
                return false;
            } else {
                return this.isInLove() && whaleentity.isInLove();
            }
        }
    }

    public boolean shouldAttackEntity(LivingEntity target, LivingEntity owner) {
        if (!(target instanceof CreeperEntity) && !(target instanceof GhastEntity)) {
            if (target instanceof WhaleEntity) {
                WhaleEntity whaleentity = (WhaleEntity)target;
                return !whaleentity.isTamed() || whaleentity.getOwner() != owner;
            } else if (target instanceof PlayerEntity && owner instanceof PlayerEntity && !((PlayerEntity)owner).canAttackPlayer((PlayerEntity)target)) {
                return false;
            } else if (target instanceof AbstractHorseEntity && ((AbstractHorseEntity)target).isTame()) {
                return false;
            } else {
                return !(target instanceof TameableEntity) || !((TameableEntity)target).isTamed();
            }
        } else {
            return false;
        }
    }

    protected void followMother() {
        if (this.isBreeding() && this.isChild() && !this.isEatingHaystack()) {
            LivingEntity livingentity = this.world.getClosestEntityWithinAABB(WhaleEntity.class, MOMMY_TARGETING, this, this.getPosX(), this.getPosY(), this.getPosZ(), this.getBoundingBox().grow(16.0D));
            if (livingentity != null && this.getDistanceSq(livingentity) > 4.0D) {
                this.navigator.getPathToEntity(livingentity, 0);
            }
        }
    }

    @OnlyIn(Dist.CLIENT)
    public Vector3d func_241205_ce_() {
        return new Vector3d(0.0D, (double)(2.0F * this.getEyeHeight()), (double)(this.getWidth() * 4.0F));
    }

    static class MoveHelperController extends MovementController {
        private final WhaleEntity whale;

        public MoveHelperController(WhaleEntity whaleIn) {
            super(whaleIn);
            this.whale = whaleIn;
        }

        public void tick() {
            if (this.whale.isInWater()) {
                this.whale.setMotion(this.whale.getMotion().add(0.0D, 0.005D, 0.0D));
            }

            if (this.action == Action.MOVE_TO && !this.whale.getNavigator().noPath()) {
                double d0 = this.posX - this.whale.getPosX();
                double d1 = this.posY - this.whale.getPosY();
                double d2 = this.posZ - this.whale.getPosZ();
                double d3 = d0 * d0 + d1 * d1 + d2 * d2;
                if (d3 < (double) 2.5000003E-7F) {
                    this.mob.setMoveForward(0.0F);
                } else {
                    float f = (float) (MathHelper.atan2(d2, d0) * (double) (180F / (float) Math.PI)) - 90.0F;
                    this.whale.rotationYaw = this.limitAngle(this.whale.rotationYaw, f, 10.0F);
                    this.whale.renderYawOffset = this.whale.rotationYaw;
                    this.whale.rotationYawHead = this.whale.rotationYaw;
                    float f1 = (float) (this.speed * this.whale.func_233637_b_(Attributes.field_233821_d_));
                    if (this.whale.isInWater()) {
                        this.whale.setAIMoveSpeed(f1 * 0.02F);
                        float f2 = -((float) (MathHelper.atan2(d1, (double) MathHelper.sqrt(d0 * d0 + d2 * d2)) * (double) (180F / (float) Math.PI)));
                        f2 = MathHelper.clamp(MathHelper.wrapDegrees(f2), -85.0F, 85.0F);
                        this.whale.rotationPitch = this.limitAngle(this.whale.rotationPitch, f2, 5.0F);
                        float f3 = MathHelper.cos(this.whale.rotationPitch * ((float) Math.PI / 180F));
                        float f4 = MathHelper.sin(this.whale.rotationPitch * ((float) Math.PI / 180F));
                        this.whale.moveForward = f3 * f1;
                        this.whale.moveVertical = -f4 * f1;
                    } else {
                        this.whale.setAIMoveSpeed(f1 * 0.1F);
                    }

                }
            } else {
                this.whale.setAIMoveSpeed(0.0F);
                this.whale.setMoveStrafing(0.0F);
                this.whale.setMoveVertical(0.0F);
                this.whale.setMoveForward(0.0F);
            }
        }
    }

    static class SwimWithPlayerGoal extends Goal {
        private final WhaleEntity whale;
        private final double speed;
        private PlayerEntity targetPlayer;

        SwimWithPlayerGoal(WhaleEntity whaleIn, double speedIn) {
            this.whale = whaleIn;
            this.speed = speedIn;
            this.setMutexFlags(EnumSet.of(Flag.MOVE, Flag.LOOK));
        }

        /**
         * Returns whether execution should begin. You can also read and cache any state necessary for execution in this
         * method as well.
         */
        public boolean shouldExecute() {
            this.targetPlayer = this.whale.world.getClosestPlayer(WhaleEntity.field_213810_bA, this.whale);
            if (this.targetPlayer == null) {
                return false;
            } else {
                return this.targetPlayer.isSwimming() && this.whale.getAttackTarget() != this.targetPlayer;
            }
        }

        /**
         * Returns whether an in-progress EntityAIBase should continue executing
         */
        public boolean shouldContinueExecuting() {
            return this.targetPlayer != null && this.targetPlayer.isSwimming() && this.whale.getDistanceSq(this.targetPlayer) < 256.0D;
        }

        /**
         * Execute a one shot task or start executing a continuous task
         */
        public void startExecuting() {
            this.targetPlayer.addPotionEffect(new EffectInstance(Effects.DOLPHINS_GRACE, 100));
        }

        /**
         * Reset the task's internal state. Called when this task is interrupted by another one
         */
        public void resetTask() {
            this.targetPlayer = null;
            this.whale.getNavigator().clearPath();
        }

        /**
         * Keep ticking a continuous task that has already been started
         */
        public void tick() {
            this.whale.getLookController().setLookPositionWithEntity(this.targetPlayer, (float) (this.whale.getHorizontalFaceSpeed() + 20), (float) this.whale.getVerticalFaceSpeed());
            if (this.whale.getDistanceSq(this.targetPlayer) < 6.25D) {
                this.whale.getNavigator().clearPath();
            } else {
                this.whale.getNavigator().tryMoveToEntityLiving(this.targetPlayer, this.speed);
            }

            if (this.targetPlayer.isSwimming() && this.targetPlayer.world.rand.nextInt(6) == 0) {
                this.targetPlayer.addPotionEffect(new EffectInstance(Effects.DOLPHINS_GRACE, 100));
            }
        }
    }

    public class BornBabyGoal extends MoveToBlockGoal {
        private final WhaleEntity whale;

        BornBabyGoal(WhaleEntity whaleentity, double speedIn) {
            super(whaleentity, speedIn, 16);
            this.whale = whaleentity;
        }

        /**
         * Returns whether execution should begin. You can also read and cache any state necessary for execution in this
         * method as well.
         */
        public boolean shouldExecute() {
            return this.whale.hasBaby() && this.whale.getHome().withinDistance(this.whale.getPositionVec(), 9.0D) ? super.shouldExecute() : false;
        }

        /**
         * Returns whether an in-progress EntityAIBase should continue executing
         */
        public boolean shouldContinueExecuting() {
            return super.shouldContinueExecuting() && this.whale.hasBaby() && this.whale.getHome().withinDistance(this.whale.getPositionVec(), 9.0D);
        }

        /**
         * Keep ticking a continuous task that has already been started
         */
        public void tick() {
            super.tick();
            BlockPos blockpos = this.whale.func_233580_cy_();
            if (!this.whale.isInWater() && this.getIsAboveDestination()) {
                if (this.whale.isBorning < 1) {
                    this.whale.setBorning(true);
                } else if (this.whale.isBorning > 200) {
                    World world = this.whale.world;
                    world.playSound((PlayerEntity) null, blockpos, SoundEvents.ENTITY_TURTLE_LAY_EGG, SoundCategory.BLOCKS, 0.3F, 0.9F + world.rand.nextFloat() * 0.2F);
                    world.setBlockState(this.destinationBlock.up(), Blocks.TURTLE_EGG.getDefaultState().with(TurtleEggBlock.EGGS, Integer.valueOf(this.whale.rand.nextInt(4) + 1)), 3);
                    this.whale.setHasBaby(false);
                    this.whale.setBorning(false);
                    this.whale.setInLove(600);
                }

                if (this.whale.isBorning()) {
                    this.whale.isBorning++;
                }
            }
        }

        @Override
        protected boolean shouldMoveTo(IWorldReader worldIn, BlockPos pos) {
            return !worldIn.isAirBlock(pos.up()) ? false : WhaleEntity.func_241473_b_(worldIn, pos);
        }
    }

    private static boolean func_241473_b_(IWorldReader worldIn, BlockPos pos) {
        return true;
    }

    static class MateGoal extends BreedGoal {
        private final WhaleEntity whale;

        MateGoal(WhaleEntity whale, double speedIn) {
            super(whale, speedIn);
            this.whale = whale;
        }

        /**
         * Returns whether execution should begin. You can also read and cache any state necessary for execution in this
         * method as well.
         */
        public boolean shouldExecute() {
            return super.shouldExecute() && !this.whale.hasBaby();
        }

        /**
         * Spawns a baby animal of the same type.
         */
        protected void spawnBaby() {
            ServerPlayerEntity serverplayerentity = this.animal.getLoveCause();
            if (serverplayerentity == null && this.targetMate.getLoveCause() != null) {
                serverplayerentity = this.targetMate.getLoveCause();
            }

            if (serverplayerentity != null) {
                serverplayerentity.addStat(Stats.ANIMALS_BRED);
                CriteriaTriggers.BRED_ANIMALS.trigger(serverplayerentity, this.animal, this.targetMate, (AgeableEntity)null);
            }

            this.whale.setHasBaby(true);
            this.animal.resetInLove();
            this.targetMate.resetInLove();
            Random random = this.animal.getRNG();
            if (this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
                this.world.addEntity(new ExperienceOrbEntity(this.world, this.animal.getPosX(), this.animal.getPosY(), this.animal.getPosZ(), random.nextInt(7) + 1));
            }
        }
    }
}

I think that main reason can be that I placed some behaviours in wrong places.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.