MotionControllerDive class

Пакет: com.hypixel.hytale.server.npc.movement.controllers

Файл: com/hypixel/hytale/server/npc/movement/controllers/MotionControllerDive.java

extends: MotionControllerBase

Поля (64)

МодификаторыТипИмя
final String TYPE
var1
float var10
var10
var10
double var11
var11
var11
double var11
double var11
var11
double var11
var11
TransformComponent var13
boolean var13
double var13
double var14
MotionControllerBase.AppliedVelocity var15
float var17
float var18
var18
var18
var18
float var19
var19
var19
var19
float var2
boolean var20
double var20
var20
var20
float var21
var21
var21
float var22
var22
double var27
double var28
Velocity var29
double var3
double var3
double var30
var30
double var32
boolean var4
double var5
var5
var5
Predicate var5
Vector3d var6
double var7
boolean var7
Vector3d var7
Vector3d var8
BlockCollisionData var8
BlockCollisionData var8
double var9
float var9
var9
var9
double var9
var9
double var9

Методы (39)

МодификаторыВозвратСигнатура
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Invalid position")
private void applyActiveProbeBlockCollisionFiltervoid applyActiveProbeBlockCollisionFilter()
public double bisectdouble bisect(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3d var2, double var3, @Nonnull Vector3d var5, double var6, @Nonnull Vector3d var8, @Nonnull ComponentAccessor<EntityStore> var9)
public double bisectdouble bisect(@Nonnull Ref<EntityStore> var1, @Nonnull Vector3d var2, @Nonnull Vector3d var3, @Nonnull Vector3d var4, @Nonnull ComponentAccessor<EntityStore> var5)
private void computeTranslationvoid computeTranslation(@Nonnull Vector3d var1, double var2, float var4, double var5, double var7)
abstract for for(int var14 = 0; var14 < this.appliedVelocities.size()
public double getDampingDecelerationdouble getDampingDeceleration()
if if(var11 > var5)
if if(this.collisionWithSolid)
if if(!var20)
if if(this.debugModeSteer)
if if(var13)
if if(var15.velocity.y + this.externalVelocity.y <= 0.0 || var15.velocity.y < 0.0)
if if(var13 && var15.canClear)
if if(this.debugModeBlockCollisions)
if if(this.debugModeBlockCollisions)
if if(this.debugModeCollisions)
if if(var8 == null)
if if(this.debugModeMove)
if if(var4)
if if(var4)
if if(this.debugModeMove)
if if(this.debugModeCollisions)
if if(var8 == null)
if if(this.debugModeMove)
if if(this.debugModeMove)
if if(var4)
if if(this.debugModeMove)
if if(this.debugModeMove)
if if(var4)
if if(var4)
if if(this.debugModeMove)
if if(this.activeProbeBlockCollisionFilter != null)
if if(var2 == null)
private boolean isNearZeroboolean isNearZero(float var1)
static double relativeSwimDepthToBoundingBoxdouble relativeSwimDepthToBoundingBox(double var0, @Nullable Box var2, float var3)
static double relativeSwimDepthToHeightdouble relativeSwimDepthToHeight(double var0, @Nullable Box var2, float var3)
static double relativeSwimDepthToHeightdouble relativeSwimDepthToHeight(@Nullable Ref<EntityStore> var0, double var1, Model var3, Box var4, @Nullable ComponentAccessor<EntityStore> var5)
abstract super super(var1, var2)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.npc.movement.controllers;

class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.shape.Box;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3dUtil;
class="kw">import com.hypixel.hytale.protocol.BlockMaterial;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.Model;
class="kw">import com.hypixel.hytale.server.core.modules.collision.BlockCollisionData;
class="kw">import com.hypixel.hytale.server.core.modules.collision.CollisionConfig;
class="kw">import com.hypixel.hytale.server.core.modules.collision.CollisionModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
class="kw">import com.hypixel.hytale.server.core.modules.physics.util.PhysicsMath;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
class="kw">import com.hypixel.hytale.server.npc.movement.MotionKind;
class="kw">import com.hypixel.hytale.server.npc.movement.MovementMode;
class="kw">import com.hypixel.hytale.server.npc.movement.Steering;
class="kw">import com.hypixel.hytale.server.npc.movement.controllers.builders.BuilderMotionControllerDive;
class="kw">import com.hypixel.hytale.server.npc.role.Role;
class="kw">import com.hypixel.hytale.server.npc.util.NPCPhysicsMath;
class="kw">import com.hypixel.hytale.server.npc.util.PositionProbeWater;
class="kw">import java.util.EnumSet;
class="kw">import java.util.Set;
class="kw">import java.util.function.Predicate;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class MotionControllerDive class="kw">extends MotionControllerBase {
   class="kw">public class="kw">static class="kw">final String TYPE = "Dive";
   class="kw">public class="kw">static class="kw">final Set<MovementMode> SUPPORTED_MOVEMENT_MODES = Set.of(MovementMode.DIVE);
   class="kw">public class="kw">static class="kw">final Set<MovementMode> DEFAULT_SPAWN_MOVEMENT_MODES = Set.of(MovementMode.DIVE);
   class="kw">public class="kw">static class="kw">final int COLLISION_MATERIALS_ACTIVE = 5;
   class="kw">public class="kw">static class="kw">final int COLLISION_MATERIALS_PASSIVE = 4;
   class="kw">public class="kw">static class="kw">final double DEFAULT_SWIM_DEPTH = 0.5;
   class="kw">protected class="kw">static double DAMPING_FACTOR = 20.0;
   class="kw">protected class="kw">final double maxVerticalSpeed;
   class="kw">protected class="kw">final double acceleration;
   class="kw">protected class="kw">final double maxFallSpeed;
   class="kw">protected class="kw">final double maxSinkSpeed;
   class="kw">protected class="kw">final double maxRotationSpeed;
   class="kw">protected class="kw">final float maxMoveTurnAngle;
   class="kw">protected class="kw">final double minDiveDepth;
   class="kw">protected class="kw">final double maxDiveDepth;
   class="kw">protected class="kw">final double minWaterDepth;
   class="kw">protected class="kw">final double maxWaterDepth;
   class="kw">protected class="kw">final double minDepthAboveGround;
   class="kw">protected class="kw">final double minDepthBelowSurface;
   class="kw">protected class="kw">final double relativeSwimDepth;
   class="kw">protected class="kw">final double sinkRatio;
   class="kw">protected class="kw">final double fastDiveThreshold;
   class="kw">protected class="kw">final double externalVelocityStopThresholdSquared;
   class="kw">protected class="kw">final double desiredDepthWeight;
   class="kw">protected double swimDepth;
   class="kw">protected double climbSpeed;
   class="kw">protected double currentRelativeSpeed;
   class="kw">protected boolean collisionWithSolid;
   @Nullable
   class="kw">private Predicate<CollisionConfig> activeProbeBlockCollisionFilter;
   class="kw">protected class="kw">final MotionController.VerticalRange verticalRange = new MotionController.VerticalRange();
   class="kw">protected class="kw">final PositionProbeWater moveProbe = new PositionProbeWater();
   class="kw">protected class="kw">final PositionProbeWater probeMoveProbe = new PositionProbeWater();
   class="kw">protected class="kw">final Vector3d tempPosition = new Vector3d();
   class="kw">protected class="kw">final Vector3d tempDirection = new Vector3d();
   class="kw">private class="kw">static class="kw">final EnumSet<MotionKind> VALID_MOTIONS = EnumSet.of(MotionKind.SWIMMING, MotionKind.SWIMMING_TURNING, MotionKind.MOVING);

   class="kw">public MotionControllerDive(@Nonnull BuilderSupport var1, @Nonnull BuilderMotionControllerDive var2) {
      super(var1, var2);
      this.setGravity(var2.getGravity());
      this.componentSelector.set(1.0, 1.0, 1.0);
      this.maxVerticalSpeed = var2.getMaxVerticalSpeed();
      this.acceleration = var2.getAcceleration();
      this.maxSinkSpeed = var2.getMaxSinkSpeed();
      this.maxFallSpeed = var2.getMaxFallSpeed();
      this.maxRotationSpeed = var2.getMaxRotationSpeed();
      this.maxMoveTurnAngle = var2.getMaxMoveTurnAngle();
      this.minDiveDepth = var2.getMinDiveDepth();
      this.maxDiveDepth = var2.getMaxDiveDepth();
      this.minWaterDepth = var2.getMinWaterDepth();
      this.maxWaterDepth = var2.getMaxWaterDepth();
      this.minDepthAboveGround = var2.getMinDepthAboveGround();
      this.minDepthBelowSurface = var2.getMinDepthBelowSurface();
      this.relativeSwimDepth = var2.getSwimDepth();
      this.sinkRatio = var2.getSinkRatio();
      this.fastDiveThreshold = var2.getFastDiveThreshold();
      this.desiredDepthWeight = var2.getDesiredDepthWeight();
      double var3 = MathUtil.minValue(this.maxVerticalSpeed, this.maxSinkSpeed, this.maxFallSpeed);
      this.externalVelocityStopThresholdSquared = var3 * var3;
   }

   @Override
   class="kw">public void activate() {
      super.activate();
      this.collisionResult.disableSlides();
   }

   @Override
   class="kw">public double getWanderVerticalMovementRatio() {
      class="kw">return this.sinkRatio;
   }

   @Nonnull
   @Override
   class="kw">public MotionController.VerticalRange getDesiredVerticalRange(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      double var3 = this.moveProbe.getWaterLevel() + 1.0;
      double var5 = var3 - this.swimDepth - this.minDepthBelowSurface;
      double var7 = this.moveProbe.getGroundLevel() + this.minDepthAboveGround;
      double var9 = var3 - this.maxDiveDepth;
      double var11 = Math.max(var7, var9);
      TransformComponent var13 = var2.getComponent(var1, TransformComponent.getComponentType());
      assert var13 != null;
      double var14 = var13.getPosition().y;
      if (this.onGround()) {
         var11 = var14;
      }

      if (this.moveProbe.isTouchCeil()) {
         var5 = var14;
      }

      if (var11 > var5) {
         var11 = var14;
         var5 = var14;
      }

      this.verticalRange.set(var14, var11, var5);
      class="kw">return this.verticalRange;
   }

   @Override
   class="kw">protected double computeMove(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull Role var2,
      @Nonnull Steering var3,
      double var4,
      @Nonnull Vector3d var6,
      @Nonnull ComponentAccessor<EntityStore> var7
   ) {
      this.saveMotionKind();
      this.moveProbe.probePosition(var1, this.collisionBoundingBox, this.position, this.collisionResult, this.swimDepth, var7);
      this.setMotionKind(!this.moveProbe.isInWater() && this.moveProbe.isOnGround() ? MotionKind.MOVING : MotionKind.SWIMMING);
      this.currentRelativeSpeed = var3.getSpeed();
      Vector3d var8 = var3.getTranslation();
      float var9 = this.getYaw();
      float var10 = this.getPitch();
      if (this.collisionWithSolid) {
         this.moveSpeed = 0.0;
         this.climbSpeed = 0.0;
         this.externalVelocity.zero();
         this.appliedVelocities.clear();
      }

      if (this.canSteer(var1, var7)) {
         this.tempDirection.set(var8.x, 0.0, var8.z);
         double var27 = this.maxVerticalSpeed * this.effectHorizontalSpeedMultiplier;
         double var28 = this.tempDirection.length() * this.getMaximumSpeed();
         double var32 = var8.y * var27;
         this.moveSpeed = NPCPhysicsMath.accelerateToTargetSpeed(this.moveSpeed, var28, var4, this.acceleration, this.getMaximumSpeed());
         this.climbSpeed = NPCPhysicsMath.accelerateToTargetSpeed(this.climbSpeed, var32, var4, this.acceleration, this.acceleration, -var27, var27);
         float var17 = (float)(var4 * this.getCurrentMaxBodyRotationSpeed());
         boolean var20 = this.moveSpeed * this.moveSpeed + this.climbSpeed * this.climbSpeed > 1.0E-12 && var3.hasTranslation();
         float var18;
         float var19;
         if (this.moveSpeed * this.moveSpeed > 1.0000000000000002E-10 && var3.hasTranslation()) {
            var18 = PhysicsMath.normalizeTurnAngle(PhysicsMath.headingFromDirection(var8.x, var8.z));
            var19 = PhysicsMath.normalizeTurnAngle(PhysicsMath.pitchFromDirection(var8.x, var8.y, var8.z));
         } else {
            var6.zero();
            if (var3.hasYawOrDirection()) {
               var18 = var3.getYawOrDirection();
            } else {
               var18 = var9;
            }

            var3.clearYaw();
            if (var3.hasPitchOrDirection()) {
               var19 = var3.getPitchOrDirection();
            } else {
               var19 = var10;
            }

            var3.clearPitch();
         }

         float var21 = NPCPhysicsMath.turnAngle(var9, var18);
         float var22 = NPCPhysicsMath.turnAngle(var10, var19);
         if (Math.abs(var21) > this.maxMoveTurnAngle) {
            this.moveSpeed = 0.0;
         }

         if (this.isNearZero(var21)) {
            var9 = var18;
            var21 = 0.0F;
         } else {
            var21 = MathUtil.clamp(var21, -var17, var17);
            var9 += var21;
            if (!var20) {
               this.setMotionKind(MotionKind.SWIMMING_TURNING);
            }
         }

         var9 = PhysicsMath.normalizeTurnAngle(var9);
         if (this.isNearZero(var22)) {
            var10 = var19;
         } else {
            var22 = MathUtil.clamp(var22, -var17, var17);
            var10 += var22;
         }

         var10 = PhysicsMath.normalizeTurnAngle(var10);
         if (!var3.hasYaw()) {
            var3.setYaw(var9);
         }

         if (!var3.hasPitch()) {
            var3.setPitch(var10);
         }

         if (this.debugModeSteer) {
            LOGGER.at(Level.INFO)
               .log(
                  "eid=%d === Compute = t =%.4f v =%.4f h =%.4f nh=%.4f dh=%.4f",
                  this.debugEntityId,
                  var4,
                  this.moveSpeed,
                  (180.0F / (float)Math.PI) * var9,
                  (180.0F / (float)Math.PI) * var18,
                  (180.0F / (float)Math.PI) * var21
               );
         }

         this.computeTranslation(var6, var4, var9, this.moveSpeed, this.climbSpeed);
         class="kw">return var4;
      } else {
         double var11 = this.moveProbe.isInWater() ? this.maxSinkSpeed : this.maxFallSpeed;
         boolean var13 = this.onGround();
         if (!this.isAlive(var1, var7)) {
            var3.setYaw(this.getYaw());
            var3.setPitch(var13 ? 0.0F : this.getPitch());
            this.externalVelocity.zero();
            this.appliedVelocities.clear();
            this.moveSpeed = 0.0;
            this.climbSpeed = 0.0;
            if (var13) {
               var6.zero();
            } else {
               Velocity var29 = var7.getComponent(var1, Velocity.getComponentType());
               double var30 = var29.getVelocity().y;
               var30 = NPCPhysicsMath.gravityDrag(var30, 5.0 * this.gravity, var4, var11);
               var6.set(0.0, var30, 0.0).mul(var4);
            }

            class="kw">return var4;
         } else if (this.externalVelocity.equals(Vector3dUtil.ZERO) && this.appliedVelocities.isEmpty()) {
            if (!var3.hasYaw()) {
               var3.setYaw(var9);
            }

            if (!var3.hasPitch()) {
               var3.setPitch(this.onGround() ? 0.0F : var10);
            }

            this.climbSpeed = NPCPhysicsMath.gravityDrag(this.climbSpeed, 5.0 * this.gravity, var4, var11);
            this.computeTranslation(var6, var4, var9, this.moveSpeed, this.climbSpeed);
            class="kw">return var4;
         } else {
            this.moveSpeed = 0.0;
            this.climbSpeed = 0.0;
            if (!this.isObstructed()) {
               var6.set(this.externalVelocity);

               for (int var14 = 0; var14 < this.appliedVelocities.size(); var14++) {
                  MotionControllerBase.AppliedVelocity var15 = this.appliedVelocities.get(var14);
                  if (var15.velocity.y + this.externalVelocity.y <= 0.0 || var15.velocity.y < 0.0) {
                     var15.canClear = true;
                  }

                  if (var13 && var15.canClear) {
                     var15.velocity.y = 0.0;
                  }

                  var6.add(var15.velocity);
               }
            } else {
               var6.zero();
               this.appliedVelocities.clear();
               this.externalVelocity.zero();
            }

            var6.y = NPCPhysicsMath.gravityDrag(this.externalVelocity.y, 5.0 * this.gravity, var4, var11);
            var6.mul(var4);
            var3.setYaw(this.getYaw());
            var3.setPitch(this.getPitch());
            class="kw">return var4;
         }
      }
   }

   @Override
   class="kw">protected boolean shouldDampenAppliedVelocitiesY() {
      class="kw">return true;
   }

   @Override
   class="kw">protected boolean shouldAlwaysUseGroundResistance() {
      class="kw">return true;
   }

   class="kw">private void computeTranslation(@Nonnull Vector3d var1, double var2, float var4, double var5, double var7) {
      var1.x = var5 * var2 * PhysicsMath.headingX(var4);
      var1.z = var5 * var2 * PhysicsMath.headingZ(var4);
      var1.y = var7 * var2;
      Vector3dUtil.clipToZero(var1, this.getEpsilonSpeed());
   }

   class="kw">private boolean isNearZero(float var1) {
      float var2 = this.getEpsilonAngle();
      class="kw">return var1 >= -var2 && var1 <= var2;
   }

   @Override
   class="kw">public void setMotionKind(MotionKind var1) {
      if (!VALID_MOTIONS.contains(var1)) {
         var1 = MotionKind.SWIMMING;
      }

      super.setMotionKind(var1);
   }

   @Override
   class="kw">protected double executeMove(
      @Nonnull Ref<EntityStore> var1, @Nonnull Role var2, double var3, @Nonnull Vector3d var5, @Nonnull ComponentAccessor<EntityStore> var6
   ) {
      if (this.debugModeValidatePositions && !this.isValidPosition(this.position, this.collisionResult, var6)) {
         throw new IllegalStateException("Invalid position");
      }

      boolean var7 = this.canSteer(var1, var6);
      this.collisionResult.setCollisionByMaterial(var7 ? 5 : 4);
      if (this.debugModeBlockCollisions) {
         this.collisionResult.setLogger(LOGGER, this.debugEntityId);
      }

      CollisionModule.findCollisions(this.collisionBoundingBox, this.position, var5, this.collisionResult, var6);
      if (this.debugModeBlockCollisions) {
         this.collisionResult.setLogger(null);
      }

      if (this.debugModeCollisions) {
         this.dumpCollisionResults();
      }

      this.lastValidPosition.set(this.position);
      this.isObstructed = false;
      this.collisionWithSolid = false;
      BlockCollisionData var8 = this.collisionResult.getFirstBlockCollision();
      if (var8 == null) {
         double var11 = var3;
         this.position.add(var5);
         if (!this.moveProbe.probePosition(var1, this.collisionBoundingBox, this.position, this.collisionResult, this.swimDepth, var6)
            || var7 && !this.moveProbe.isInWater()) {
            var11 = this.bisect(var1, this.lastValidPosition, 0.0, this.position, var3, this.position, var6);
            this.isObstructed = true;
            if (this.shouldDebugMove(var5)) {
               LOGGER.at(Level.INFO)
                  .log(
                     "eid=%d Move - Dive: No Collision, Bisect pos=%s, blocked=%s",
                     this.debugEntityId,
                     Vector3dUtil.formatShortString(this.position),
                     this.isObstructed
                  );
            }
         } else if (this.shouldDebugMove(var5)) {
            LOGGER.at(Level.INFO)
               .log(
                  "eid=%d Move - Dive: No collision, pos=%s, blocked=%s", this.debugEntityId, Vector3dUtil.formatShortString(this.position), this.isObstructed
               );
         }

         if (this.debugModeValidatePositions && !this.isValidPosition(this.position, this.collisionResult, var6)) {
            throw new IllegalStateException("Invalid position");
         }

         this.processTriggers(var1, this.collisionResult, var11 / var3, var6);
         class="kw">return var11;
      } else {
         if (this.debugModeValidatePositions && !this.isValidPosition(var8.collisionPoint, this.collisionResult, var6)) {
            throw new IllegalStateException("Invalid position");
         }

         double var9 = var8.collisionStart;
         this.position.set(var8.collisionPoint);
         this.isObstructed = true;
         this.collisionWithSolid = var8.blockMaterial == BlockMaterial.Solid;
         if (!this.moveProbe.probePosition(var1, this.collisionBoundingBox, this.position, this.collisionResult, this.swimDepth, var6)
            || var7 && !this.moveProbe.isInWater()) {
            var9 = this.bisect(var1, this.lastValidPosition, 0.0, this.position, var9, this.position, var6);
            if (this.debugModeMove) {
               LOGGER.at(Level.INFO)
                  .log(
                     "eid=%d Move - Dive: Collision with solid=%s, Bisect pos=%s, blocked=%s",
                     this.debugEntityId,
                     this.collisionWithSolid,
                     Vector3dUtil.formatShortString(this.position),
                     this.isObstructed
                  );
            }
         } else if (this.debugModeMove) {
            LOGGER.at(Level.INFO)
               .log(
                  "eid=%d Move - Dive: Collision with solid=%s, pos=%s, blocked=%s",
                  this.debugEntityId,
                  this.collisionWithSolid,
                  Vector3dUtil.formatShortString(this.position),
                  this.isObstructed
               );
         }

         if (this.debugModeValidatePositions && !this.isValidPosition(this.position, this.collisionResult, var6)) {
            throw new IllegalStateException("Invalid position");
         }

         this.processTriggers(var1, this.collisionResult, var9, var6);
         class="kw">return var3 * var9;
      }
   }

   @Override
   class="kw">public void constrainRotations(Role var1, @Nonnull TransformComponent var2) {
      var2.getRotation().setRoll(0.0F);
   }

   @Override
   class="kw">public double getCurrentMaxBodyRotationSpeed() {
      class="kw">return this.maxRotationSpeed * this.effectHorizontalSpeedMultiplier;
   }

   @Override
   class="kw">public boolean canSteer(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      class="kw">return super.canSteer(var1, var2) && this.moveProbe.isInWater();
   }

   @Override
   class="kw">public boolean inAir() {
      class="kw">return !this.moveProbe.isOnGround();
   }

   @Override
   class="kw">public boolean inWater() {
      class="kw">return this.moveProbe.isInWater();
   }

   @Override
   class="kw">public boolean onGround() {
      class="kw">return this.moveProbe.isOnGround();
   }

   @Nonnull
   @Override
   class="kw">public String getType() {
      class="kw">return "Dive";
   }

   @Nonnull
   @Override
   class="kw">public Set<MovementMode> getSupportedMovementModes() {
      class="kw">return SUPPORTED_MOVEMENT_MODES;
   }

   @Nonnull
   @Override
   class="kw">public Set<MovementMode> getDefaultSpawnMovementModes() {
      class="kw">return DEFAULT_SPAWN_MOVEMENT_MODES;
   }

   class="kw">public double bisect(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull Vector3d var2,
      double var3,
      @Nonnull Vector3d var5,
      double var6,
      @Nonnull Vector3d var8,
      @Nonnull ComponentAccessor<EntityStore> var9
   ) {
      class="kw">return NPCPhysicsMath.lerp(var3, var6, this.bisect(var1, var2, var5, var8, var9));
   }

   class="kw">public double bisect(
      @Nonnull Ref<EntityStore> var1, @Nonnull Vector3d var2, @Nonnull Vector3d var3, @Nonnull Vector3d var4, @Nonnull ComponentAccessor<EntityStore> var5
   ) {
      class="kw">return this.bisect(var2, var3, this, (var2x, var3x) -> {
         var2x.applyActiveProbeBlockCollisionFilter();
         class="kw">return var2x.probeMoveProbe.probePosition(var1, var2x.collisionBoundingBox, var3x, var2x.collisionResult, var2x.swimDepth, var5);
      }, var4);
   }

   @Override
   class="kw">public double probeMove(@Nonnull Ref<EntityStore> var1, @Nonnull ProbeMoveData var2, @Nonnull ComponentAccessor<EntityStore> var3) {
      boolean var4 = var2.startProbing();
      this.collisionResult.setCollisionByMaterial(5);
      Predicate var5 = this.collisionResult.setBlockCollisionFilter(var2.getBlockCollisionFilter());
      this.activeProbeBlockCollisionFilter = var2.getBlockCollisionFilter();

      try {
         Vector3d var6 = var2.probePosition;
         Vector3d var7 = var2.probeDirection;
         if (var4) {
            var2.addStartSegment(var6, false);
         }

         this.applyActiveProbeBlockCollisionFilter();
         if (!this.probeMoveProbe.probePosition(var1, this.collisionBoundingBox, var6, this.collisionResult, this.swimDepth, var3)) {
            if (var4) {
               var2.addEndSegment(var6, false, 0.0);
            }

            class="kw">return 0.0;
         } else {
            double var9 = var7.length();
            this.applyActiveProbeBlockCollisionFilter();
            CollisionModule.findCollisions(this.collisionBoundingBox, var6, var7, this.collisionResult, var3);
            if (this.debugModeMove) {
               LOGGER.at(Level.INFO)
                  .log(
                     "eid=%d Probe Step: pos=%s mov=%s left=%s",
                     this.debugEntityId,
                     Vector3dUtil.formatShortString(var6),
                     Vector3dUtil.formatShortString(var7),
                     var9
                  );
            }

            if (this.debugModeCollisions) {
               this.dumpCollisionResults();
            }

            BlockCollisionData var8 = this.collisionResult.getFirstBlockCollision();
            this.tempPosition.set(var6);
            if (var8 == null) {
               var6.add(var7);
               var7.zero();
               this.applyActiveProbeBlockCollisionFilter();
               double var20;
               if (this.probeMoveProbe.probePosition(var1, this.collisionBoundingBox, var6, this.collisionResult, this.swimDepth, var3)
                  && this.probeMoveProbe.isInWater()) {
                  var20 = var9;
                  if (this.debugModeMove) {
                     LOGGER.at(Level.INFO)
                        .log(
                           "eid=%d Probe - Dive: No Collision, valid pos=%s, distanceLeft=%s",
                           this.debugEntityId,
                           Vector3dUtil.formatShortString(var6),
                           var9 - var20
                        );
                  }
               } else {
                  var20 = this.bisect(var1, this.tempPosition, 0.0, var6, var9, var6, var3);
                  if (this.debugModeMove) {
                     LOGGER.at(Level.INFO)
                        .log(
                           "eid=%d Probe - Dive: No Collision, Bisect pos=%s, distanceLeft=%s",
                           this.debugEntityId,
                           Vector3dUtil.formatShortString(var6),
                           var9 - var20
                        );
                  }
               }

               this.applyActiveProbeBlockCollisionFilter();
               if (this.debugModeValidatePositions && !this.isValidPosition(this.tempPosition, this.collisionResult, var3)) {
                  throw new IllegalStateException("Invalid position");
               }

               if (var4) {
                  var2.addMoveSegment(var6, false, var20);
                  var2.addEndSegment(var6, false, var20);
               }

               if (this.debugModeMove) {
                  LOGGER.at(Level.INFO).log("eid=%d Probe Move done: No collision - maxDistance=%s distanceLeft=%s", this.debugEntityId, var9, var9 - var20);
               }

               class="kw">return var20;
            } else {
               double var13 = var8.collisionStart;
               double var11 = var9 * var13;
               var6.set(var8.collisionPoint);
               this.applyActiveProbeBlockCollisionFilter();
               if (!this.probeMoveProbe.probePosition(var1, this.collisionBoundingBox, var6, this.collisionResult, this.swimDepth, var3)
                  || !this.probeMoveProbe.isInWater()) {
                  var11 = this.bisect(var1, this.tempPosition, 0.0, var6, var11, var6, var3);
                  if (this.debugModeMove) {
                     LOGGER.at(Level.INFO)
                        .log(
                           "eid=%d Probe - Dive: Collision, Bisect pos=%s, distanceLeft=%s, collision start=%s",
                           this.debugEntityId,
                           Vector3dUtil.formatShortString(var6),
                           var9 - var11,
                           var13
                        );
                  }
               } else if (this.debugModeMove) {
                  LOGGER.at(Level.INFO)
                     .log(
                        "eid=%d Probe - Dive: Collision, valid pos=%s, distanceLeft=%s, collision start=%s",
                        this.debugEntityId,
                        Vector3dUtil.formatShortString(var6),
                        var9 - var11,
                        var13
                     );
               }

               this.applyActiveProbeBlockCollisionFilter();
               if (this.debugModeValidatePositions && !this.isValidPosition(var6, this.collisionResult, var3)) {
                  throw new IllegalStateException("Invalid position");
               }

               if (var4) {
                  if (this.getWorldNormal().equals(var8.collisionNormal)) {
                     var2.addHitGroundSegment(var6, var11, var8.collisionNormal, var8.blockId);
                  } else {
                     var2.addHitWallSegment(var6, false, var11, var8.collisionNormal, var8.blockId);
                  }
               }

               if (var4) {
                  var2.addEndSegment(var6, false, var11);
               }

               if (this.debugModeMove) {
                  LOGGER.at(Level.INFO).log("eid=%d Probe Move done: maxDistance=%s distanceLeft=%s", this.debugEntityId, var9, var9 - var11);
               }

               class="kw">return var11;
            }
         }
      } class="kw">finally {
         this.collisionResult.setBlockCollisionFilter(var5);
         this.activeProbeBlockCollisionFilter = null;
      }
   }

   class="kw">private void applyActiveProbeBlockCollisionFilter() {
      if (this.activeProbeBlockCollisionFilter != null) {
         this.collisionResult.setBlockCollisionFilter(this.activeProbeBlockCollisionFilter);
      }
   }

   @Override
   class="kw">public void spawned() {
   }

   @Override
   class="kw">public double getCurrentSpeed() {
      class="kw">return this.moveSpeed;
   }

   @Override
   class="kw">public double getCurrentTurnRadius() {
      class="kw">return 0.0;
   }

   @Override
   class="kw">public float getMaxClimbAngle() {
      class="kw">return (float) (Math.PI / 2);
   }

   @Override
   class="kw">public float getMaxSinkAngle() {
      class="kw">return (float) (Math.PI / 2);
   }

   @Override
   class="kw">public double getMaximumSpeed() {
      class="kw">return this.maxHorizontalSpeed * this.effectHorizontalSpeedMultiplier;
   }

   @Override
   class="kw">public boolean isFastMotionKind(double var1) {
      class="kw">return this.currentRelativeSpeed > this.fastDiveThreshold;
   }

   @Override
   class="kw">public boolean is2D() {
      class="kw">return false;
   }

   @Override
   class="kw">public boolean canRestAtPlace() {
      class="kw">return true;
   }

   @Override
   class="kw">public double getDesiredAltitudeWeight() {
      class="kw">return this.desiredDepthWeight;
   }

   @Override
   class="kw">public double getHeightOverGround() {
      class="kw">return this.probeMoveProbe.getHeightOverGround();
   }

   @Override
   class="kw">public boolean estimateVelocity(Steering var1, @Nonnull Vector3d var2) {
      var2.zero();
      class="kw">return false;
   }

   @Override
   class="kw">public void updateModelParameters(Ref<EntityStore> var1, Model var2, @Nonnull Box var3, ComponentAccessor<EntityStore> var4) {
      super.updateModelParameters(var1, var2, var3, var4);
      this.swimDepth = relativeSwimDepthToHeight(var1, this.relativeSwimDepth, var2, var3, var4);
   }

   @Override
   class="kw">protected void dampExternalVelocity(@Nonnull Vector3d var1, double var2, double var4, ComponentAccessor<EntityStore> var6) {
      if (var1.lengthSquared() < this.externalVelocityStopThresholdSquared) {
         var1.zero();
      } else {
         NPCPhysicsMath.deccelerateToStop(var1, this.getDampingDeceleration(), var4);
      }
   }

   class="kw">public class="kw">static double relativeSwimDepthToBoundingBox(double var0, @Nullable Box var2, float var3) {
      if (var2 == null) {
         class="kw">return 0.5;
      } else {
         class="kw">return var0 < 0.0 ? NPCPhysicsMath.lerp(var3, var2.getMin().y(), -var0) : NPCPhysicsMath.lerp(var3, var2.getMax().y(), var0);
      }
   }

   class="kw">public class="kw">static double relativeSwimDepthToHeight(double var0, @Nullable Box var2, float var3) {
      class="kw">return var2 == null ? 0.5 : relativeSwimDepthToBoundingBox(var0, var2, var3) - var2.getMin().y();
   }

   class="kw">public class="kw">static double relativeSwimDepthToHeight(
      @Nullable Ref<EntityStore> var0, double var1, Model var3, Box var4, @Nullable ComponentAccessor<EntityStore> var5
   ) {
      class="kw">return relativeSwimDepthToHeight(var1, var4, var3 != null ? var3.getEyeHeight(var0, var5) : 0.0F);
   }

   class="kw">public double getDampingDeceleration() {
      class="kw">return this.externalVelocityDamping * DAMPING_FACTOR;
   }
}