yyl
2 天以前 4b5b31a23a74c1559460643836d70778d7d49931
Main/System/Main/FightPowerManager.cs
@@ -1,236 +1,561 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using LitJson;
using Spine;
//!单英雄查看战力 只算自己的上阵属性  不算羁绊 总上阵属性  光环
// 战力的计算方式
//  先算上阵的单武将战力按公式一一算出各个属性(基础/战斗),再把算出来的各个属性代入到战力公式
//  所有武将战力加起来 + 技能战力汇总(公式)就是整个号的战力
public class FightPowerManager : Singleton<FightPowerManager>
{
    string propertyFormula;
    public string propertyFormula;
    public string fightPropertyFormula;
    public string fightPowerFormula;
    public string skillFightPowerFormula;
    Dictionary<string, double> propertyVariables = new Dictionary<string, double>();
    Dictionary<string, double> fightPowerVariables = new Dictionary<string, double>();  //总战力中的单武将战力
    public FightPowerManager()
    {
        // 数值1:基础三维属性计算公式
        // 数值2:战斗属性/战斗抗性/特殊属性计算公式
        // 数值3:属性战力计算公式,计算参数详见 S.属性条目配置
        var config = FuncConfigConfig.Get("HeroAttrFormula");
        propertyFormula = config.Numerical1;
        fightPropertyFormula = config.Numerical2;
        fightPowerFormula = config.Numerical3;
        skillFightPowerFormula = config.Numerical4;
        JaceCalculator.Init();
    }
    #region 初始化战力计算的信息
    TeamType teamTypeCalc = TeamType.Story; //不同阵容战力不同
    bool isPreviewTeamPower;  //预览阵容(队伍)战力
    int dropIndexCalc = -1; //掉落装备在阵容的索引,用于预览战力对比
    //装备战力为最终总战力的结果比(提升整个角色总战力)
    public int CalculatePower(int level)
    //计算阵容战力,装备对比等情况需要代入
    /// <summary>
    ///
    /// </summary>
    /// <param name="teamType">阵容类型</param>
    /// <param name="dropindex">掉落装备的索引,-1代表不替换计算</param>
    /// <param name="ispreview">预览阵容战力</param>
    public void InitFightPowerParam(TeamType teamType = TeamType.Story, int dropindex = -1, bool ispreview = false)
    {
        // Equation.Instance.Clear();
        // Equation.Instance.AddKeyValue("equipScoreTotal", CountEquipScore(level));
        // var power = Equation.Instance.Eval<int>(scoreFormula);
        teamTypeCalc = teamType;
        isPreviewTeamPower = ispreview;
        // var propertyContainer = new Properties();
        // Equation.Instance.Clear();
        // var keys = propertyContainer.keys;
        // for (int i = 0; i < keys.Count; i++)
        // {
        //     var id = keys[i];
        //     var value = propertyContainer[id];
        //     var config = PlayerPropertyConfig.Get(id);
        //     Equation.Instance.AddKeyValue(config.Parameter, value);
        // }
        // var propertyPower = Equation.Instance.Eval<int>(propertyFormula);
        // power += propertyPower;
        dropIndexCalc = dropindex;
#if UNITY_EDITOR
        Debug.Log("战力:初始化参数 dropIndex:" + dropIndexCalc + " 阵型:" + teamTypeCalc + " ispreview:" + ispreview);
#endif
    }
    #endregion
        return 0;
    #region 先计算所有功能的汇总属性
    //功能属性 类型:值
    public Dictionary<int, int> lvAttrs = new Dictionary<int, int>();  //等级属性
    public Dictionary<int, int> officialAttrs = new Dictionary<int, int>();  //官职属性
    //分开存储预览和 真实属性
    public Dictionary<int, int> equipAttrs = new Dictionary<int, int>();   //装备属性
    public Dictionary<string, int> lineUpPerDict = new Dictionary<string, int>();  //阵容属性加成
    public Dictionary<int, int> countryAttrs = new Dictionary<int, int>();   //阵容国家(光环)属性
    //等级属性
    void RefreshLVAttrs()
    {
        lvAttrs.Clear();
        var playerLVConfig = PlayerLVConfig.Get(PlayerDatas.Instance.baseData.LV);
        foreach (var attrType in PlayerPropertyConfig.baseAttrs)
        {
            lvAttrs[attrType] = GetPlayerLVValue(playerLVConfig, attrType);
        }
#if UNITY_EDITOR
        Debug.Log("战力:等级属性 " + JsonMapper.ToJson(lvAttrs));
#endif
    }
    //和身上装备对比
    public long GetFightPowerChange(ItemModel item)
    public int GetPlayerLVValue(PlayerLVConfig config, int type)
    {
        if (type == 6)
        {
            return config.Atk;
        }
        else if (type == 7)
        {
            return config.Def;
        }
        else if (type == 8)
        {
            return config.MaxHP;
        }
        return 0;
    }
    class Properties
    //官职属性
    void RefreshOfficialAttrs()
    {
        Dictionary<int, int> tables = new Dictionary<int, int>();
        public List<int> keys { get { return new List<int>(tables.Keys); } }
        public int this[int id] { get { return tables[id]; } }
        public void Add(int id, int value)
        officialAttrs.Clear();
        var config = RealmConfig.Get(PlayerDatas.Instance.baseData.realmLevel);
        for (int i = 0; i < config.AddAttrType.Length; i++)
        {
            if (id == 7)
            {
                Add(67, value);
                Add(68, value);
            }
            else
            {
                if (tables.ContainsKey(id))
                {
                    tables[id] = tables[id] + value;
                }
                else
                {
                    tables[id] = value;
                }
            }
            var id = config.AddAttrType[i];
            officialAttrs[id] = config.AddAttrNum[i];
        }
        public void AddRange(List<int> ids, List<int> values)
        {
            if (ids.IsNullOrEmpty() || values.IsNullOrEmpty())
            {
                return;
            }
            var count = Mathf.Min(ids.Count, values.Count);
            for (int i = 0; i < count; i++)
            {
                Add(ids[i], values[i]);
            }
        }
#if UNITY_EDITOR
        Debug.Log("战力:官职属性 " + JsonMapper.ToJson(officialAttrs));
#endif
    }
    //装备属性:身上装备汇总
    void RefrehEquipAttrs()
    {
        equipAttrs.Clear();  //身上装备属性重置
        for (int i = 0; i < EquipModel.TotleEquip; i++)
        {
            var equip = EquipModel.Instance.GetEquip(i);
            if (dropIndexCalc != -1)
            {
                var dropEquip = PackManager.Instance.GetItemByIndex(PackType.DropItem, dropIndexCalc);
                if (dropEquip.config.EquipPlace - 1 == i)
                {
                    equip = dropEquip;  //替换计算总战力
                }
            }
            if (equip == null)
            {
                continue;
            }
            var baseIDAttrs = EquipModel.Instance.GetEquipBaseAttrs(equip);
            var baseVauleAttrs = EquipModel.Instance.GetEquipBaseValues(equip);
            if (baseIDAttrs != null)
            {
                for (int j = 0; j < baseIDAttrs.Count; j++)
                {
                    if (!equipAttrs.ContainsKey(baseIDAttrs[j]))
                    {
                        equipAttrs[baseIDAttrs[j]] = baseVauleAttrs[j];
                    }
                    else
                    {
                        equipAttrs[baseIDAttrs[j]] += baseVauleAttrs[j];
                    }
                }
            }
            var fightIDAttrs = EquipModel.Instance.GetEquipFightAttrs(equip);
            var fightValueAttrs = EquipModel.Instance.GetEquipFightValues(equip);
            if (fightIDAttrs != null)
            {
                for (int j = 0; j < fightIDAttrs.Count; j++)
                {
                    if (!equipAttrs.ContainsKey(fightIDAttrs[j]))
                    {
                        equipAttrs[fightIDAttrs[j]] = fightValueAttrs[j];
                    }
                    else
                    {
                        equipAttrs[fightIDAttrs[j]] += fightValueAttrs[j];
                    }
                }
            }
        }
    #region 计算战斗力
    public static readonly string FightPowerFormula = "FightpowerFormula";
#if UNITY_EDITOR
        Debug.Log("战力:装备属性 " + JsonMapper.ToJson(equipAttrs));
#endif
    }
    // public static int GetFightPower(Dictionary<int, int> _propertyDict)
    // {
    //     Equation.Instance.Clear();
    //     if (_propertyDict == null || _propertyDict.Count == 0)
    //     {
    //         return 0;
    //     }
    // 计算队伍中上阵的所有武将的上阵属性 和 光环
    void RefreshTeamAttrs()
    {
        //阵容属性
        // 阵容:所有武将上阵属性
        lineUpPerDict = HeroUIManager.Instance.GetLineupPer(teamTypeCalc, isPreviewTeamPower);
    //     foreach (var _key in _propertyDict.Keys)
    //     {
    //         PlayerPropertyConfig cfg = PlayerPropertyConfig.Get(_key);
    //         if (cfg != null)
    //         {
    //             if (_key == 7)
    //             {
    //                 Equation.Instance.AddKeyValue("MinAtk", _propertyDict[_key]);
    //                 Equation.Instance.AddKeyValue("MaxAtk", _propertyDict[_key]);
    //             }
    //             else if (_key == 24)
    //             {
    //                 Equation.Instance.AddKeyValue("PetMinAtk", _propertyDict[_key]);
    //                 Equation.Instance.AddKeyValue("PetMaxAtk", _propertyDict[_key]);
    //             }
    //             else
    //             {
    //                 ulong attrValue = (ulong)_propertyDict[_key];
    //                 var fightParm = GetFightPowerParmByAttrId(_key);
    //                 if (_key == 11)
    //                 {
    //                     var playerLv = PlayerDatas.Instance.baseData.LV;
    //                     var paramConfig = FightPowerParamConfig.Get(playerLv);
    //                     Equation.Instance.AddKeyValue("AtkSpeedParameter", paramConfig.AtkSpeedParameter);
    //                 }
    //                 else
    //                 {
    //                     if (fightParm != 0)
    //                     {
    //                         attrValue = attrValue * (ulong)fightParm;
    //                     }
    //                 }
    //                 Equation.Instance.AddKeyValue(cfg.Parameter, attrValue);
    //             }
    //         }
    //     }
    //     FuncConfigConfig funcCfg = FuncConfigConfig.Get(FightPowerFormula);
    //     return Equation.Instance.Eval<int>(funcCfg.Numerical1);
    // }
    // public static int GetFightPowerParmByAttrId(int attrId)
    // {
    //     int playerLv = PlayerDatas.Instance.baseData.LV;
    //     FightPowerParamConfig paramConfig = FightPowerParamConfig.Get(playerLv);
    //     PlayerPropertyConfig cfg = PlayerPropertyConfig.Get(attrId);
    //     if (paramConfig == null || cfg == null) return 0;
    //     switch (cfg.Parameter)
    //     {
    //         case "Hit":
    //             return paramConfig.Hit;
    //         case "Miss":
    //             return paramConfig.Miss;
    //         case "IgnoreDefRate":
    //             return paramConfig.IgnoreDefRate;
    //         case "DamChanceDef":
    //             return paramConfig.DamChanceDef;
    //         case "FaintRate":
    //             return paramConfig.FaintRate;
    //         case "LuckyHitRateReduce":
    //             return paramConfig.LuckyHitRateReduce;
    //         case "SkillAtkRate":
    //             return paramConfig.SkillAtkRate;
    //         case "SkillAtkRateReduce":
    //             return paramConfig.SkillAtkRateReduce;
    //         case "DamagePerPVP":
    //             return paramConfig.DamagePerPVP;
    //         case "DamagePerPVPReduce":
    //             return paramConfig.DamagePerPVPReduce;
    //         case "DamBackPer":
    //             return paramConfig.DamBackPer;
    //         case "IgnoreDefRateReduce":
    //             return paramConfig.IgnoreDefRateReduce;
    //         case "FaintDefRate":
    //             return paramConfig.FaintDefRate;
    //         case "AtkSpeedParameter":
    //             return paramConfig.AtkSpeedParameter;
    //         case "JobAHurtAddPer":
    //             return paramConfig.JobAHurtAddPer;
    //         case "JobBHurtAddPer":
    //             return paramConfig.JobBHurtAddPer;
    //         case "JobCHurtAddPer":
    //             return paramConfig.JobCHurtAddPer;
    //         case "JobAAtkReducePer":
    //             return paramConfig.JobAAtkReducePer;
    //         case "JobBAtkReducePer":
    //             return paramConfig.JobBAtkReducePer;
    //         case "JobCAtkReducePer":
    //             return paramConfig.JobCAtkReducePer;
    //         case "SuperHitRate":
    //             return paramConfig.SuperHitRate;
    //         case "LuckyHitRate":
    //             return paramConfig.LuckyHitRate;
    //         case "SuperHitRateReduce":
    //             return paramConfig.SuperHitRateReduce;
    //         case "FinalHurtPer":
    //             return paramConfig.FinalHurtPer;
    //         case "FinalHurtReducePer":
    //             return paramConfig.FinalHurtReducePer;
    //         case "NPCHurtAddPer":
    //             return paramConfig.NPCHurtAddPer;
    //         case "NormalHurtPer":
    //             return paramConfig.NormalHurtPer;
    //         case "FabaoHurtPer":
    //             return paramConfig.FabaoHurtPer;
    //         case "AffairSpeedPer":
    //             return paramConfig.AffairSpeedPer;
    //         case "FamilyBossHurtPer":
    //             return paramConfig.FamilyBossHurtPer;
    //         case "FamilyWarHPPer":
    //             return paramConfig.FamilyWarHPPer;
    //         case "FamilyWarAtkPer":
    //             return paramConfig.FamilyWarAtkPer;
    //         case "FamilySitExpPer":
    //             return paramConfig.FamilySitExpPer;
    //         case "BossFinalHurtPer":
    //             return paramConfig.BossFinalHurtPer;
    //     }
    //     return 0;
    // }
#if UNITY_EDITOR
        Debug.Log("战力:上阵属性 " + JsonMapper.ToJson(lineUpPerDict));
#endif
        // 阵容:国家(光环)属性
        countryAttrs = HeroUIManager.Instance.GetCountryAttrs(teamTypeCalc, isPreviewTeamPower);
#if UNITY_EDITOR
        Debug.Log("战力:国家(光环)属性 " + JsonMapper.ToJson(countryAttrs));
#endif
    }
    #endregion
    //单属性公式分基础三维和战斗属性
    // 【主公属性】
    // 等级属性    lvValue
    // 装备属性    equipValue
    // 图鉴属性    bookValue 、 bookPer
    // 【阵容属性】 - 该阵容所有武将有效
    // 初始加成    lineupInitAddPer
    // 升级加成    lineupLVAddPer
    // 突破加成    lineupBreakLVAddPer
    // 吞噬加成    lineupStarAddPer
    // 阵容光环    lineupHaloValue 、 lineupHaloPer
    // 【武将属性】
    // 继承比例    inheritPer
    // 自身属性    heroSelfValue 、 heroSelfPer
    // 吞噬属性    starTalentValue 、 starTalentPer
    // 突破属性    breakLVValue 、 breakLVPer
    // 觉醒属性    awakeTalentValue 、 awakeTalentPer
    // 羁绊属性    fetterValue 、 fetterPer
    #region 属性公式
    // 单基础属性计算
    public double GetPropertyVaule(int attrType, HeroInfo hero, string formula)
    {
        propertyVariables.Clear();
        propertyVariables["lvValue"] = lvAttrs.ContainsKey(attrType) ? lvAttrs[attrType] : 0;
        propertyVariables["equipValue"] = equipAttrs.ContainsKey(attrType) ? equipAttrs[attrType] : 0;
        propertyVariables["bookValue"] = 0;
        propertyVariables["bookPer"] = GetBookPer(attrType) / 10000.0f;
        propertyVariables["realmValue"] = officialAttrs.ContainsKey(attrType) ? officialAttrs[attrType] : 0;
        propertyVariables["realmPer"] = GetOfficialPer(attrType) / 10000.0f;
        //!!!单武将战力预览的话需要排除队伍影响战力,只算武将自身的上阵属性
        propertyVariables["lineupInitAddPer"] = GetLineUpPer(attrType, "lineupInitAddPer") / 10000.0f;
        propertyVariables["lineupLVAddPer"] = GetLineUpPer(attrType, "lineupLVAddPer") / 10000.0f;
        propertyVariables["lineupBreakLVAddPer"] = GetLineUpPer(attrType, "lineupBreakLVAddPer") / 10000.0f;
        propertyVariables["lineupStarAddPer"] = GetLineUpPer(attrType, "lineupStarAddPer") / 10000.0f;
        //阵容光环 三围百分比加成
        propertyVariables["lineupHaloValue"] = countryAttrs.ContainsKey(attrType) ? countryAttrs[attrType] : 0;
        propertyVariables["lineupHaloPer"] = GetCountryPer(attrType) / 10000.0f;
        //武将属性
        propertyVariables["inheritPer"] = hero.GetInheritAttrPer(attrType) / 10000.0f;
        propertyVariables["heroSelfValue"] = hero.GetSelfAddValue(attrType);
        propertyVariables["heroSelfPer"] = hero.GetSelfAddPer(attrType) / 10000.0f;
        propertyVariables["starTalentValue"] = hero.GetTalentAttrValue(attrType);
        propertyVariables["starTalentPer"] = hero.GetTalentAttrPer(attrType) / 10000.0f;
        propertyVariables["breakLVValue"] = hero.GetBreakAttrValue(attrType);
        propertyVariables["breakLVPer"] = hero.GetBreakAttrPer(attrType) / 10000.0f;
        propertyVariables["awakeTalentValue"] = hero.GetAwakeAttrValue(attrType);
        propertyVariables["awakeTalentPer"] = hero.GetAwakeAttrPer(attrType) / 10000.0f;
        propertyVariables["fetterValue"] = hero.GetFetterAttrValue(attrType);
        propertyVariables["fetterPer"] = hero.GetFetterAttrPer(attrType) / 10000.0f;
#if UNITY_EDITOR
        //排除值为0的属性输出
        var tmpPropertyVariables = propertyVariables.Where(x => x.Value > 0).ToDictionary(x => x.Key, x => x.Value);
        if (!tmpPropertyVariables.IsNullOrEmpty())
            propertyStrForDebug += $"属性ID {attrType} - {JsonMapper.ToJson(tmpPropertyVariables)}";
#endif
        return JaceCalculator.Calculate(formula, propertyVariables);
    }
    int GetLineUpPer(int attrType, string key)
    {
        if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
        {
            return 0;
        }
        return lineUpPerDict[key];
    }
    int GetBookPer(int attrType)
    {
        if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
        {
            return 0;
        }
        return HeroUIManager.Instance.allHeroBookPer;
    }
    int GetOfficialPer(int attrType)
    {
        if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
        {
            var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
            return officialAttrs.ContainsKey(pertype) ? officialAttrs[pertype] : 0;
        }
        return 0;
    }
    int GetCountryPer(int attrType)
    {
        if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
        {
            var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
            return countryAttrs.ContainsKey(pertype) ? countryAttrs[pertype] : 0;
        }
        return 0;
    }
    #endregion
    #region 计算战力
    //如果服务端战力计算有压力,可改成关键点结算(如同步排行榜跨服等),表现由客户端自己计算
    //装备战力为最终总战力的结果比(提升整个角色总战力)
    //计算总战力中的武将战力,几个武将加起来就是总战力,其他功能属性计算应该涵盖在英雄里
    public long CalculatePower()
    {
#if UNITY_EDITOR
        Debug.Log("战力:开始计算");
#endif
        // --- 先计算所有功能的汇总属性 ---
        RefreshLVAttrs();
        RefreshOfficialAttrs();
        RefrehEquipAttrs();
        RefreshTeamAttrs();
        // --- 算单武将功能属性战力 后相加---
        long fightPower = 0;
        var team = TeamManager.Instance.GetTeam(teamTypeCalc);
        if (team == null)
        {
            return fightPower;
        }
        TeamHero[] teamHeroes = isPreviewTeamPower ? team.tempHeroes : team.serverHeroes;
        foreach (var hero in teamHeroes)
        {
            if (hero == null)
            {
                continue;
            }
            HeroInfo heroInfo = HeroManager.Instance.GetHero(hero.guid);
            if (heroInfo == null)
            {
                continue;
            }
            fightPower += CalculateTeamHeroPower(heroInfo);
        }
#if UNITY_EDITOR
        Debug.Log("战力:计算完毕 " + fightPower);
#endif
        return fightPower;
    }
#if UNITY_EDITOR
    string propertyStrForDebug = "";
#endif
    //计算阵容中武将战力
    public long CalculateTeamHeroPower(HeroInfo hero)
    {
        fightPowerVariables.Clear();
        hero.RefreshFetterAttrsWhenCalcPower(teamTypeCalc); //羁绊属性要实时算
#if UNITY_EDITOR
        propertyStrForDebug = "";
#endif
        foreach (var config in PlayerPropertyConfig.GetValues())
        {
            if (config.showType < 1 || config.showType > 4)
            {
                continue;
            }
            if (config.showType == 1)
            {
                fightPowerVariables[config.Parameter] = Math.Round(GetPropertyVaule(config.ID, hero, propertyFormula), 3);
            }
            else
            {
                fightPowerVariables[config.Parameter] = Math.Round(GetPropertyVaule(config.ID, hero, fightPropertyFormula), 3);
            }
        }
#if UNITY_EDITOR
        Debug.Log($"战力:武将ID {hero.heroId} 属性信息 {propertyStrForDebug}");
#endif
        //属性系数根据官职等级的加成
        var fightPowerRatioConfig = FightPowerRatioConfig.Get(PlayerDatas.Instance.baseData.realmLevel);
        fightPowerVariables["AtkRatio"] = fightPowerRatioConfig.AtkRatio;
        fightPowerVariables["MaxHPRatio"] = fightPowerRatioConfig.MaxHPRatio;
        fightPowerVariables["DefRatio"] = fightPowerRatioConfig.DefRatio;
        fightPowerVariables["StunRateRatio"] = fightPowerRatioConfig.StunRateRatio;
        fightPowerVariables["SuperHitRateRatio"] = fightPowerRatioConfig.SuperHitRateRatio;
        fightPowerVariables["ComboRateRatio"] = fightPowerRatioConfig.ComboRateRatio;
        fightPowerVariables["MissRateRatio"] = fightPowerRatioConfig.MissRateRatio;
        fightPowerVariables["ParryRateRatio"] = fightPowerRatioConfig.ParryRateRatio;
        fightPowerVariables["SuckHPPerRatio"] = fightPowerRatioConfig.SuckHPPerRatio;
        fightPowerVariables["StunRateDefRatio"] = fightPowerRatioConfig.StunRateDefRatio;
        fightPowerVariables["SuperHitRateDefRatio"] = fightPowerRatioConfig.SuperHitRateDefRatio;
        fightPowerVariables["ComboRateDefRatio"] = fightPowerRatioConfig.ComboRateDefRatio;
        fightPowerVariables["MissRateDefRatio"] = fightPowerRatioConfig.MissRateDefRatio;
        fightPowerVariables["ParryRateDefRatio"] = fightPowerRatioConfig.ParryRateDefRatio;
        fightPowerVariables["SuckHPPerDefRatio"] = fightPowerRatioConfig.SuckHPPerDefRatio;
        fightPowerVariables["NormalSkillPerRatio"] = fightPowerRatioConfig.NormalSkillPerRatio;
        fightPowerVariables["NormalSkillPerDefRatio"] = fightPowerRatioConfig.NormalSkillPerDefRatio;
        fightPowerVariables["AngerSkillPerRatio"] = fightPowerRatioConfig.AngerSkillPerRatio;
        fightPowerVariables["AngerSkillPerDefRatio"] = fightPowerRatioConfig.AngerSkillPerDefRatio;
        fightPowerVariables["SuperDamPerRatio"] = fightPowerRatioConfig.SuperDamPerRatio;
        fightPowerVariables["SuperDamPerDefRatio"] = fightPowerRatioConfig.SuperDamPerDefRatio;
        fightPowerVariables["ShieldPerRatio"] = fightPowerRatioConfig.ShieldPerRatio;
        fightPowerVariables["ShieldPerDefRatio"] = fightPowerRatioConfig.ShieldPerDefRatio;
        fightPowerVariables["DOTPerRatio"] = fightPowerRatioConfig.DOTPerRatio;
        fightPowerVariables["DOTPerDefRatio"] = fightPowerRatioConfig.DOTPerDefRatio;
        fightPowerVariables["WeiFinalDamPerRatio"] = fightPowerRatioConfig.WeiFinalDamPerRatio;
        fightPowerVariables["WeiFinalDamPerDefRatio"] = fightPowerRatioConfig.WeiFinalDamPerDefRatio;
        fightPowerVariables["ShuFinalDamPerRatio"] = fightPowerRatioConfig.ShuFinalDamPerRatio;
        fightPowerVariables["ShuFinalDamPerDefRatio"] = fightPowerRatioConfig.ShuFinalDamPerDefRatio;
        fightPowerVariables["WuFinalDamPerRatio"] = fightPowerRatioConfig.WuFinalDamPerRatio;
        fightPowerVariables["WuFinalDamPerDefRatio"] = fightPowerRatioConfig.WuFinalDamPerDefRatio;
        fightPowerVariables["QunFinalDamPerRatio"] = fightPowerRatioConfig.QunFinalDamPerRatio;
        fightPowerVariables["QunFinalDamPerDefRatio"] = fightPowerRatioConfig.QunFinalDamPerDefRatio;
        fightPowerVariables["FinalDamPerRatio"] = fightPowerRatioConfig.FinalDamPerRatio;
        fightPowerVariables["FinalDamPerDefRatio"] = fightPowerRatioConfig.FinalDamPerDefRatio;
        fightPowerVariables["PhyDamPerRatio"] = fightPowerRatioConfig.PhyDamPerRatio;
        fightPowerVariables["PhyDamPerDefRatio"] = fightPowerRatioConfig.PhyDamPerDefRatio;
        fightPowerVariables["MagDamPerRatio"] = fightPowerRatioConfig.MagDamPerRatio;
        fightPowerVariables["MagDamPerDefRatio"] = fightPowerRatioConfig.MagDamPerDefRatio;
        fightPowerVariables["CurePerRatio"] = fightPowerRatioConfig.CurePerRatio;
        fightPowerVariables["CurePerDefRatio"] = fightPowerRatioConfig.CurePerDefRatio;
        long fightPower = (long)JaceCalculator.Calculate(fightPowerFormula, fightPowerVariables);
#if UNITY_EDITOR
        //排除值为0的属性输出
        var tmpFightPowerVariables = fightPowerVariables.Where(x => x.Value > 0).ToDictionary(x => x.Key, x => x.Value);
        if (!tmpFightPowerVariables.IsNullOrEmpty())
            Debug.Log($"战力:武将ID {hero.heroId} 属性战力 {fightPower} 属性战力参数 {JsonMapper.ToJson(tmpFightPowerVariables)}");
#endif
        //加上技能战力
        fightPowerVariables.Clear();
        fightPowerVariables["PlayerLV"] = PlayerDatas.Instance.baseData.LV;
        fightPowerVariables["OfficialLV"] = PlayerDatas.Instance.baseData.realmLevel;
        fightPowerVariables["SkillPower"] = hero.GetSkillsFightPower();
        long skillPower = (long)JaceCalculator.Calculate(skillFightPowerFormula, fightPowerVariables);
#if UNITY_EDITOR
        Debug.Log($"战力:武将ID {hero.heroId} 技能战力 {skillPower} 技能参数 {JsonMapper.ToJson(fightPowerVariables)}");
        Debug.Log($"战力:武将ID {hero.heroId} 总战力 {fightPower + skillPower}");
#endif
        return fightPower + skillPower;
    }
    /// <summary>
    /// 和身上装备对比差
    /// </summary>
    /// <param name="item">地板装备</param>
    /// <returns></returns>
    public long GetFightPowerChange(ItemModel item)
    {
        InitFightPowerParam();
        var fightPower = CalculatePower();
        InitFightPowerParam(dropindex: item.gridIndex);
        var tmpFightPower = CalculatePower();
        return tmpFightPower - fightPower;
    }
    // 单英雄查看战力
    // 1. 上阵英雄显示,在主线阵容下的战力
    // 2. 非上阵或其他上阵阵容:上阵不足6个人的,按增加的方式的计算;人数满的情况下按替换6号位计算
    public long GetHeroFightPower(HeroInfo heroInfo)
    {
        bool ispreview = false;
        var team = TeamManager.Instance.GetTeam(TeamType.Story);
        if (!team.HasHero(heroInfo.itemHero.guid))
        {
            //替换上阵位置
            ispreview = true;
            var index = team.GetEmptyPosition();
            if (index < 0)
            {
                team.AddHero(heroInfo, 5);
            }
            else
            {
                team.AddHero(heroInfo, index);
            }
        }
        InitFightPowerParam(ispreview: ispreview);
        RefreshLVAttrs();
        RefreshOfficialAttrs();
        RefrehEquipAttrs();
        RefreshTeamAttrs();
        var fightPower = CalculateTeamHeroPower(heroInfo);
        //计算完恢复队伍
        if (ispreview)
            team.RestoreTeam();
        return fightPower;
    }
    //查看阵容战力
    public long GetTeamFightPower(TeamType team, bool isPreview)
    {
        InitFightPowerParam(team, -1, isPreview);
        return CalculatePower();
    }
    #endregion
    public Dictionary<int, long> GetHeroTotalAttr(HeroInfo hero)
    {
        Dictionary<int, long> tmpAttrs = new Dictionary<int, long>();
        hero.RefreshFetterAttrsWhenCalcPower(TeamType.Story); //羁绊属性要实时算
#if UNITY_EDITOR
        propertyStrForDebug = "";
#endif
        foreach (var config in PlayerPropertyConfig.GetValues())
        {
            if (config.showType < 1 || config.showType > 4)
            {
                continue;
            }
            if (config.showType == 1)
            {
                tmpAttrs[config.ID] = (long)GetPropertyVaule(config.ID, hero, propertyFormula);
            }
            else
            {
                tmpAttrs[config.ID] = (long)GetPropertyVaule(config.ID, hero, fightPropertyFormula);
            }
        }
#if UNITY_EDITOR
        Debug.Log($"战力:武将ID {hero.heroId} 属性信息 {propertyStrForDebug}");
#endif
        return tmpAttrs;
    }
}