98 lines
3 KiB
Java
98 lines
3 KiB
Java
package net.minecraft.world.entity.ai.goal;
|
|
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.tags.FluidTags;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.entity.animal.Dolphin;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class DolphinJumpGoal extends JumpGoal {
|
|
private static final int[] STEPS_TO_CHECK = new int[]{0, 1, 4, 5, 6, 7};
|
|
private final Dolphin dolphin;
|
|
private final int interval;
|
|
private boolean breached;
|
|
|
|
public DolphinJumpGoal(Dolphin dolphin, int interval) {
|
|
this.dolphin = dolphin;
|
|
this.interval = reducedTickDelay(interval);
|
|
}
|
|
|
|
@Override
|
|
public boolean canUse() {
|
|
if (this.dolphin.getRandom().nextInt(this.interval) != 0) {
|
|
return false;
|
|
} else {
|
|
Direction direction = this.dolphin.getMotionDirection();
|
|
int i = direction.getStepX();
|
|
int j = direction.getStepZ();
|
|
BlockPos blockPos = this.dolphin.blockPosition();
|
|
|
|
for (int k : STEPS_TO_CHECK) {
|
|
if (!this.waterIsClear(blockPos, i, j, k) || !this.surfaceIsClear(blockPos, i, j, k)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private boolean waterIsClear(BlockPos pos, int dx, int dz, int scale) {
|
|
BlockPos blockPos = pos.offset(dx * scale, 0, dz * scale);
|
|
return this.dolphin.level().getFluidState(blockPos).is(FluidTags.WATER) && !this.dolphin.level().getBlockState(blockPos).blocksMotion();
|
|
}
|
|
|
|
private boolean surfaceIsClear(BlockPos pos, int dx, int dz, int scale) {
|
|
return this.dolphin.level().getBlockState(pos.offset(dx * scale, 1, dz * scale)).isAir()
|
|
&& this.dolphin.level().getBlockState(pos.offset(dx * scale, 2, dz * scale)).isAir();
|
|
}
|
|
|
|
@Override
|
|
public boolean canContinueToUse() {
|
|
double d = this.dolphin.getDeltaMovement().y;
|
|
return (!(d * d < 0.03F) || this.dolphin.getXRot() == 0.0F || !(Math.abs(this.dolphin.getXRot()) < 10.0F) || !this.dolphin.isInWater())
|
|
&& !this.dolphin.onGround();
|
|
}
|
|
|
|
@Override
|
|
public boolean isInterruptable() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void start() {
|
|
Direction direction = this.dolphin.getMotionDirection();
|
|
this.dolphin.setDeltaMovement(this.dolphin.getDeltaMovement().add(direction.getStepX() * 0.6, 0.7, direction.getStepZ() * 0.6));
|
|
this.dolphin.getNavigation().stop();
|
|
}
|
|
|
|
@Override
|
|
public void stop() {
|
|
this.dolphin.setXRot(0.0F);
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
boolean bl = this.breached;
|
|
if (!bl) {
|
|
FluidState fluidState = this.dolphin.level().getFluidState(this.dolphin.blockPosition());
|
|
this.breached = fluidState.is(FluidTags.WATER);
|
|
}
|
|
|
|
if (this.breached && !bl) {
|
|
this.dolphin.playSound(SoundEvents.DOLPHIN_JUMP, 1.0F, 1.0F);
|
|
}
|
|
|
|
Vec3 vec3 = this.dolphin.getDeltaMovement();
|
|
if (vec3.y * vec3.y < 0.03F && this.dolphin.getXRot() != 0.0F) {
|
|
this.dolphin.setXRot(Mth.rotLerp(0.2F, this.dolphin.getXRot(), 0.0F));
|
|
} else if (vec3.length() > 1.0E-5F) {
|
|
double d = vec3.horizontalDistance();
|
|
double e = Math.atan2(-vec3.y, d) * 180.0F / (float)Math.PI;
|
|
this.dolphin.setXRot((float)e);
|
|
}
|
|
}
|
|
}
|