Shape enum

Пакет: com.hypixel.hytale.server.npc.corecomponents.world

Файл: com/hypixel/hytale/server/npc/corecomponents/world/BodyMotionPath.java

implements: Supplier<String>

Поля (1)

МодификаторыТипИмя
private final String description

Методы (2)

МодификаторыВозвратСигнатура
abstract CHAIN CHAIN("Nodes form an open path of line segments and will chain together with the next nearest path upon reaching the final node")
public String getpublic String get()

Исходный код

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

class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.random.RandomExtra;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3dUtil;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.universe.world.path.IPath;
class="kw">import com.hypixel.hytale.server.core.universe.world.path.IPathWaypoint;
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.corecomponents.BodyMotionBase;
class="kw">import com.hypixel.hytale.server.npc.corecomponents.world.builders.BuilderBodyMotionPath;
class="kw">import com.hypixel.hytale.server.npc.instructions.ExecutionSupport;
class="kw">import com.hypixel.hytale.server.npc.movement.Steering;
class="kw">import com.hypixel.hytale.server.npc.movement.controllers.MotionController;
class="kw">import com.hypixel.hytale.server.npc.movement.steeringforces.SteeringForcePursue;
class="kw">import com.hypixel.hytale.server.npc.movement.steeringforces.SteeringForceRotate;
class="kw">import com.hypixel.hytale.server.npc.role.support.WorldSupport;
class="kw">import com.hypixel.hytale.server.npc.sensorinfo.IPathProvider;
class="kw">import com.hypixel.hytale.server.npc.sensorinfo.InfoProvider;
class="kw">import com.hypixel.hytale.server.npc.util.NPCPhysicsMath;
class="kw">import it.unimi.dsi.fastutil.ints.IntArrayList;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.ints.IntLists;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import java.util.function.Supplier;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class BodyMotionPath class="kw">extends BodyMotionBase {
   class="kw">public class="kw">static class="kw">final double MIN_GUARD_POINT_WAIT_TIME = 1.0;
   class="kw">public class="kw">static class="kw">final boolean TESTING = false;
   class="kw">protected class="kw">final BodyMotionPath.Shape shape;
   class="kw">protected class="kw">final double pathWidth;
   class="kw">protected class="kw">final double nodeWidth;
   class="kw">protected class="kw">final double minRelativeSpeed;
   class="kw">protected class="kw">final double maxRelativeSpeed;
   class="kw">protected class="kw">final double minWalkDistance;
   class="kw">protected class="kw">final double maxWalkDistance;
   class="kw">protected class="kw">final boolean startAtNearestNode;
   class="kw">protected class="kw">final BodyMotionPath.Direction direction;
   class="kw">protected class="kw">final double minNodeDelay;
   class="kw">protected class="kw">final double maxNodeDelay;
   class="kw">protected class="kw">final int viewSegments;
   class="kw">protected class="kw">final boolean useNodeViewDirection;
   class="kw">protected class="kw">final boolean pickRandomAngle;
   class="kw">protected class="kw">final double minDelayScale;
   class="kw">protected class="kw">final double maxDelayScale;
   class="kw">protected class="kw">final double minPercentage;
   class="kw">protected class="kw">final double maxPercentage;
   class="kw">protected int currentWaypointIndex = -1;
   @Nullable
   class="kw">protected BodyMotionPath.Direction currentDirection;
   class="kw">protected class="kw">final Vector3d currentWaypointPosition = new Vector3d();
   class="kw">protected class="kw">final Vector3d lastWaypointPosition = new Vector3d();
   class="kw">protected class="kw">final IntList visitOrder = new IntArrayList();
   class="kw">protected int visitIndex;
   class="kw">protected class="kw">final SteeringForceRotate steeringForceRotate = new SteeringForceRotate();
   class="kw">protected class="kw">final SteeringForcePursue steeringForcePursue = new SteeringForcePursue();
   class="kw">protected double currentSpeed;
   class="kw">protected class="kw">final Vector3d currentPosition = new Vector3d();
   class="kw">protected class="kw">final Vector3d nextPosition = new Vector3d();
   class="kw">protected boolean nextPositionValid;
   class="kw">protected double currentNodeDelay;
   class="kw">protected boolean pendingNodeDelay;
   class="kw">protected boolean rotatingToView;
   class="kw">protected float nodeViewDirection;
   class="kw">protected double nodeWaitTime;
   class="kw">protected float observationSector;
   class="kw">protected double currentObservationDelay;
   class="kw">protected boolean rotating;
   class="kw">protected class="kw">final Vector3d previousSteeringTranslation = new Vector3d(Vector3dUtil.MIN);
   class="kw">protected int currentViewSegment;

