ChargingTag class

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

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

implements: CollectorTag

Поля (2)

МодификаторыТипИмя
private final float seconds
ChargingInteraction.ChargingTag var2

Методы (6)

МодификаторыВозвратСигнатура
public boolean equalspublic boolean equals(@Nullable Object var1)
public double getSecondspublic double getSeconds()
public int hashCodepublic int hashCode()
if if(this == var1)
public static ChargingInteraction.ChargingTag ofpublic static ChargingInteraction.ChargingTag of(float var0)
public String toStringpublic String toString()

Исходный код

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

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.map.EnumMapCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.Float2ObjectMapCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.protocol.ChargingDelay;
class="kw">import com.hypixel.hytale.protocol.InteractionState;
class="kw">import com.hypixel.hytale.protocol.InteractionSyncData;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.WaitForDataFrom;
class="kw">import com.hypixel.hytale.server.core.entity.EntityUtils;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionChain;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionContext;
class="kw">import com.hypixel.hytale.server.core.entity.InteractionManager;
class="kw">import com.hypixel.hytale.server.core.entity.damage.DamageDataComponent;
class="kw">import com.hypixel.hytale.server.core.meta.MetaKey;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.IInteractionSimulationHandler;
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.RootInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.Collector;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.CollectorTag;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.StringTag;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.Label;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.operation.OperationsBuilder;
class="kw">import com.hypixel.hytale.server.core.modules.time.TimeResource;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.floats.Float2IntOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.floats.Float2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.floats.Float2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.floats.FloatIterator;
class="kw">import it.unimi.dsi.fastutil.objects.Object2IntMap;
class="kw">import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import java.util.Arrays;
class="kw">import java.util.Map;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class ChargingInteraction class="kw">extends Interaction {
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<ChargingDelay> DELAY_CODEC = BuilderCodec.<ChargingDelay>builder(ChargingDelay.class, ChargingDelay::new)
      .documentation(
         "Configuration for delay when the user is attacked.\nThe delay will be between **MinDelay** when the incoming at **MinHealth** and **MaxDelay** when the incoming damage is at or above **MaxHealth**."
      )
      .<Float>appendInherited(
         new KeyedCodec<>("MinDelay", Codec.FLOAT), (var0, var1) -> var0.minDelay = var1, var0 -> var0.minDelay, (var0, var1) -> var0.minDelay = var1.minDelay
      )
      .documentation("The smallest amount of delay that can be applied.")
      .addValidator(Validators.nonNull())
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MaxDelay", Codec.FLOAT), (var0, var1) -> var0.maxDelay = var1, var0 -> var0.maxDelay, (var0, var1) -> var0.maxDelay = var1.maxDelay
      )
      .documentation("The largest amount of delay that can be applied.")
      .addValidator(Validators.nonNull())
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MaxTotalDelay", Codec.FLOAT),
         (var0, var1) -> var0.maxTotalDelay = var1,
         var0 -> var0.maxTotalDelay,
         (var0, var1) -> var0.maxTotalDelay = var1.maxTotalDelay
      )
      .documentation("The max amount of delay applied during this interaction before any additional delay is ignored.")
      .addValidator(Validators.nonNull())
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MinHealth", Codec.FLOAT),
         (var0, var1) -> var0.minHealth = var1,
         var0 -> var0.minHealth,
         (var0, var1) -> var0.minHealth = var1.minHealth
      )
      .documentation("The amount of health (as a percentage between 1.0 and 0.0) where if the user's health is below the value then the delay wont be applied.")
      .addValidator(Validators.nonNull())
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MaxHealth", Codec.FLOAT),
         (var0, var1) -> var0.maxHealth = var1,
         var0 -> var0.maxHealth,
         (var0, var1) -> var0.maxHealth = var1.maxHealth
      )
      .documentation("The amount of health (as a percentage between 1.0 and 0.0) where if the user's health is above the value then the delay will be capped.")
      .addValidator(Validators.nonNull())
      .addValidator(Validators.greaterThanOrEqual(0.0F))
      .add()
      .build();
   class="kw">public class="kw">static class="kw">final BuilderCodec<ChargingInteraction> ABSTRACT_CODEC = BuilderCodec.abstractBuilder(ChargingInteraction.class, Interaction.ABSTRACT_CODEC)
      .appendInherited(
         new KeyedCodec<>("FailOnDamage", Codec.BOOLEAN),
         (var0, var1) -> var0.failOnDamage = var1,
         var0 -> var0.failOnDamage,
         (var0, var1) -> var0.failOnDamage = var1.failOnDamage
      )
      .documentation("Whether the interaction will be cancelled and the item removed when the entity takes damage")
      .add()
      .appendInherited(
         new KeyedCodec<>("CancelOnOtherClick", Codec.BOOLEAN),
         (var0, var1) -> var0.cancelOnOtherClick = var1,
         var0 -> var0.cancelOnOtherClick,
         (var0, var1) -> var0.cancelOnOtherClick = var1.cancelOnOtherClick
      )
      .add()
      .<Map<InteractionType, String>>appendInherited(
         new KeyedCodec<>("Forks", new EnumMapCodec<>(InteractionType.class, RootInteraction.CHILD_ASSET_CODEC)),
         (var0, var1) -> var0.forks = var1,
         var0 -> var0.forks,
         (var0, var1) -> var0.forks = var1.forks
      )
      .documentation(
         "A collection of interactions to fork into when the input associated with the interaction type is used.\n\nFor example listing a `Primary` interaction type here with interactions will allow the user to press the input tied to the `Primary` interaction type whilst holding the input used to run the current interaction to run the specified interactions. e.g. Having a shield that you can hold `Secondary` to block and whilst blocking press `Primary` to shield bash.\n\nThis does not cancel the current interaction when triggered but the `CancelOnOtherClick` check will still run and may cancel the interaction.\n\nThe existing forks will class="kw">continue to run even if this interaction ends."
      )
      .addValidatorLate(() -> RootInteraction.VALIDATOR_CACHE.getMapValueValidator().late())
      .add()
      .afterDecode(var0 -> {
         float var1 = 0.0F;
         if (var0.next != null) {
            FloatIterator var2 = var0.next.keySet().iterator();

            while (var2.hasNext()) {
               float var3 = var2.nextFloat();
               if (var3 > var1) {
                  var1 = var3;
               }
            }

            var0.sortedKeys = var0.next.keySet().toFloatArray();
            Arrays.sort(var0.sortedKeys);
         }

         var0.highestChargeValue = var1;
      })
      .<String>appendInherited(
         new KeyedCodec<>("Failed", Interaction.CHILD_ASSET_CODEC),
         (var0, var1) -> var0.failed = var1,
         var0 -> var0.failed,
         (var0, var1) -> var0.failed = var1.failed
      )
      .documentation("The interactions to run when this interaction fails.")
      .addValidatorLate(() -> VALIDATOR_CACHE.getValidator().late())
      .add()
      .build();
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<ChargingInteraction> CODEC = BuilderCodec.builder(ChargingInteraction.class, ChargingInteraction::new, ABSTRACT_CODEC)
      .documentation(
         "An interaction that holds until the key is released (or a time limit is reached) and executes different interactions based on how long the key was pressed."
      )
      .appendInherited(
         new KeyedCodec<>("AllowIndefiniteHold", Codec.BOOLEAN),
         (var0, var1) -> var0.allowIndefiniteHold = var1,
         var0 -> var0.allowIndefiniteHold,
         (var0, var1) -> var0.allowIndefiniteHold = var1.allowIndefiniteHold
      )
      .add()
      .appendInherited(
         new KeyedCodec<>("DisplayProgress", Codec.BOOLEAN),
         (var0, var1) -> var0.displayProgress = var1,
         var0 -> var0.displayProgress,
         (var0, var1) -> var0.displayProgress = var1.displayProgress
      )
      .add()
      .<Float2ObjectMap<String>>appendInherited(
         new KeyedCodec<>("Next", new Float2ObjectMapCodec<>(Interaction.CHILD_ASSET_CODEC, Float2ObjectOpenHashMap::new)),
         (var0, var1) -> var0.next = var1,
         var0 -> var0.next,
         (var0, var1) -> var0.next = var1.next
      )
      .addValidatorLate(() -> VALIDATOR_CACHE.getMapValueValidator().late())
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MouseSensitivityAdjustmentTarget", Codec.FLOAT),
         (var0, var1) -> var0.mouseSensitivityAdjustmentTarget = var1,
         var0 -> var0.mouseSensitivityAdjustmentTarget,
         (var0, var1) -> var0.mouseSensitivityAdjustmentTarget = var1.mouseSensitivityAdjustmentTarget
      )
      .documentation("What is the target modifier to apply to mouse sensitivity while this interaction is active.")
      .addValidator(Validators.range(0.0F, 1.0F))
      .add()
      .<Float>appendInherited(
         new KeyedCodec<>("MouseSensitivityAdjustmentDuration", Codec.FLOAT),
         (var0, var1) -> var0.mouseSensitivityAdjustmentDuration = var1,
         var0 -> var0.mouseSensitivityAdjustmentDuration,
         (var0, var1) -> var0.mouseSensitivityAdjustmentDuration = var1.mouseSensitivityAdjustmentDuration
      )
      .documentation("Override the global linear modifier adjustment with this as the time to go from 1.0 to 0.0.")
      .add()
      .<ChargingDelay>appendInherited(
         new KeyedCodec<>("Delay", DELAY_CODEC),
         (var0, var1) -> var0.chargingDelay = var1,
         var0 -> var0.chargingDelay,
         (var0, var1) -> var0.chargingDelay = var1.chargingDelay
      )
      .documentation("Settings that allow for delaying the charging interaction on damage.")
      .add()
      .build();
   class="kw">private class="kw">static class="kw">final MetaKey<Object2IntMap<InteractionType>> FORK_COUNTS = Interaction.META_REGISTRY.registerMetaObject(var0 -> new Object2IntOpenHashMap());
   class="kw">private class="kw">static class="kw">final MetaKey<InteractionChain> FORKED_CHAIN = Interaction.META_REGISTRY.registerMetaObject(var0 -> null);
   class="kw">private class="kw">static class="kw">final MetaKey<Long> CHARGE_START_NANOS = Interaction.META_REGISTRY.registerMetaObject(var0 -> 0L);
   class="kw">private class="kw">static class="kw">final float CHARGING_HELD = -1.0F;
   class="kw">private class="kw">static class="kw">final float CHARGING_CANCELED = -2.0F;
   class="kw">private class="kw">static class="kw">final float CHARGE_GRACE_SECONDS = 0.25F;
   class="kw">private class="kw">static class="kw">final StringTag TAG_FAILED = StringTag.of("Failed");
   class="kw">protected boolean allowIndefiniteHold;
   class="kw">protected boolean displayProgress = true;
   class="kw">protected boolean cancelOnOtherClick = true;
   class="kw">protected boolean failOnDamage;
   class="kw">protected float mouseSensitivityAdjustmentTarget = 1.0F;
   class="kw">protected float mouseSensitivityAdjustmentDuration = 1.0F;
   @Nullable
   class="kw">protected String failed;
   @Nullable
   class="kw">protected Float2ObjectMap<String> next;
   class="kw">protected float[] sortedKeys;
   class="kw">protected Map<InteractionType, String> forks;
   @Nullable
   class="kw">protected ChargingDelay chargingDelay;
   class="kw">protected float highestChargeValue;

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

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

   @Override
   class="kw">protected void tick0(boolean var1, float var2, @Nonnull InteractionType var3, @Nonnull InteractionContext var4, @Nonnull CooldownHandler var5) {
      InteractionSyncData var6 = var4.getClientState();
      if (var4.getClientState().state == InteractionState.Failed && var4.hasLabels()) {
         var4.getState().state = InteractionState.Failed;
         var4.jump(var4.getLabel(this.next != null ? this.next.size() : 0));
      } else {
         if (var1) {
            var4.getInstanceStore().putMetaObject(CHARGE_START_NANOS, System.nanoTime());
         }

         if (var6.forkCounts != null && this.forks != null) {
            Object2IntMap var7 = var4.getInstanceStore().getMetaObject(FORK_COUNTS);
            InteractionChain var8 = var4.getInstanceStore().getMetaObject(FORKED_CHAIN);
            if (var8 != null && var8.getServerState() != InteractionState.NotFinished) {
               var8 = null;
            }

            boolean var9 = true;

            for (Entry var11 : var6.forkCounts.entrySet()) {
               int var12 = var7.getInt(var11.getKey());
               String var13 = this.forks.get(var11.getKey());
               if (var8 == null && var12 < var11.getValue() && var13 != null) {
                  InteractionContext var14 = var4.duplicate();
                  var8 = var4.fork(var11.getKey(), var14, RootInteraction.getRootInteractionOrUnknown(var13), true);
                  var4.getInstanceStore().putMetaObject(FORKED_CHAIN, var8);
                  var7.put(var11.getKey(), ++var12);
               }

               var9 &= var12 == var11.getValue();
            }

            if (!var9) {
               var4.getState().state = InteractionState.NotFinished;
               class="kw">return;
            }
         }

         if (var6.chargeValue == -1.0F) {
            this.validateHoldDuration(var4);
            var4.getState().state = InteractionState.NotFinished;
         } else if (var6.chargeValue == -2.0F) {
            var4.getState().state = InteractionState.Finished;
         } else {
            var4.getState().state = InteractionState.Finished;
            float var15 = var6.chargeValue;
            this.validateChargeValue(var15, var4);
            if (this.next != null) {
               this.jumpToChargeValue(var4, var15);
               CommandBuffer var16 = var4.getCommandBuffer();
               assert var16 != null;
               Ref var17 = var4.getEntity();
               DamageDataComponent var18 = var16.getComponent(var17, DamageDataComponent.getComponentType());
               assert var18 != null;
               var18.setLastChargeTime(var16.getResource(TimeResource.getResourceType()).getNow());
            }
         }
      }
   }

   @Override
   class="kw">protected void simulateTick0(boolean var1, float var2, @Nonnull InteractionType var3, @Nonnull InteractionContext var4, @Nonnull CooldownHandler var5) {
      Ref var6 = var4.getEntity();
      IInteractionSimulationHandler var7 = var4.getInteractionManager().getInteractionSimulationHandler();
      if (var7.isCharging(var1, var2, var3, var4, var6, var5) && (this.allowIndefiniteHold || var2 < this.highestChargeValue)) {
         if (this.failOnDamage && var7.shouldCancelCharging(var1, var2, var3, var4, var6, var5)) {
            var4.getState().state = InteractionState.Failed;
            class="kw">return;
         }

         var4.getState().state = InteractionState.NotFinished;
      } else {
         var4.getState().state = InteractionState.Finished;
         float var8 = var7.getChargeValue(var1, var2, var3, var4, var6, var5);
         var4.getState().chargeValue = var8;
         if (this.next == null) {
            class="kw">return;
         }

         this.jumpToChargeValue(var4, var8);
      }
   }

   class="kw">private void jumpToChargeValue(@Nonnull InteractionContext var1, float var2) {
      float var3 = 2.1474836E9F;
      int var4 = -1;
      int var5 = 0;

      for (float var9 : this.sortedKeys) {
         if (var2 < var9) {
            var5++;
         } else {
            float var10 = var2 - var9;
            if (var4 == -1 || var10 < var3) {
               var3 = var10;
               var4 = var5;
            }

            var5++;
         }
      }

      if (var4 != -1) {
         var1.jump(var1.getLabel(var4));
      }
   }

   @Override
   class="kw">public void compile(@Nonnull OperationsBuilder var1) {
      Label var2 = var1.createUnresolvedLabel();
      Label[] var3 = new Label[(this.next != null ? this.next.size() : 0) + 1];

      for (int var4 = 0; var4 < var3.length; var4++) {
         var3[var4] = var1.createUnresolvedLabel();
      }

      var1.addOperation(this, var3);
      var1.jump(var2);
      if (this.sortedKeys != null) {
         for (int var7 = 0; var7 < this.sortedKeys.length; var7++) {
            float var5 = this.sortedKeys[var7];
            var1.resolveLabel(var3[var7]);
            Interaction var6 = Interaction.getInteractionOrUnknown((String)this.next.get(var5));
            var6.compile(var1);
            var1.jump(var2);
         }
      }

      int var8 = this.sortedKeys != null ? this.sortedKeys.length : 0;
      var1.resolveLabel(var3[var8]);
      if (this.failed != null) {
         Interaction var9 = Interaction.getInteractionOrUnknown(this.failed);
         var9.compile(var1);
      }

      var1.resolveLabel(var2);
   }

   @Override
   class="kw">public boolean walk(@Nonnull Collector var1, @Nonnull InteractionContext var2) {
      if (this.next != null) {
         ObjectIterator var3 = this.next.float2ObjectEntrySet().iterator();

         while (var3.hasNext()) {
            it.unimi.dsi.fastutil.floats.Float2ObjectMap.Entry var4 = (it.unimi.dsi.fastutil.floats.Float2ObjectMap.Entry<String>)var3.next();
            if (InteractionManager.walkInteraction(var1, var2, ChargingInteraction.ChargingTag.of(var4.getFloatKey()), (String)var4.getValue())) {
               class="kw">return true;
            }
         }
      }

      class="kw">return this.failed != null && InteractionManager.walkInteraction(var1, var2, TAG_FAILED, this.failed);
   }

   @Nonnull
   @Override
   class="kw">protected com.hypixel.hytale.protocol.Interaction generatePacket() {
      class="kw">return new com.hypixel.hytale.protocol.ChargingInteraction();
   }

   @Override
   class="kw">protected void configurePacket(com.hypixel.hytale.protocol.Interaction var1) {
      super.configurePacket(var1);
      com.hypixel.hytale.protocol.ChargingInteraction var2 = (com.hypixel.hytale.protocol.ChargingInteraction)var1;
      var2.allowIndefiniteHold = this.allowIndefiniteHold;
      var2.mouseSensitivityAdjustmentTarget = this.mouseSensitivityAdjustmentTarget;
      var2.mouseSensitivityAdjustmentDuration = this.mouseSensitivityAdjustmentDuration;
      var2.displayProgress = this.displayProgress;
      var2.cancelOnOtherClick = this.cancelOnOtherClick;
      var2.failOnDamage = this.failOnDamage;
      var2.failed = Interaction.getInteractionIdOrUnknown(this.failed);
      var2.chargingDelay = this.chargingDelay;
      if (this.next != null) {
         Float2IntOpenHashMap var3 = new Float2IntOpenHashMap();
         ObjectIterator var4 = this.next.float2ObjectEntrySet().iterator();

         while (var4.hasNext()) {
            it.unimi.dsi.fastutil.floats.Float2ObjectMap.Entry var5 = (it.unimi.dsi.fastutil.floats.Float2ObjectMap.Entry<String>)var4.next();
            var3.put(var5.getFloatKey(), Interaction.getInteractionIdOrUnknown((String)var5.getValue()));
         }

         var2.chargedNext = var3;
      }

      if (this.forks != null) {
         Object2IntOpenHashMap var6 = new Object2IntOpenHashMap();

         for (Entry var8 : this.forks.entrySet()) {
            var6.put(var8.getKey(), RootInteraction.getRootInteractionIdOrUnknown(var8.getValue()));
         }

         var2.forks = var6;
      }
   }

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

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "ChargingInteraction{allowIndefiniteHold="
         + this.allowIndefiniteHold
         + ", displayProgress="
         + this.displayProgress
         + ", mouseSensitivityAdjustmentTarget="
         + this.mouseSensitivityAdjustmentTarget
         + ", mouseSensitivityAdjustmentDuration="
         + this.mouseSensitivityAdjustmentDuration
         + ", cancelOnOtherClick="
         + this.cancelOnOtherClick
         + ", next="
         + this.next
         + ", forks="
         + this.forks
         + ", highestChargeValue="
         + this.highestChargeValue
         + ", failOnDamage="
         + this.failOnDamage
         + "} "
         + super.toString();
   }

   class="kw">private void validateChargeValue(float var1, @Nonnull InteractionContext var2) {
      Long var3 = var2.getInstanceStore().getMetaObject(CHARGE_START_NANOS);
      if (var3 != 0L) {
         CommandBuffer var4 = var2.getCommandBuffer();
         assert var4 != null;
         float var5 = (float)(System.nanoTime() - var3) / 1.0E9F;
         float var6 = var4.getResource(TimeResource.getResourceType()).getTimeDilationModifier();
         float var7 = var5 * var6 + 0.25F;
         if (!this.allowIndefiniteHold && this.highestChargeValue > 0.0F) {
            var7 = Math.min(var7, this.highestChargeValue);
         }

         if (var1 > var7) {
            LOGGER.at(Level.WARNING)
               .log(
                  "%s charge value %.3f exceeds max allowed %.3f (wall: %.3f, dilation: %.2f)",
                  EntityUtils.getEntityName(var2.getEntity(), var4),
                  var1,
                  var7,
                  var5,
                  var6
               );
         }
      }
   }

   class="kw">private void validateHoldDuration(@Nonnull InteractionContext var1) {
      if (!this.allowIndefiniteHold && !(this.highestChargeValue <= 0.0F)) {
         Long var2 = var1.getInstanceStore().getMetaObject(CHARGE_START_NANOS);
         if (var2 != 0L) {
            CommandBuffer var3 = var1.getCommandBuffer();
            assert var3 != null;
            float var4 = (float)(System.nanoTime() - var2) / 1.0E9F;
            float var5 = var3.getResource(TimeResource.getResourceType()).getTimeDilationModifier();
            if (var4 * var5 > this.highestChargeValue + 0.25F) {
               LOGGER.at(Level.WARNING)
                  .log(
                     "%s held charge %.3fs beyond max %.3f (wall: %.3f, dilation: %.2f)",
                     EntityUtils.getEntityName(var1.getEntity(), var3),
                     var4 * var5,
                     this.highestChargeValue,
                     var4,
                     var5
                  );
            }
         }
      }
   }

   class="kw">public class="kw">static class="kw">final class ChargingTag class="kw">implements CollectorTag {
      class="kw">private class="kw">final float seconds;

      class="kw">private ChargingTag(float var1) {
         this.seconds = var1;
      }

      class="kw">public double getSeconds() {
         class="kw">return this.seconds;
      }

      @Override
      class="kw">public boolean equals(@Nullable Object var1) {
         if (this == var1) {
            class="kw">return true;
         } else if (var1 != null && this.getClass() == var1.getClass()) {
            ChargingInteraction.ChargingTag var2 = (ChargingInteraction.ChargingTag)var1;
            class="kw">return Float.compare(var2.seconds, this.seconds) == 0;
         } else {
            class="kw">return false;
         }
      }

      @Override
      class="kw">public int hashCode() {
         class="kw">return this.seconds != 0.0F ? Float.floatToIntBits(this.seconds) : 0;
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "ChargingTag{seconds=" + this.seconds + "}";
      }

      @Nonnull
      class="kw">public class="kw">static ChargingInteraction.ChargingTag of(float var0) {
         class="kw">return new ChargingInteraction.ChargingTag(var0);
      }
   }
}