content: package emu.grasscutter.data.excels;
  
  import java.util.List;
  
  import emu.grasscutter.data.GameData;
  import emu.grasscutter.data.GameResource;
  import emu.grasscutter.data.ResourceType;
  import emu.grasscutter.data.ResourceType.LoadPriority;
  import emu.grasscutter.data.binout.AbilityEmbryoEntry;
  import emu.grasscutter.data.common.PropGrowCurve;
  import emu.grasscutter.game.props.FightProperty;
  import emu.grasscutter.game.props.WeaponType;
  import emu.grasscutter.utils.Utils;
  import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
  import it.unimi.dsi.fastutil.ints.IntArrayList;
  import it.unimi.dsi.fastutil.ints.IntList;
  import lombok.Getter;
  
  @ResourceType(name = "AvatarExcelConfigData.json", loadPriority = LoadPriority.LOW)
  public class AvatarData extends GameResource {
  
      private String iconName;
      @Getter private String bodyType;
      @Getter private String qualityType;
      @Getter private int chargeEfficiency;
      @Getter private int initialWeapon;
      @Getter private WeaponType weaponType;
      @Getter private String imageName;
      @Getter private int avatarPromoteId;
      @Getter private String cutsceneShow;
      @Getter private int skillDepotId;
      @Getter private int staminaRecoverSpeed;
      @Getter private List<String> candSkillDepotIds;
      @Getter private String avatarIdentityType;
      @Getter private List<Integer> avatarPromoteRewardLevelList;
      @Getter private List<Integer> avatarPromoteRewardIdList;
  
      @Getter private long nameTextMapHash;
  
      private float hpBase;
      private float attackBase;
      private float defenseBase;
      private float critical;
      private float criticalHurt;
  
      private List<PropGrowCurve> propGrowCurves;
      @Getter(onMethod = @__(@Override))
      private int id;
  
      // Transient
      @Getter private String name;
  
      private Int2ObjectMap<String> growthCurveMap;
      private float[] hpGrowthCurve;
      private float[] attackGrowthCurve;
      private float[] defenseGrowthCurve;
      @Getter private AvatarSkillDepotData skillDepot;
      @Getter private IntList abilities;
  
      @Getter private List<Integer> fetters;
      @Getter private int nameCardRewardId;
      @Getter private int nameCardId;
  
      public float getBaseHp(int level) {
          try {
              return this.hpBase * this.hpGrowthCurve[level - 1];
          } catch (Exception e) {
              return this.hpBase;
          }
      }
  
      public float getBaseAttack(int level) {
          try {
              return this.attackBase * this.attackGrowthCurve[level - 1];
          } catch (Exception e) {
              return this.attackBase;
          }
      }
  
      public float getBaseDefense(int level) {
          try {
              return this.defenseBase * this.defenseGrowthCurve[level - 1];
          } catch (Exception e) {
              return this.defenseBase;
          }
      }
  
      public float getBaseCritical() {
          return this.critical;
      }
  
      public float getBaseCriticalHurt() {
          return this.criticalHurt;
      }
  
      public float getGrowthCurveById(int level, FightProperty prop) {
          String growCurve = this.growthCurveMap.get(prop.getId());
          if (growCurve == null) {
              return 1f;
          }
          AvatarCurveData curveData = GameData.getAvatarCurveDataMap().get(level);
          if (curveData == null) {
              return 1f;
          }
          return curveData.getCurveInfos().getOrDefault(growCurve, 1f);
      }
  
      @Override
      public void onLoad() {
          this.skillDepot = GameData.getAvatarSkillDepotDataMap().get(this.skillDepotId);
  
          // Get fetters from GameData
          this.fetters = GameData.getFetterDataEntries().get(this.id);
  
          if (GameData.getFetterCharacterCardDataMap().get(this.id) != null) {
              this.nameCardRewardId = GameData.getFetterCharacterCardDataMap().get(this.id).getRewardId();
          }
  
          if (GameData.getRewardDataMap().get(this.nameCardRewardId) != null) {
              this.nameCardId = GameData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
          }
  
          int size = GameData.getAvatarCurveDataMap().size();
          this.hpGrowthCurve = new float[size];
          this.attackGrowthCurve = new float[size];
          this.defenseGrowthCurve = new float[size];
          for (AvatarCurveData curveData : GameData.getAvatarCurveDataMap().values()) {
              int level = curveData.getLevel() - 1;
              for (PropGrowCurve growCurve : this.propGrowCurves) {
                  FightProperty prop = FightProperty.getPropByName(growCurve.getType());
                  switch (prop) {
                      case FIGHT_PROP_BASE_HP:
                          this.hpGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
                          break;
                      case FIGHT_PROP_BASE_ATTACK:
                          this.attackGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
                          break;
                      case FIGHT_PROP_BASE_DEFENSE:
                          this.defenseGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
                          break;
                      default:
                          break;
                  }
              }
          }
  
          /*
          for (PropGrowCurve growCurve : this.PropGrowCurves) {
              FightProperty prop = FightProperty.getPropByName(growCurve.getType());
              this.growthCurveMap.put(prop.getId(), growCurve.getGrowCurve());
          }
          */
  
          // Cache abilities
          String[] split = this.iconName.split("_");
          if (split.length > 0) {
              this.name = split[split.length - 1];
  
              AbilityEmbryoEntry info = GameData.getAbilityEmbryoInfo().get(this.name);
              if (info != null) {
                  this.abilities = new IntArrayList(info.getAbilities().length);
                  for (String ability : info.getAbilities()) {
                      this.abilities.add(Utils.abilityHash(ability));
                  }
              }
          }
      }
  }
  
  