   class="kw">public BodyMotionPath(@Nonnull BuilderBodyMotionPath var1, @Nonnull BuilderSupport var2) {
      super(var1);
      this.shape = var1.getShape(var2);
      this.pathWidth = var1.getPathWidth();
      this.nodeWidth = var1.getNodeWidth();
      this.minRelativeSpeed = var1.getMinRelativeSpeed();
      this.maxRelativeSpeed = var1.getMaxRelativeSpeed();
      this.minWalkDistance = var1.getMinWalkDistance();
      this.maxWalkDistance = var1.getMaxWalkDistance();
      this.startAtNearestNode = var1.isStartAtNearestNode();
      this.direction = var1.getDirection();
      this.minNodeDelay = var1.getMinNodeDelay();
      this.maxNodeDelay = var1.getMaxNodeDelay();
      this.useNodeViewDirection = var1.isUseNodeViewDirection();
      double[] var3 = var1.getDelayScaleRange(var2);
      this.minDelayScale = var3[0];
      this.maxDelayScale = var3[1];
      double[] var4 = var1.getPercentDelayRange(var2);
      this.minPercentage = var4[0];
      this.maxPercentage = var4[1];
      this.pickRandomAngle = var1.isPickRandomAngle();
      this.viewSegments = var1.getViewSegments(var2);
   }

   @Override
   class="kw">public void activate(@Nonnull Ref<EntityStore> var1, @Nonnull ExecutionSupport var2, @Nonnull ComponentAccessor<EntityStore> var3) {
      this.reset();
   }

   @Override
   class="kw">public void loaded(ExecutionSupport var1) {
      this.invalidateWaypoint();
      this.reset();
   }

