ScanState class

Пакет: com.hypixel.hytale.server.core.modules.interaction.interaction.config.server

Файл: com/hypixel/hytale/server/core/modules/interaction/interaction/config/server/RevealMapMarkersInViewInteraction.java

implements: TriIntObjectConsumer<String>

Поля (7)

МодификаторыТипИмя
private ComponentAccessor<EntityStore> componentAccessor
private boolean conditionsHeld
private final Vector3d markerCenter
private float nextScanTime
private final List<Ref<EntityStore>> particleTargets
private WorldParticle[] particles
private Player player

Методы (4)

МодификаторыВозвратСигнатура
public void acceptpublic void accept(int var1, int var2, int var3, @Nonnull String var4)
public void beginpublic void begin(@Nonnull Player var1, @Nonnull Ref<EntityStore> var2, @Nonnull ComponentAccessor<EntityStore> var3, @Nullable WorldParticle[] var4)
public void endpublic void end()
if if(this.particles != null)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.modules.interaction.interaction.config.server;

class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.function.consumer.TriIntObjectConsumer;
class="kw">import com.hypixel.hytale.protocol.InteractionState;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.WaitForDataFrom;
class="kw">import com.hypixel.hytale.server.core.asset.type.particle.config.WorldParticle;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionContext;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.meta.DynamicMetaStore;
class="kw">import com.hypixel.hytale.server.core.meta.MetaKey;
class="kw">import com.hypixel.hytale.server.core.modules.entity.condition.Condition;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.time.TimeResource;
class="kw">import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldmap.markers.DiscoverableMapMarkers;
class="kw">import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
class="kw">import java.time.Instant;
class="kw">import java.util.Arrays;
class="kw">import java.util.List;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class RevealMapMarkersInViewInteraction class="kw">extends SimpleInteraction {
   class="kw">private class="kw">static class="kw">final float DEFAULT_FIELD_OF_VIEW = 30.0F;
   class="kw">private class="kw">static class="kw">final float MIN_FIELD_OF_VIEW = 0.0F;
   class="kw">private class="kw">static class="kw">final float MAX_FIELD_OF_VIEW = 360.0F;
   class="kw">private class="kw">static class="kw">final double DEFAULT_MAX_DISTANCE = 128.0;
   class="kw">private class="kw">static class="kw">final double MAX_DISTANCE_LIMIT = Double.MAX_VALUE;
   class="kw">private class="kw">static class="kw">final float DEFAULT_SCAN_INTERVAL = 0.25F;
   class="kw">private class="kw">static class="kw">final float DEFAULT_CONDITION_GRACE = 1.0F;
   class="kw">private class="kw">static class="kw">final float MAX_SCAN_INTERVAL = 60.0F;
   class="kw">private class="kw">static class="kw">final float MAX_CONDITION_GRACE = 60.0F;
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<RevealMapMarkersInViewInteraction> CODEC = BuilderCodec.builder(
         RevealMapMarkersInViewInteraction.class, RevealMapMarkersInViewInteraction::new, SimpleInteraction.CODEC
      )
      .documentation("Reveals the discoverable world map markers that sit inside the view cone of the player.")
      .<Float>appendInherited(
         new KeyedCodec<>("FieldOfView", Codec.FLOAT),
         (var0, var1) -> var0.fieldOfView = var1,
         var0 -> var0.fieldOfView,
         (var0, var1) -> var0.fieldOfView = var1.fieldOfView
      )
      .documentation(
         "The full angle of the view cone in degrees. A marker is found when it sits within half this angle of the look direction. Keep it narrow for a tool the player has to aim."
      )
      .addValidator(Validators.greaterThan(0.0F))
      .addValidator(Validators.max(360.0F))
      .add()
      .<Double>appendInherited(
         new KeyedCodec<>("MaxDistance", Codec.DOUBLE),
         (var0, var1) -> var0.maxDistance = var1,
         var0 -> var0.maxDistance,
         (var0, var1) -> var0.maxDistance = var1.maxDistance
      )
      .documentation(
         "The maximum distance in blocks from the eye position of the player. This is not an occlusion test, so a marker behind terrain is still found. It must be a finite distance."
      )
      .addValidator(Validators.greaterThan(0.0))
      .addValidator(Validators.max(Double.MAX_VALUE))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("ScanInterval", Codec.FLOAT),
         (var0, var1) -> var0.scanInterval = var1,
         var0 -> var0.scanInterval,
         (var0, var1) -> var0.scanInterval = var1.scanInterval
      )
      .documentation(
         "The time in seconds between scans. The first scan runs immediately. One scan tests every marker of the world, so a short interval costs more on a world with many markers. A value of 0 scans on every tick. The run ends on a scan, so this also bounds how long it takes to end."
      )
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .addValidator(Validators.max(60.0F))
      .add()
      .<Condition[]>appendInherited(
         new KeyedCodec<>("RunWhile", new ArrayCodec<>(Condition.CODEC, Condition[]::new)),
         (var0, var1) -> var0.runWhile = var1 != null && var1.length != 0 ? var1 : null,
         var0 -> var0.runWhile,
         (var0, var1) -> var0.runWhile = var1.runWhile
      )
      .documentation(
         "Conditions that must all hold for the scanning to class="kw">continue. The interaction finishes on the first scan where one of them fails. Leave this out, or give an empty list, to scan once."
      )
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("ConditionGrace", Codec.FLOAT),
         (var0, var1) -> var0.conditionGrace = var1,
         var0 -> var0.conditionGrace,
         (var0, var1) -> var0.conditionGrace = var1.conditionGrace
      )
      .documentation(
         "The time in seconds the `RunWhile` conditions have to start holding in. This does nothing without `RunWhile`. Raise it above the windup of the interaction this runs beside, or that windup ends the run before the conditions ever hold. A value of 0 ends the run on the first scan where they do not hold."
      )
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .addValidator(Validators.max(60.0F))
      .add()
      .<WorldParticle[]>appendInherited(
         new KeyedCodec<>("RevealParticles", WorldParticle.ARRAY_CODEC),
         (var0, var1) -> var0.revealParticles = var1,
         var0 -> var0.revealParticles,
         (var0, var1) -> var0.revealParticles = var1.revealParticles
      )
      .documentation(
         "Particle systems to spawn on the marker block when the player reveals it. Only the player who found the marker sees them, because discovery is per player."
      )
      .add()
      .build();
   @Nonnull
   class="kw">private class="kw">static class="kw">final MetaKey<RevealMapMarkersInViewInteraction.ScanState> SCAN_STATE = Interaction.META_REGISTRY.registerMetaObject(var0 -> null);
   class="kw">private float fieldOfView = 30.0F;
   class="kw">private double maxDistance = 128.0;
   class="kw">private float scanInterval = 0.25F;
   class="kw">private float conditionGrace = 1.0F;
   @Nullable
   class="kw">private Condition[] runWhile;
   @Nullable
   class="kw">private WorldParticle[] revealParticles;

   class="kw">public RevealMapMarkersInViewInteraction() {
   }

   @Nonnull
   @Override
   class="kw">public WaitForDataFrom getWaitForDataFrom() {
      class="kw">return WaitForDataFrom.Server;
   }

   @Override
   class="kw">protected void tick0(boolean var1, float var2, @Nonnull InteractionType var3, @Nonnull InteractionContext var4, @Nonnull CooldownHandler var5) {
      CommandBuffer var6 = var4.getCommandBuffer();
      assert var6 != null;
      Ref var7 = var4.getOwningEntity();
      if (var7 == null) {
         this.end(InteractionState.Failed, var1, var2, var3, var4, var5);
      } else {
         Player var8 = var6.getComponent(var7, Player.getComponentType());
         if (var8 == null) {
            this.end(InteractionState.Failed, var1, var2, var3, var4, var5);
         } else {
            DynamicMetaStore var9 = var4.getInstanceStore();
            RevealMapMarkersInViewInteraction.ScanState var10 = var9.getIfPresentMetaObject(SCAN_STATE);
            if (var1 || var10 == null) {
               var10 = new RevealMapMarkersInViewInteraction.ScanState();
               var9.putMetaObject(SCAN_STATE, var10);
            }

            if (var2 < var10.nextScanTime) {
               var4.getState().state = InteractionState.NotFinished;
            } else {
               float var11 = var10.nextScanTime + this.scanInterval;
               var10.nextScanTime = var11 > var2 ? var11 : var2 + this.scanInterval;
               if (!this.shouldContinue(var10, var2, var7, var6)) {
                  this.end(InteractionState.Finished, var1, var2, var3, var4, var5);
               } else {
                  this.scan(var8, var7, var6, var10);
                  if (this.runWhile == null) {
                     this.end(InteractionState.Finished, var1, var2, var3, var4, var5);
                  } else {
                     var4.getState().state = InteractionState.NotFinished;
                  }
               }
            }
         }
      }
   }

   @Override
   class="kw">protected void simulateTick0(boolean var1, float var2, @Nonnull InteractionType var3, @Nonnull InteractionContext var4, @Nonnull CooldownHandler var5) {
      var4.getState().state = var4.getServerState().state;
      super.tick0(var1, var2, var3, var4, var5);
   }

   class="kw">private boolean shouldContinue(
      @Nonnull RevealMapMarkersInViewInteraction.ScanState var1, float var2, @Nonnull Ref<EntityStore> var3, @Nonnull ComponentAccessor<EntityStore> var4
   ) {
      if (this.runWhile == null) {
         class="kw">return true;
      }

      Instant var5 = var4.getResource(TimeResource.getResourceType()).getNow();
      boolean var6 = Condition.allConditionsMet(var4, var3, var5, this.runWhile);
      boolean var7 = continuesRunning(var6, var1.conditionsHeld, var2, this.conditionGrace);
      if (var6) {
         var1.conditionsHeld = true;
      }

      class="kw">return var7;
   }

   class="kw">static boolean continuesRunning(boolean var0, boolean var1, float var2, float var3) {
      class="kw">return var0 ? true : !var1 && var2 < var3;
   }

   class="kw">private void scan(
      @Nonnull Player var1,
      @Nonnull Ref<EntityStore> var2,
      @Nonnull ComponentAccessor<EntityStore> var3,
      @Nonnull RevealMapMarkersInViewInteraction.ScanState var4
   ) {
      var4.begin(var1, var2, var3, this.revealParticles);

      try {
         DiscoverableMapMarkers.forEachMarkerInView(var1, var3, this.fieldOfView, this.maxDistance, false, var4);
      } class="kw">finally {
         var4.end();
      }
   }

   class="kw">private void end(
      @Nonnull InteractionState var1, boolean var2, float var3, @Nonnull InteractionType var4, @Nonnull InteractionContext var5, @Nonnull CooldownHandler var6
   ) {
      var5.getState().state = var1;
      super.tick0(var2, var3, var4, var5, var6);
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "RevealMapMarkersInViewInteraction{fieldOfView="
         + this.fieldOfView
         + ", maxDistance="
         + this.maxDistance
         + ", scanInterval="
         + this.scanInterval
         + ", conditionGrace="
         + this.conditionGrace
         + ", runWhile="
         + Arrays.toString(this.runWhile)
         + ", revealParticles="
         + Arrays.toString(this.revealParticles)
         + "} "
         + super.toString();
   }

   class="kw">private class="kw">static class ScanState class="kw">implements TriIntObjectConsumer<String> {
      class="kw">private float nextScanTime;
      class="kw">private boolean conditionsHeld;
      @Nullable
      class="kw">private Player player;
      @Nullable
      class="kw">private ComponentAccessor<EntityStore> componentAccessor;
      @Nullable
      class="kw">private WorldParticle[] particles;
      @Nonnull
      class="kw">private class="kw">final List<Ref<EntityStore>> particleTargets = new ReferenceArrayList(1);
      @Nonnull
      class="kw">private class="kw">final Vector3d markerCenter = new Vector3d();

      class="kw">private ScanState() {
      }

      class="kw">public void begin(@Nonnull Player var1, @Nonnull Ref<EntityStore> var2, @Nonnull ComponentAccessor<EntityStore> var3, @Nullable WorldParticle[] var4) {
         this.player = var1;
         this.componentAccessor = var3;
         this.particles = var4;
         this.particleTargets.clear();
         this.particleTargets.add(var2);
      }

      class="kw">public void end() {
         this.player = null;
         this.componentAccessor = null;
         this.particles = null;
         this.particleTargets.clear();
      }

      class="kw">public void accept(int var1, int var2, int var3, @Nonnull String var4) {
         assert this.player != null : "Scan state not initialized";
         assert this.componentAccessor != null : "Scan state not initialized";
         if (DiscoverableMapMarkers.reveal(this.player, var4)) {
            if (this.particles != null) {
               this.markerCenter.set(var1 + 0.5, var2 + 0.5, var3 + 0.5);
               ParticleUtil.spawnParticleEffects(this.particles, this.markerCenter, null, this.particleTargets, this.componentAccessor);
            }
         }
      }
   }
}