package ru.galior.legacy.entity;
import java.util.Random;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EntitySize;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.Pose;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.ai.controller.MovementController;
import net.minecraft.entity.ai.goal.AvoidEntityGoal;
import net.minecraft.entity.ai.goal.PanicGoal;
import net.minecraft.entity.ai.goal.RandomSwimmingGoal;
import net.minecraft.entity.passive.WaterMobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.pathfinding.PathNavigator;
import net.minecraft.pathfinding.SwimmerPathNavigator;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.EntityPredicates;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
public abstract class AbstractFishEntity extends WaterMobEntity {
public AbstractFishEntity(EntityType<? extends AbstractFishEntity> type, World worldIn) {
super(type, worldIn);
this.moveController = new AbstractFishEntity.MoveHelperController(this);
}
protected float getStandingEyeHeight(Pose poseIn, EntitySize sizeIn) {
return sizeIn.height * 0.65F;
}
protected void registerAttributes() {
super.registerAttributes();
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(0.5D);
}
public static boolean func_223363_b(EntityType<? extends AbstractFishEntity> p_223363_0_, IWorld p_223363_1_, SpawnReason p_223363_2_, BlockPos p_223363_3_, Random p_223363_4_) {
return p_223363_1_.getBlockState(p_223363_3_).getBlock() == Blocks.WATER && p_223363_1_.getBlockState(p_223363_3_.up()).getBlock() == Blocks.WATER;
}
public int getMaxSpawnedInChunk() {
return 8;
}
protected void registerGoals() {
super.registerGoals();
this.goalSelector.addGoal(0, new PanicGoal(this, 1.25D));
this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, PlayerEntity.class, 8.0F, 1.6D, 1.4D, EntityPredicates.NOT_SPECTATING::test));
this.goalSelector.addGoal(4, new AbstractFishEntity.SwimGoal(this));
}
protected PathNavigator createNavigator(World worldIn) {
return new SwimmerPathNavigator(this, worldIn);
}
public void travel(Vec3d p_213352_1_) {
if (this.isServerWorld() && this.isInWater()) {
this.moveRelative(0.01F, 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 void livingTick() {
if (!this.isInWater() && this.onGround && this.collidedVertically) {
this.setMotion(this.getMotion().add((double)((this.rand.nextFloat() * 2.0F - 1.0F) * 0.05F), (double)0.4F, (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 0.05F)));
this.onGround = false;
this.isAirBorne = true;
this.playSound(this.getFlopSound(), this.getSoundVolume(), this.getSoundPitch());
}
super.livingTick();
}
protected boolean func_212800_dy() {
return true;
}
protected abstract SoundEvent getFlopSound();
protected SoundEvent getSwimSound() {
return SoundEvents.ENTITY_FISH_SWIM;
}
static class MoveHelperController extends MovementController {
private final AbstractFishEntity fish;
MoveHelperController(AbstractFishEntity fish) {
super(fish);
this.fish = fish;
}
public void tick() {
if (this.fish.areEyesInFluid(FluidTags.WATER)) {
this.fish.setMotion(this.fish.getMotion().add(0.0D, 0.005D, 0.0D));
}
if (this.action == MovementController.Action.MOVE_TO && !this.fish.getNavigator().noPath()) {
double d0 = this.posX - this.fish.posX;
double d1 = this.posY - this.fish.posY;
double d2 = this.posZ - this.fish.posZ;
double d3 = (double)MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d1 = d1 / d3;
float f = (float)(MathHelper.atan2(d2, d0) * (double)(180F / (float)Math.PI)) - 90.0F;
this.fish.rotationYaw = this.limitAngle(this.fish.rotationYaw, f, 90.0F);
this.fish.renderYawOffset = this.fish.rotationYaw;
float f1 = (float)(this.speed * this.fish.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getValue());
this.fish.setAIMoveSpeed(MathHelper.lerp(0.125F, this.fish.getAIMoveSpeed(), f1));
this.fish.setMotion(this.fish.getMotion().add(0.0D, (double)this.fish.getAIMoveSpeed() * d1 * 0.1D, 0.0D));
} else {
this.fish.setAIMoveSpeed(0.0F);
}
}
}
static class SwimGoal extends RandomSwimmingGoal {
private final AbstractFishEntity fish;
public SwimGoal(AbstractFishEntity fish) {
super(fish, 1.0D, 40);
this.fish = fish;
}
public boolean shouldExecute() {
return this.fish.func_212800_dy() && super.shouldExecute();
}
}
}