   @Override
   class="kw">public boolean computeSteering(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull ExecutionSupport var2,
      @Nullable InfoProvider var3,
      double var4,
      @Nonnull Steering var6,
      @Nonnull ComponentAccessor<EntityStore> var7
   ) {
      var6.clear();
      if (!var2.getMotionContextSupport().getActiveMotionController().canSteer(var1, var7)) {
         class="kw">return true;
      }

      IPathProvider var8 = var3.getExtraInfo(IPathProvider.class);
      if (var8 != null && var8.hasPath()) {
         IPath var9 = var8.getPath();
         int var10 = var9.length();
         if (this.visitOrder.size() != var10) {
            this.visitOrder.clear();

            for (int var11 = 0; var11 < var10; var11++) {
               this.visitOrder.add(var11);
            }

            IntLists.shuffle(this.visitOrder, ThreadLocalRandom.current());
            this.visitIndex = 0;
            this.invalidateWaypoint();
         }

         TransformComponent var22 = var7.getComponent(var1, TransformComponent.getComponentType());
         assert var22 != null;
         Vector3d var12 = var22.getPosition();
         if (this.currentWaypointIndex == -1) {
            if (!this.getFirstWaypoint(var1, var2, var9, var12, var7)) {
               class="kw">return false;
            }

            this.nextPositionValid = false;
            this.currentNodeDelay = 0.0;
         }

         float var13 = var22.getRotation().yaw();
         if (this.currentNodeDelay > 0.0) {
            this.currentNodeDelay -= var4;
            if (this.observationSector != 0.0F || var10 == 1) {
               this.steeringForceRotate.setHeading(var13);
               if (this.steeringForceRotate.compute(var6)) {
                  class="kw">return true;
               }

               var6.setYaw(var13);
               if (this.tickObservationDelay(var4)) {
                  class="kw">return true;
               }

               this.pickNextObservationAngle();
            }

            class="kw">return true;
         } else {
            MotionController var14 = var2.getMotionContextSupport().getActiveMotionController();
            Vector3d var15 = var14.getComponentSelector();
            WorldSupport var16 = var2.getWorldSupport();
            this.currentPosition.set(var12.x(), var12.y(), var12.z());
            int var17 = this.currentWaypointIndex;
            this.lastWaypointPosition.set(this.currentWaypointPosition);

            while (this.closeToPosition(this.currentWaypointPosition, var14)) {
               if (this.nextPositionValid || var10 == 1) {
                  IPathWaypoint var18 = var9.get(this.currentWaypointIndex);
                  if (var18 == null) {
                     class="kw">return false;
                  }

                  this.nodeViewDirection = var18.getWaypointRotation(var7).yaw();
                  this.nodeWaitTime = var18.getPauseTime();
                  this.observationSector = var18.getObservationAngle() / 2.0F;
                  this.currentViewSegment = 0;
                  if (var10 == 1) {
                     this.currentNodeDelay = MathUtil.maxValue(this.nodeWaitTime, 1.0);
                     this.pickNextObservationAngle();
                     var6.setYaw(var13);
                     class="kw">return true;
                  }
               }

               this.nextPositionValid = false;
               if (!this.nextWayPoint(var9, var16, var7)) {
                  if (var16.hasRequestedNewPath()) {
                     var6.setTranslation(this.previousSteeringTranslation);
                  }

                  class="kw">return false;
               }

               if (this.currentWaypointIndex == var17) {
                  class="kw">return false;
               }
            }

            if (!this.nextPositionValid || this.closeToPosition(this.nextPosition, var14)) {
               if (this.pathWidth == 0.0) {
                  this.nextPosition.set(this.currentWaypointPosition);
               } else {
                  double var23 = NPCPhysicsMath.dotProduct(this.currentWaypointPosition, this.lastWaypointPosition, this.currentPosition, var15);
                  double var20 = Math.min(RandomExtra.randomRange(this.minWalkDistance, this.maxWalkDistance), var23);
                  if (var20 >= var23 - this.nodeWidth) {
                     this.nextPosition.set(this.currentWaypointPosition);
                  } else {
                     NPCPhysicsMath.orthoComposition(
                        this.lastWaypointPosition,
                        this.currentWaypointPosition,
                        var20,
                        Vector3dUtil.UP,
                        RandomExtra.randomRange(-this.pathWidth / 2.0, this.pathWidth / 2.0),
                        this.nextPosition
                     );
                  }
               }

               this.nextPositionValid = true;
               this.currentSpeed = RandomExtra.randomRange(this.minRelativeSpeed, this.maxRelativeSpeed);
               this.steeringForcePursue.setTargetPosition(this.nextPosition);
               this.steeringForcePursue.setDistances(this.nodeWidth * 1.0, 0.1);
               this.steeringForcePursue.setComponentSelector(var15);
               if ((!this.useNodeViewDirection || !(this.minNodeDelay > 0.0)) && !(this.nodeWaitTime > 0.0)) {
                  this.steeringForceRotate.setDesiredHeading(NPCPhysicsMath.lookatHeading(this.currentPosition, this.nextPosition, var13));
                  this.pendingNodeDelay = this.minNodeDelay > 0.0;
               } else {
                  this.pickNextObservationAngle();
                  this.rotatingToView = true;
                  this.pendingNodeDelay = false;
               }

               this.rotating = true;
            }

            if (this.rotating) {
               this.steeringForceRotate.setHeading(var13);
               if (this.useNodeViewDirection && this.rotatingToView) {
                  if (this.steeringForceRotate.compute(var6)) {
                     class="kw">return true;
                  }

                  var6.setYaw(var13);
                  if (this.tickObservationDelay(var4)) {
                     class="kw">return true;
                  }

                  this.rotatingToView = false;
                  this.steeringForceRotate.setDesiredHeading(NPCPhysicsMath.lookatHeading(this.currentPosition, this.nextPosition, var13));
                  if (this.minNodeDelay > 0.0) {
                     this.currentNodeDelay = RandomExtra.randomRange(this.minNodeDelay, this.maxNodeDelay);
                  }

                  if (this.nodeWaitTime > this.currentNodeDelay) {
                     this.currentNodeDelay = this.nodeWaitTime;
                  }

                  if (this.currentNodeDelay > 0.0) {
                     this.pickNextObservationAngle();
                  }

                  class="kw">return true;
               }

               if (this.steeringForceRotate.compute(var6)) {
                  class="kw">return true;
               }

               if (this.pendingNodeDelay) {
                  this.currentNodeDelay = RandomExtra.randomRange(this.minNodeDelay, this.maxNodeDelay);
                  this.pendingNodeDelay = false;
                  class="kw">return true;
               }

               this.rotating = false;
            }

            this.steeringForcePursue.setSelfPosition(this.currentPosition);
            this.steeringForcePursue.setComponentSelector(var14.getComponentSelector());
            this.nextPositionValid = this.steeringForcePursue.compute(var6);
            if (var6.hasTranslation()) {
               var6.scaleTranslation(this.currentSpeed);
            }

            this.previousSteeringTranslation.set(var6.getTranslation());
            class="kw">return true;
         }
      } else {
         class="kw">return false;
      }
   }

   class="kw">protected boolean tickObservationDelay(double var1) {
      if (this.currentObservationDelay > 0.0) {
         this.currentObservationDelay -= var1;
         class="kw">return true;
      } else {
         class="kw">return false;
      }
   }

