HitFrame class

Пакет: com.hypixel.hytale.server.core.asset.type.item.config.damageData

Файл: com/hypixel/hytale/server/core/asset/type/item/config/damageData/WeaponDamageDataCollector.java

Поля (7)

МодификаторыТипИмя
boolean aborted
boolean descended
float dmgMax
float dmgMin
DamageEntityInteraction pendingDamage
WeaponDamageDataCollector.HitFrame var1
Set<String> visited

Методы (1)

МодификаторыВозвратСигнатура
WeaponDamageDataCollector.HitFrame copyWeaponDamageDataCollector.HitFrame copy()

Исходный код

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

class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.Item;
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.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.client.ChargingInteraction;
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.config.server.DamageEntityInteraction;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.combat.DamageCalculator;
class="kw">import com.hypixel.hytale.server.core.modules.projectile.config.ProjectileConfig;
class="kw">import com.hypixel.hytale.server.core.modules.projectile.interaction.ProjectileInteraction;
class="kw">import java.util.ArrayDeque;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Deque;
class="kw">import java.util.HashSet;
class="kw">import java.util.LinkedHashMap;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Set;
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="kw">final class WeaponDamageDataCollector class="kw">implements Collector {
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final String LABEL_CHARGED = "charged";
   class="kw">private class="kw">static class="kw">final String LABEL_BACKSTAB = "backstab";
   class="kw">private class="kw">final Deque<WeaponDamageDataCollector.Frame> stack = new ArrayDeque<>();
   class="kw">private class="kw">final List<WeaponDamageDataCollector.Leaf> leaves = new ArrayList<>();
   class="kw">private class="kw">final float[] damageScratch = new float[2];
   @Nullable
   class="kw">private CollectorTag pendingTag;

   @Nonnull
   class="kw">public class="kw">static DamageBreakdown calculate(@Nonnull Item var0, @Nonnull InteractionType var1) {
      String var2 = var0.getInteractions().get(var1);
      if (var2 == null) {
         class="kw">return DamageBreakdown.EMPTY;
      }

      RootInteraction var3 = RootInteraction.getAssetMap().getAsset(var2);
      if (var3 == null) {
         class="kw">return DamageBreakdown.EMPTY;
      }

      try {
         InteractionContext var4 = InteractionContext.withoutEntity();
         var4.setInteractionVarsGetter(var1x -> var0.getInteractionVars());
         WeaponDamageDataCollector var5 = new WeaponDamageDataCollector();
         InteractionManager.walkChain(var5, var1, var4, var3);
         class="kw">return var5.build();
      } catch (Throwable var6) {
         ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var6)).log("Failed to fetch damage value for item %s", var0.getId());
         class="kw">return DamageBreakdown.EMPTY;
      }
   }

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

   @Override
   class="kw">public void start() {
      this.stack.clear();
      this.leaves.clear();
      this.pendingTag = null;
   }

   @Override
   class="kw">public void into(@Nonnull InteractionContext var1, @Nullable Interaction var2) {
      WeaponDamageDataCollector.Frame var3 = this.stack.peek();
      WeaponDamageDataCollector.Frame var4 = var3 != null ? var3.copy() : new WeaponDamageDataCollector.Frame();
      CollectorTag var5 = this.pendingTag;
      this.pendingTag = null;
      if (var5 class="kw">instanceof ChargingInteraction.ChargingTag var6) {
         var4.labelKey = var6.getSeconds() > 0.0 ? "charged" : null;
      } else if (var5 class="kw">instanceof DamageEntityInteraction.AngledDamageTag) {
         var4.labelKey = "backstab";
      } else if (var5 class="kw">instanceof DamageEntityInteraction.TargetedDamageTag var7) {
         var4.labelKey = "targeted." + var7.getKey();
      } else if (var5 class="kw">instanceof StringTag var8) {
         String var9 = var8.getTag();
         if ("Failed".equals(var9) || "Blocked".equals(var9)) {
            var4.labelKey = null;
         }
      }

      if (var2 != null) {
         if (!var4.visited.add(var2.getId())) {
            var4.aborted = true;
         } else if (var3 != null && var3.pendingDamage != null) {
            this.adjustDamageForChildEdge(var3.pendingDamage, var5, var4);
         }

         if (var2 class="kw">instanceof DamageEntityInteraction var10) {
            var4.pendingDamage = var10;
            this.applyDamage(var10.getDamageCalculator(), var10.getRunTime(), 1, var4);
         } else {
            var4.pendingDamage = null;
            if (var2 class="kw">instanceof ProjectileInteraction var11) {
               var4.labelKey = null;
               this.applyProjectileHitDamage(var11, var1, var4);
            }
         }
      }

      if (var3 != null) {
         var3.descended = true;
      }

      this.stack.push(var4);
   }

   @Override
   class="kw">public boolean collect(@Nonnull CollectorTag var1, @Nonnull InteractionContext var2, @Nonnull Interaction var3) {
      this.pendingTag = var1;
      class="kw">return false;
   }

   @Override
   class="kw">public void outof() {
      WeaponDamageDataCollector.Frame var1 = this.stack.pop();
      if (!var1.aborted && !var1.descended) {
         if (!(var1.totalDmgMax <= 0.0F)) {
            this.leaves.add(new WeaponDamageDataCollector.Leaf(var1.labelKey, var1.totalDmgMin, var1.totalDmgMax));
         }
      }
   }

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

   class="kw">private void adjustDamageForChildEdge(@Nonnull DamageEntityInteraction var1, @Nullable CollectorTag var2, @Nonnull WeaponDamageDataCollector.Frame var3) {
      float var4 = var1.getRunTime();
      DamageCalculator var5 = var1.getDamageCalculator();
      if (var2 class="kw">instanceof DamageEntityInteraction.AngledDamageTag var6) {
         this.applyDamage(var5, var4, -1, var3);
         DamageEntityInteraction.AngledDamage[] var9 = var1.getAngledDamage();
         if (var9 != null && var6.getIndex() < var9.length) {
            DamageEntityInteraction.AngledDamage var10 = var9[var6.getIndex()];
            DamageCalculator var11 = var10.getDamageCalculator() != null ? var10.getDamageCalculator() : var5;
            this.applyDamage(var11, var4, 1, var3);
         }
      } else if (var2 class="kw">instanceof DamageEntityInteraction.TargetedDamageTag var7) {
         this.applyDamage(var5, var4, -1, var3);
         DamageEntityInteraction.TargetedDamage var12 = var1.getTargetedDamage().get(var7.getKey());
         if (var12 != null) {
            DamageCalculator var14 = var12.getDamageCalculator() != null ? var12.getDamageCalculator() : var5;
            this.applyDamage(var14, var4, 1, var3);
         }
      } else if (var2 class="kw">instanceof StringTag var8) {
         String var13 = var8.getTag();
         if ("Failed".equals(var13) || "Blocked".equals(var13)) {
            this.applyDamage(var5, var4, -1, var3);
         }
      }
   }

   class="kw">private void applyDamage(@Nullable DamageCalculator var1, double var2, int var4, @Nonnull WeaponDamageDataCollector.Frame var5) {
      if (var1 != null) {
         var1.computeDamageRange(var2, this.damageScratch);
         var5.totalDmgMin = var5.totalDmgMin + var4 * this.damageScratch[0];
         var5.totalDmgMax = var5.totalDmgMax + var4 * this.damageScratch[1];
      }
   }

   class="kw">private void applyProjectileHitDamage(@Nonnull ProjectileInteraction var1, @Nonnull InteractionContext var2, @Nonnull WeaponDamageDataCollector.Frame var3) {
      ProjectileConfig var4 = var1.getConfig();
      if (var4 != null) {
         String var5 = var4.getInteractions().get(InteractionType.ProjectileHit);
         if (var5 != null) {
            RootInteraction var6 = RootInteraction.getAssetMap().getAsset(var5);
            if (var6 != null) {
               WeaponDamageDataCollector.HitDamageCollector var7 = new WeaponDamageDataCollector.HitDamageCollector();
               InteractionManager.walkChain(var7, InteractionType.ProjectileHit, var2, var6);
               var3.totalDmgMin = var3.totalDmgMin + var7.minDamage;
               var3.totalDmgMax = var3.totalDmgMax + var7.maxDamage;
            }
         }
      }
   }

   @Nonnull
   class="kw">private DamageBreakdown build() {
      if (this.leaves.isEmpty()) {
         class="kw">return DamageBreakdown.EMPTY;
      }

      Map var1 = new LinkedHashMap<>();

      for (WeaponDamageDataCollector.Leaf var3 : this.leaves) {
         String var4 = var3.labelKey == null ? "" : var3.labelKey;
         float[] var5 = var1.computeIfAbsent(var4, var0 -> new float[]{Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY});
         if (var3.totalDmgMin < var5[0]) {
            var5[0] = var3.totalDmgMin;
         }

         if (var3.totalDmgMax > var5[1]) {
            var5[1] = var3.totalDmgMax;
         }
      }

      if (!var1.containsKey("") && var1.containsKey("charged")) {
         var1.put("", var1.remove("charged"));
      }

      List var6 = new ArrayList<>(var1.size());
      float[] var7 = var1.remove("");
      if (var7 != null) {
         var6.add(new DamageBreakdown.Entry(null, var7[0], var7[1]));
      }

      for (Entry var9 : var1.entrySet()) {
         var6.add(new DamageBreakdown.Entry(var9.getKey(), var9.getValue()[0], var9.getValue()[1]));
      }

      class="kw">return new DamageBreakdown(var6);
   }

   class="kw">private class="kw">static class="kw">final class Frame {
      float totalDmgMin;
      float totalDmgMax;
      @Nullable
      String labelKey;
      @Nullable
      DamageEntityInteraction pendingDamage;
      @Nonnull
      Set<String> visited = new HashSet<>();
      boolean descended;
      boolean aborted;

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

      @Nonnull
      WeaponDamageDataCollector.Frame copy() {
         WeaponDamageDataCollector.Frame var1 = new WeaponDamageDataCollector.Frame();
         var1.totalDmgMin = this.totalDmgMin;
         var1.totalDmgMax = this.totalDmgMax;
         var1.labelKey = this.labelKey;
         var1.pendingDamage = this.pendingDamage;
         var1.visited = new HashSet<>(this.visited);
         var1.aborted = this.aborted;
         class="kw">return var1;
      }
   }

   class="kw">private class="kw">static class="kw">final class HitDamageCollector class="kw">implements Collector {
      class="kw">private class="kw">final Deque<WeaponDamageDataCollector.HitFrame> stack = new ArrayDeque<>();
      class="kw">private class="kw">final float[] scratch = new float[2];
      class="kw">private float minDamage;
      class="kw">private float maxDamage;
      @Nullable
      class="kw">private CollectorTag pendingTag;

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

      @Override
      class="kw">public void start() {
         this.stack.clear();
         this.minDamage = Float.POSITIVE_INFINITY;
         this.maxDamage = Float.NEGATIVE_INFINITY;
         this.pendingTag = null;
      }

      @Override
      class="kw">public void into(@Nonnull InteractionContext var1, @Nullable Interaction var2) {
         WeaponDamageDataCollector.HitFrame var3 = this.stack.peek();
         WeaponDamageDataCollector.HitFrame var4 = var3 != null ? var3.copy() : new WeaponDamageDataCollector.HitFrame();
         CollectorTag var5 = this.pendingTag;
         this.pendingTag = null;
         if (var2 != null) {
            if (!var4.visited.add(var2.getId())) {
               var4.aborted = true;
            } else if (var3 != null && var3.pendingDamage != null) {
               this.adjustDamageForEdge(var3.pendingDamage, var5, var4);
            }

            if (var2 class="kw">instanceof DamageEntityInteraction var6) {
               var4.pendingDamage = var6;
               this.applyToFrame(var6.getDamageCalculator(), var6.getRunTime(), 1, var4);
            } else {
               var4.pendingDamage = null;
            }
         }

         if (var3 != null) {
            var3.descended = true;
         }

         this.stack.push(var4);
      }

      @Override
      class="kw">public boolean collect(@Nonnull CollectorTag var1, @Nonnull InteractionContext var2, @Nonnull Interaction var3) {
         this.pendingTag = var1;
         class="kw">return false;
      }

      @Override
      class="kw">public void outof() {
         WeaponDamageDataCollector.HitFrame var1 = this.stack.pop();
         if (!var1.aborted && !var1.descended) {
            if (var1.dmgMax > 0.0F) {
               if (var1.dmgMin < this.minDamage) {
                  this.minDamage = var1.dmgMin;
               }

               if (var1.dmgMax > this.maxDamage) {
                  this.maxDamage = var1.dmgMax;
               }
            }
         }
      }

      @Override
      class="kw">public void finished() {
         if (this.minDamage == Float.POSITIVE_INFINITY) {
            this.minDamage = 0.0F;
            this.maxDamage = 0.0F;
         }
      }

      class="kw">private void adjustDamageForEdge(@Nonnull DamageEntityInteraction var1, @Nullable CollectorTag var2, @Nonnull WeaponDamageDataCollector.HitFrame var3) {
         float var4 = var1.getRunTime();
         DamageCalculator var5 = var1.getDamageCalculator();
         if (var2 class="kw">instanceof DamageEntityInteraction.AngledDamageTag var6) {
            this.applyToFrame(var5, var4, -1, var3);
            DamageEntityInteraction.AngledDamage[] var9 = var1.getAngledDamage();
            if (var9 != null && var6.getIndex() < var9.length) {
               DamageEntityInteraction.AngledDamage var10 = var9[var6.getIndex()];
               this.applyToFrame(var10.getDamageCalculator() != null ? var10.getDamageCalculator() : var5, var4, 1, var3);
            }
         } else if (var2 class="kw">instanceof DamageEntityInteraction.TargetedDamageTag var7) {
            this.applyToFrame(var5, var4, -1, var3);
            DamageEntityInteraction.TargetedDamage var11 = var1.getTargetedDamage().get(var7.getKey());
            if (var11 != null) {
               this.applyToFrame(var11.getDamageCalculator() != null ? var11.getDamageCalculator() : var5, var4, 1, var3);
            }
         } else if (var2 class="kw">instanceof StringTag var8) {
            String var12 = var8.getTag();
            if ("Failed".equals(var12) || "Blocked".equals(var12)) {
               this.applyToFrame(var5, var4, -1, var3);
            }
         }
      }

      class="kw">private void applyToFrame(@Nullable DamageCalculator var1, double var2, int var4, @Nonnull WeaponDamageDataCollector.HitFrame var5) {
         if (var1 != null) {
            var1.computeDamageRange(var2, this.scratch);
            var5.dmgMin = var5.dmgMin + var4 * this.scratch[0];
            var5.dmgMax = var5.dmgMax + var4 * this.scratch[1];
         }
      }
   }

   class="kw">private class="kw">static class="kw">final class HitFrame {
      float dmgMin;
      float dmgMax;
      @Nullable
      DamageEntityInteraction pendingDamage;
      @Nonnull
      Set<String> visited = new HashSet<>();
      boolean descended;
      boolean aborted;

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

      @Nonnull
      WeaponDamageDataCollector.HitFrame copy() {
         WeaponDamageDataCollector.HitFrame var1 = new WeaponDamageDataCollector.HitFrame();
         var1.dmgMin = this.dmgMin;
         var1.dmgMax = this.dmgMax;
         var1.pendingDamage = this.pendingDamage;
         var1.visited = new HashSet<>(this.visited);
         var1.aborted = this.aborted;
         class="kw">return var1;
      }
   }

   class="kw">private record Leaf(@Nullable String labelKey, float totalDmgMin, float totalDmgMax) {
      class="kw">private Leaf {
      }
   }
}