   class="kw">protected void pickNextObservationAngle() {
      if (this.pickRandomAngle) {
         float var1 = RandomExtra.randomRange(-this.observationSector, this.observationSector);
         this.steeringForceRotate.setDesiredHeading(this.nodeViewDirection + var1);
      } else if (this.viewSegments > 1) {
         float var5 = this.observationSector * 2.0F;
         float var2 = this.nodeViewDirection - this.observationSector;
         float var3 = var5 / (this.viewSegments - 1);
         int var4 = this.currentViewSegment++;
         this.currentViewSegment = this.currentViewSegment % this.viewSegments;
         this.steeringForceRotate.setDesiredHeading(var2 + var4 * var3);
      } else {
         this.steeringForceRotate.setDesiredHeading(this.nodeViewDirection + this.observationSector);
         this.observationSector *= -1.0F;
      }

      this.currentObservationDelay = this.nodeWaitTime * RandomExtra.randomRange(this.minDelayScale, this.maxDelayScale);
      this.currentObservationDelay = this.currentObservationDelay
         + this.currentObservationDelay * RandomExtra.randomRange(this.minPercentage, this.maxPercentage);
   }

   class="kw">protected boolean closeToPosition(Vector3d var1, @Nonnull MotionController var2) {
      class="kw">return var2.waypointDistanceSquared(this.currentPosition, var1) <= this.nodeWidth * this.nodeWidth;
   }

   class="kw">protected void invalidateWaypoint() {
      this.currentWaypointIndex = -1;
      this.currentDirection = null;
   }

   class="kw">protected boolean nextWayPoint(@Nonnull IPath<?> var1, @Nonnull WorldSupport var2, @Nonnull ComponentAccessor<EntityStore> var3) {
      if (this.currentWaypointIndex == -1) {
         class="kw">return false;
      }

      int var4 = var1.length();
      class="kw">switch (this.shape) {
         case LINE:
         case LOOP:
         case CHAIN:
            if (this.direction == BodyMotionPath.Direction.RANDOM || this.currentDirection == null) {
               this.currentDirection = RandomExtra.randomBoolean() ? BodyMotionPath.Direction.FORWARD : BodyMotionPath.Direction.BACKWARD;
            }

            this.currentWaypointIndex = this.currentWaypointIndex + (this.currentDirection == BodyMotionPath.Direction.FORWARD ? 1 : -1);
            if (this.currentWaypointIndex < 0 || this.currentWaypointIndex >= var4) {
               if (this.shape == BodyMotionPath.Shape.LOOP) {
                  this.currentWaypointIndex = (this.currentWaypointIndex + var4) % var4;
               } else if (this.currentWaypointIndex < 0) {
                  if (this.shape == BodyMotionPath.Shape.CHAIN) {
                     this.currentWaypointIndex = -1;
                     var2.requestNewPath();
                     class="kw">return false;
                  }

                  this.currentWaypointIndex = 1;
                  this.currentDirection = BodyMotionPath.Direction.FORWARD;
               } else if (this.currentWaypointIndex >= var4) {
                  if (this.shape == BodyMotionPath.Shape.CHAIN) {
                     this.currentWaypointIndex = -1;
                     var2.requestNewPath();
                     class="kw">return false;
                  }

                  this.currentWaypointIndex = var4 - 2;
                  this.currentDirection = BodyMotionPath.Direction.BACKWARD;
               }
            }
            break;
         case POINTS:
            if (this.direction == BodyMotionPath.Direction.RANDOM) {
               int var5 = RandomExtra.randomRange(var4);
               if (var5 == this.currentWaypointIndex) {
                  var5 = (var5 + RandomExtra.randomRange(2) * 2 - 1 + var4) % var4;
               }

               this.currentWaypointIndex = var5;
            } else {
               this.visitIndex++;
               if (this.visitIndex >= this.visitOrder.size()) {
                  this.visitIndex = 0;
                  IntLists.shuffle(this.visitOrder, ThreadLocalRandom.current());
               }

               if (this.visitOrder.getInt(this.visitIndex) == this.currentWaypointIndex) {
                  this.visitIndex++;
               }

               this.currentWaypointIndex = this.visitOrder.getInt(this.visitIndex);
            }

            this.currentDirection = BodyMotionPath.Direction.FORWARD;
      }

      this.waypointIndexUpdated(var1, var3);
      class="kw">return true;
   }

   class="kw">protected boolean getFirstWaypoint(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull ExecutionSupport var2,
      @Nullable IPath<?> var3,
      @Nonnull Vector3d var4,
      @Nonnull ComponentAccessor<EntityStore> var5
   ) {
      this.invalidateWaypoint();
      if (var3 != null && var3.length() != 0) {
         this.initializeCurrentDirection();
         if (this.startAtNearestNode) {
            double var6 = Double.MAX_VALUE;
            TransformComponent var8 = var5.getComponent(var1, TransformComponent.getComponentType());
            assert var8 != null;
            Vector3d var9 = var8.getPosition();
            MotionController var10 = var2.getMotionContextSupport().getActiveMotionController();

            for (int var11 = 0; var11 < var3.length(); var11++) {
               IPathWaypoint var12 = var3.get(var11);
               if (var12 == null) {
                  class="kw">return false;
               }

               double var13 = var10.waypointDistanceSquared(var9, var12.getWaypointPosition(var5));
               if (var13 < var6) {
                  this.currentWaypointIndex = var11;
                  var6 = var13;
               }
            }

            class="kw">switch (this.shape) {
               case LINE:
               case CHAIN:
                  if (this.currentWaypointIndex == 0) {
                     this.currentDirection = BodyMotionPath.Direction.FORWARD;
                  } else if (this.currentWaypointIndex == var3.length() - 1) {
                     this.currentDirection = BodyMotionPath.Direction.BACKWARD;
                  }
               case LOOP:
               class="kw">default:
                  break;
               case POINTS:
                  if (this.direction != BodyMotionPath.Direction.RANDOM) {
                     IntLists.shuffle(this.visitOrder, ThreadLocalRandom.current());
                     this.visitIndex = this.visitOrder.indexOf(this.currentWaypointIndex);
                  }
            }
         } else {
            class="kw">switch (this.shape) {
               case LINE:
               case CHAIN:
                  this.currentWaypointIndex = this.currentDirection == BodyMotionPath.Direction.FORWARD ? 0 : var3.length() - 1;
                  break;
               case LOOP:
                  this.currentWaypointIndex = 0;
                  break;
               case POINTS:
                  if (this.direction != BodyMotionPath.Direction.RANDOM) {
                     IntLists.shuffle(this.visitOrder, ThreadLocalRandom.current());
                     this.visitIndex = 0;
                     this.currentWaypointIndex = this.visitOrder.getInt(this.visitIndex);
                  } else {
                     this.currentWaypointIndex = RandomExtra.randomRange(var3.length());
                  }
            }
         }

         this.waypointIndexUpdated(var3, var5);
         this.lastWaypointPosition.set(var4.x(), var4.y(), var4.z());
         class="kw">return true;
      } else {
         class="kw">return false;
      }
   }

   class="kw">protected void waypointIndexUpdated(@Nonnull IPath<?> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      IPathWaypoint var3 = var1.get(this.currentWaypointIndex);
      if (var3 != null) {
         Vector3d var4 = var3.getWaypointPosition(var2);
         this.currentWaypointPosition.set(var4);
      }
   }

   class="kw">protected void initializeCurrentDirection() {
      if (this.direction != BodyMotionPath.Direction.RANDOM && this.direction != BodyMotionPath.Direction.ANY) {
         this.currentDirection = this.direction;
      } else {
         this.currentDirection = RandomExtra.randomBoolean() ? BodyMotionPath.Direction.FORWARD : BodyMotionPath.Direction.BACKWARD;
      }
   }

   class="kw">protected void reset() {
      this.pendingNodeDelay = false;
      this.currentNodeDelay = 0.0;
      this.nextPositionValid = false;
      this.currentViewSegment = 0;
      this.nodeWaitTime = 0.0;
      this.rotating = false;
   }

   class="kw">public enum Direction class="kw">implements Supplier<String> {
      FORWARD("Start visiting nodes in order"),
      BACKWARD("Start visiting nodes in reverse order "),
      RANDOM("Can change direction between nodes and randomly pick target node in Points shape mode"),
      ANY("Pick any start direction");

      class="kw">private class="kw">final String description;

      Direction(String nullxx) {
         this.description = nullxx;
      }

      class="kw">public String get() {
         class="kw">return this.description;
      }
   }

   class="kw">public enum Shape class="kw">implements Supplier<String> {
      LINE("Nodes form an open path of line segments"),
      LOOP("Nodes form a closed loop of line segments (last node leads to first node)"),
      POINTS("Any path between nodes is possible"),
      CHAIN("Nodes form an open path of line segments and will chain together with the next nearest path upon reaching the class="kw">final node");

      class="kw">private class="kw">final String description;

      Shape(String nullxx) {
         this.description = nullxx;
      }

      class="kw">public String get() {
         class="kw">return this.description;
      }
   }
}