yyl
3 天以前 973edc44a04dceb8b48a32ca912e6167f86189d4
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts

# Conflicts:
# Main/System/Battle/BattleField/OperationAgent/HandModeOperationAgent.cs
78个文件已修改
1个文件已删除
21 文件已复制
23个文件已添加
1 文件已重命名
5349 ■■■■■ 已修改文件
Main/Component/UI/Effect/BattleEffectPlayer.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/EffectPlayer.cs 207 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/UIEffectPlayer.cs 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/UISpineEffect.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/UISpineEffect.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/ConfigManager.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/EffectConfig.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/FightPowerRatioConfig.cs 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/FuncOpenLVConfig.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/InvestConfig.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/InvestConfig.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/SkillConfig.cs 367 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/XBGetItemConfig.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/PlayerPropertyConfig.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/TreasureItemLibConfig.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/TreasureItemLibConfig.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/GameEngine/Player/PlayerBaseData.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/GameEngine/Player/PlayerDatas.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/GameEngine/Player/PlayerExtersionData.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA1_Sys/CA125_tagCMCoinBuyOrderInfo.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA1_Sys/CA125_tagCMCoinBuyOrderInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA541_tagCMGetInvestReward.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA541_tagCMGetInvestReward.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA568_tagCMRequestTreasure.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA338_tagMCInvestInfo.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA338_tagMCInvestInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA3_Function/HA338_tagMCInvestInfo.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA3_Function/HA338_tagMCInvestInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Main.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/SDK/SDKUtils.cs 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/OperationAgent/HandModeOperationAgent.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleManager.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/CustomizedGift/CustomizedGiftChooseCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/CustomizedGift/CustomizedGiftChooseWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/CustomizedGift/CustomizedRechargeModel.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HappyXBModel.cs 886 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultCell.cs 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs 285 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallRuleWin.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallRuleWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreRuleWin.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreRuleWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreWin.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallWin.cs 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroSmallHeadCell.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroSmallHeadCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroSmallHeadLineCell.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroSmallHeadLineCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroConfigUtility.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Awake.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Break.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Fetter.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroManager.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/UIHeroController.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroAllAttrWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBaseWin.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteHeadCell.cs 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteHeadCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteLineCell.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteLineCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteWin.cs 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroLVBreakSuccessWin.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroLVBreakWin.cs 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroListWin.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroPosWin.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroScenePosCell.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroSelectBehaviour.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 139 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Reborn.cs 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Invest.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Invest/InvestModel.cs 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Invest/InvestModel.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/BoxGetItemModel.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/BoxItemWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ChooseItemsCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ChooseItemsWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ItemTipUtility.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ItemTipWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnItemCell.cs 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnItemCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnMoneyCell.cs 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnMoneyCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/BackpackData.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/Logic/ItemLogicUtility.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/Logic/SinglePack.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/New/CommonItemBaisc.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/PackManager.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Launch/LaunchBackGroundWin.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Launch/LaunchWin.cs 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Launch/LoadingWin.cs 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Login/GameAgeWarnWin.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Mail/MailInfoAwardItemCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FightPowerManager.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HomeWin.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/MainWin.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/PlayerMainDate.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Message/ColorAnalysis.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/PhantasmPavilion/PhantasmPavilionModel.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/DailySpecialsModel.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/GotoChargeWin.cs 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/GotoChargeWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/RechargeManager.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/RoleParticulars/RoleParticularModel.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreModel.cs 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Team/TeamType.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ConfirmCancel.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/FuncRuleWin.cs 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ItemsConfirmCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ItemsConfirmWin.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ScrollTip.cs 210 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/CommonFunc.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/Constants.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/EnumHelper.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/TimeUtility.cs 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 190 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/BattleEffectPlayer.cs
@@ -237,7 +237,7 @@
        spineComp.Initialize(true);
        spineComp.timeScale = speedRate;
        spineAnimationState = spineComp.AnimationState;
        spineAnimationState = spineComp.state;
        spineAnimationState.Complete -= OnSpineAnimationComplete;
        spineAnimationState.Complete += OnSpineAnimationComplete;
Main/Component/UI/Effect/EffectPlayer.cs
@@ -5,11 +5,11 @@
using UnityEngine;
using Spine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
// 特效播放器,对象池管理:unity特效和spine特效都是做好的预制体
// unity特效预制体是特效师在制作的时候生成的,unity特效必须挂载设置播放时长脚本 EffectTime
// spine特效是特效师制作的动画文件可直接加载用,制作成预制体可增加BoneFollower之类的进行逻辑处理
// 非UI特效使用,UI特效UIEffectPlayer继承EffectPlayer,后续如果逻辑冲突大则不用继承
// 特效播放器,预制体对象池管理,unity的预制体池使用有问题(1个特效1个池但复用又低)后续修改
// unity特效《预制体》是特效师在制作的时候生成的不同预制体,unity特效必须挂载设置播放时长脚本 EffectTime
// spine特效是特效师制作的动画文件,可共同复用一个《预制体》
public class EffectPlayer : MonoBehaviour
{
    [SerializeField]
@@ -36,7 +36,16 @@
    public float speedRate = 1f;
    [Header("是否循环播放spine特效")]
    public bool isPlaySpineLoop = false;
    [Header("是否在显示时播放")]
    public bool isPlayOnEnable = false;
    [Header("延迟播放(毫秒)")]
    public int playDelayTime = 0;
    public int playSpineAnimIndex = -1; //播放spine特效动画索引,代码控制
    [Header("播放完毕立即回收")]
@@ -68,10 +77,15 @@
    protected virtual void OnEnable()
    {
        if (spineComp != null)
        if (isPlayOnEnable)
        {
            Play(false);
        }
        else if (spineComp != null)
        {
            if (!isPlaying)
            {
            {
                //隐藏,会有静态显示问题
                spineComp.enabled = false;
            }
@@ -106,18 +120,25 @@
            return;
        }
        Clear();
        return;
    }
    protected virtual void Clear()
    {
        isInit = false;
        particleList.Clear();
        animatorList.Clear();
        rendererList.Clear();
        if (spineComp != null)
        {
            spineComp.skeletonDataAsset = null;
            // spineComp.Initialize(false);
            spineComp.Clear();
        }
        spineComp = null;
        pool = null;
    }
    public virtual void Stop()
@@ -135,17 +156,24 @@
        {
            spineComp.enabled = false;
        }
        isInit = false;
        isPlaying = false;
        playSpineAnimIndex = -1;
    }
    protected void Release()
    {
        Stop();
        Clear();
        onComplete?.Invoke();
    }
    public virtual void Play(bool showLog = true)
    {
        isPlaying = true;
        if (!isInit)
        {
            InitComponent(showLog);
            //effeid 为0也初始化成功,避免重复处理,在变更effectid时会重新初始化
            isInit = true;
        }
        else
@@ -154,6 +182,11 @@
            if (!this.gameObject.activeSelf)
            {
                this.gameObject.SetActive(true);
            }
            //防范effeid 为0
            if (effectConfig != null && effectConfig.isSpine != 0)
            {
                PlaySpineEffect();
            }
            return;
        }
@@ -175,28 +208,113 @@
            this.gameObject.SetActive(true);
        }
        PlayerEffect(true);
        // 加载spine特效资源
        if (effectConfig.isSpine != 0)
        {
            PlaySpineEffect();
        }
        else
        {
            PlayerEffect();
        }
        SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
    }
    protected virtual void PlaySpineEffect()
    // protected virtual void PlaySpineEffect()
    // {
    //     spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true);
    //     spineComp.raycastTarget = false;
    //     spineComp.Initialize(true);
    //     spineAnimationState = spineComp.AnimationState;
    //     spineAnimationState.Complete -= OnSpineAnimationComplete;
    //     spineAnimationState.Complete += OnSpineAnimationComplete;
    //     // 外层控制具体播放哪个动画
    //     spineComp.enabled = true;
    //     return;
    // }
    protected void PlaySpineEffect()
    {
        spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true);
        spineComp.raycastTarget = false;
        spineComp.Initialize(true);
        spineAnimationState = spineComp.AnimationState;
        spineAnimationState.Complete -= OnSpineAnimationComplete;
        spineAnimationState.Complete += OnSpineAnimationComplete;
        // 外层控制具体播放哪个动画
        // 从特效预制体池获取特效
        if (spineComp == null)
        {
            spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
        }
        if (spineComp.skeletonDataAsset == null || spineAnimationState == null)
        {
            //LoadAsset 已经有缓存SkeletonDataAsset
            spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
            spineComp.raycastTarget = false;
            spineComp.Initialize(true);
            spineComp.timeScale = speedRate;
            // 检查动画是否有相加模式
            // bool hasAdditiveBlend = CheckForAdditiveBlend(spineComp.Skeleton);
            // if (hasAdditiveBlend)
            // {
            //    spineComp.material = ResManager.Instance.LoadAsset<Material>("UIEffect/" + effectConfig.packageName, effectConfig.fxName.Split('_')[0] + "_Material-Additive");
            // }
            // else
            // {
            //     spineComp.material = null;
            // }
            spineComp.material = ResManager.Instance.LoadAsset<Material>("Materials", "SkeletonGraphicDefault-Straight");
            spineAnimationState = spineComp.AnimationState;
            spineAnimationState.Data.DefaultMix = 0f;
            spineAnimationState.Complete -= OnSpineAnimationComplete;
            spineAnimationState.Complete += OnSpineAnimationComplete;
        }
        spineComp.enabled = true;
        return;
        PlayerTheSpineAnim();
    }
    protected virtual void PlayerEffect(bool playSpine)
        // 播放指定动画
    void PlayerTheSpineAnim()
    {
        spineComp.enabled = true;
        var skeletonData = spineComp.Skeleton.Data;
        if (skeletonData.Animations.Count > 0)
        {
            //按配置或者默认第一个
            int defaultAnimIndex = Math.Max(0, effectConfig.animIndex.Length == 0 ? 0 : effectConfig.animIndex[0]);
            string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? defaultAnimIndex : playSpineAnimIndex].Name;
            spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
        }
        else
        {
            Debug.LogError("Spine 数据中没有找到任何动画!" + effectConfig.id);
        }
    }
    private bool CheckForAdditiveBlend(Spine.Skeleton skeleton)
    {
        // 遍历所有插槽,检查是否有相加模式
        foreach (var slot in skeleton.Slots)
        {
            if (slot.Data.BlendMode == Spine.BlendMode.Additive)
            {
                return true;
            }
        }
        return false;
    }
    //unity特效
    protected virtual void PlayerEffect()
    {
        var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
        if (effectPrefab == null)
@@ -226,19 +344,13 @@
        effectTarget.transform.localRotation = Quaternion.identity;
        effectTarget.name = $"Effect_{effectConfig.fxName}";
        if (effectConfig.isSpine != 0 && playSpine)
        {
            //预制体
            PlaySpineEffect();
        }
        else
        {
            //挂载组件后 开始收集
            particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
            animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
            rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
            OnUnityAnimationComplete();
        }
        //挂载组件后 开始收集
        particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
        animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
        rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
        OnUnityAnimationComplete();
        if (null == canvas)
            canvas = GetComponentInParent<Canvas>();
@@ -253,6 +365,18 @@
        }
    }
    public async UniTask PlayAsync(bool showLog = true)
    {
        await UniTask.Delay(playDelayTime);
        try
        {
            Play(showLog);
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
    }
    protected void OnDestroy()
    {
@@ -262,7 +386,7 @@
            onDestroy = null;
        }
        // 停止特效并归还到池中
        Stop();
        Release();
        if (spineAnimationState != null)
        {
@@ -275,11 +399,16 @@
    //单次播放完毕就会触发,即使是循环
    protected virtual void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
    {
        if (isReleaseImmediately)
        if (!isPlaySpineLoop)
        {
            spineComp.enabled = false;
            isPlaying = false;
            Stop();
            onComplete?.Invoke();
            if (isReleaseImmediately)
            {
                Release();
            }
        }
    }
@@ -299,7 +428,7 @@
    {
        this.DoWaitStop();
        if (isReleaseImmediately)
            Stop();
            Release();
    }
Main/Component/UI/Effect/UIEffectPlayer.cs
@@ -11,186 +11,22 @@
//UI特效大部分情况不会改变特效,无需销毁
public class UIEffectPlayer : EffectPlayer
{
    [Header("是否循环播放spine特效")]
    public bool isPlaySpineLoop = false;
    [Header("是否在显示时播放")]
    public bool isPlayOnEnable = false;
    [Header("延迟播放(毫秒)")]
    public int playDelayTime = 0;
    int playSpineAnimIndex = -1; //播放spine特效动画索引,
    protected override void OnEnable()
    {
        playSpineAnimIndex = -1;
        if (isPlayOnEnable)
        {
            PlayAsync(false).Forget();
        }
        else if (spineComp != null)
        {
            if (!isPlaying)
            {
                //隐藏,会有静态显示问题
                spineComp.enabled = false;
            }
        }
    }
    public override void Play(bool showLog = true)
    {
        isPlaying = true;
        if (!isInit)
        {
            InitComponent(showLog);
            //effeid 为0也初始化成功,避免重复处理,在变更effectid时会重新初始化
            isInit = true;
        }
        else
        {
            //避免重复创建
            if (!this.gameObject.activeSelf)
            {
                this.gameObject.SetActive(true);
            }
            //防范effeid 为0
            if (effectConfig != null && effectConfig.isSpine != 0)
            {
                PlayerTheSpineAnim();
            }
            return;
        }
        if (EffectMgr.IsNotShowBySetting(effectId))
        {
            return;
        }
        if (null != effectTarget)
        {
            if (pool != null)
                pool.Release(effectTarget);
            effectTarget = null;
        }
        if (!this.gameObject.activeSelf)
        {
            this.gameObject.SetActive(true);
        }
        // 加载spine特效资源
        if (effectConfig.isSpine != 0)
        {
            PlaySpineEffect();
        }
        else
        {
            PlayerEffect(false);
        }
        SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
    }
    protected override void PlaySpineEffect()
    {
        if (spineComp == null)
        {
            spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
        }
        if (spineComp.skeletonDataAsset == null)
        {
            //LoadAsset 已经有缓存SkeletonDataAsset
            spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
            spineComp.raycastTarget = false;
            spineComp.Initialize(true);
            // 检查动画是否有相加模式
            bool hasAdditiveBlend = CheckForAdditiveBlend(spineComp.Skeleton);
            if (hasAdditiveBlend)
            {
                spineComp.material = ResManager.Instance.LoadAsset<Material>("UIEffect/" + effectConfig.packageName, effectConfig.fxName.Split('_')[0] + "_Material-Additive");
            }
            else
            {
                spineComp.material = null;
            }
            spineAnimationState = spineComp.AnimationState;
            spineAnimationState.Data.DefaultMix = 0f;
            spineAnimationState.Complete -= OnSpineAnimationComplete;
            spineAnimationState.Complete += OnSpineAnimationComplete;
        }
        spineComp.enabled = true;
        PlayerTheSpineAnim();
    }
    private bool CheckForAdditiveBlend(Spine.Skeleton skeleton)
    {
        // 遍历所有插槽,检查是否有相加模式
        foreach (var slot in skeleton.Slots)
        {
            if (slot.Data.BlendMode == Spine.BlendMode.Additive)
            {
                return true;
            }
        }
        return false;
    }
    //spine里的第几个动画
    public void Play(int index, bool showLog = true)
    {
        playSpineAnimIndex = index;
        PlayAsync(showLog).Forget();
    }
    async UniTask PlayAsync(bool showLog = true)
    //配置动画组数组索引
    public void PlayByArrIndex(int index, bool showLog = true)
    {
        await UniTask.Delay(playDelayTime);
        Play(showLog);
        var config = EffectConfig.Get(effectId);
        playSpineAnimIndex = config.animIndex[index];
        PlayAsync(showLog).Forget();
    }
    // 播放指定动画
    void PlayerTheSpineAnim()
    {
        spineComp.enabled = true;
        var skeletonData = spineComp.Skeleton.Data;
        if (skeletonData.Animations.Count > 0)
        {
            string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? effectConfig.animIndex : playSpineAnimIndex].Name;
            spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
        }
        else
        {
            Debug.LogError("Spine 数据中没有找到任何动画!" + effectConfig.id);
        }
    }
    //单次播放完毕就会触发,即使是循环
    protected override void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
    {
        if (!isPlaySpineLoop)
        {
            spineComp.enabled = false;
            isPlaying = false;
            if (isReleaseImmediately)
            {
                Stop();
            }
            else
            {
                onComplete?.Invoke();
            }
        }
    }
    //  创建后的特效会自动隐藏 需要手动调用Play才能播放
Main/Component/UI/Effect/UISpineEffect.cs
New file
@@ -0,0 +1,7 @@
using UnityEngine;
public class UISpineEffect : MonoBehaviour
{
    public Material material;
}
Main/Component/UI/Effect/UISpineEffect.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Component/UI/Effect/UISpineEffect.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: fdbe400d15c065042a16a05cd09dd322
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Config/ConfigManager.cs
@@ -46,6 +46,7 @@
            typeof(FightPowerRatioConfig),
            typeof(HeroLineupHaloConfig),
            typeof(HeroQualityLVConfig),
            typeof(InvestConfig),
            typeof(ItemConfig),
            typeof(MainChapterConfig),
            typeof(MainLevelConfig),
@@ -228,6 +229,8 @@
        ClearConfigDictionary<HeroLineupHaloConfig>();
        // 清空 HeroQualityLVConfig 字典
        ClearConfigDictionary<HeroQualityLVConfig>();
        // 清空 InvestConfig 字典
        ClearConfigDictionary<InvestConfig>();
        // 清空 ItemConfig 字典
        ClearConfigDictionary<ItemConfig>();
        // 清空 MainChapterConfig 字典
Main/Config/Configs/EffectConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月19日
//    [  Date ]:           Thursday, August 21, 2025
//--------------------------------------------------------
using System.Collections.Generic;
@@ -20,7 +20,7 @@
    public string packageName;
    public int isSpine;
    public string fxName;
    public int animIndex;
    public int[] animIndex;
    public int audio;
    public string nodeName;
    public int notShow;
@@ -48,7 +48,19 @@
            fxName = tables[3];
            int.TryParse(tables[4],out animIndex);
            if (tables[4].Contains("["))
            {
                animIndex = JsonMapper.ToObject<int[]>(tables[4]);
            }
            else
            {
                string[] animIndexStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                animIndex = new int[animIndexStringArray.Length];
                for (int i=0;i<animIndexStringArray.Length;i++)
                {
                     int.TryParse(animIndexStringArray[i],out animIndex[i]);
                }
            }
            int.TryParse(tables[5],out audio); 
Main/Config/Configs/FightPowerRatioConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月18日
//    [  Date ]:           Friday, August 22, 2025
//--------------------------------------------------------
using System.Collections.Generic;
@@ -32,14 +32,32 @@
    public float MissRateDefRatio;
    public float ParryRateDefRatio;
    public float SuckHPPerDefRatio;
    public float FinalDamPerRatio;
    public float FinalDamPerDefRatio;
    public float PhyDamPerRatio;
    public float PhyDamPerDefRatio;
    public float MagDamPerRatio;
    public float MagDamPerDefRatio;
    public float NormalSkillPerRatio;
    public float NormalSkillPerDefRatio;
    public float AngerSkillPerRatio;
    public float AngerSkillPerDefRatio;
    public float SuperDamPerRatio;
    public float SuperDamPerDefRatio;
    public float CurePerRatio;
    public float CurePerDefRatio;
    public float ShieldPerRatio;
    public float ShieldPerDefRatio;
    public float DOTPerRatio;
    public float DOTPerDefRatio;
    public float WeiFinalDamPerRatio;
    public float WeiFinalDamPerDefRatio;
    public float ShuFinalDamPerRatio;
    public float ShuFinalDamPerDefRatio;
    public float WuFinalDamPerRatio;
    public float WuFinalDamPerDefRatio;
    public float QunFinalDamPerRatio;
    public float QunFinalDamPerDefRatio;
    public override int LoadKey(string _key)
    {
@@ -83,21 +101,57 @@
            float.TryParse(tables[15],out SuckHPPerDefRatio); 
            float.TryParse(tables[16],out NormalSkillPerRatio);
            float.TryParse(tables[16],out FinalDamPerRatio);
            float.TryParse(tables[17],out NormalSkillPerDefRatio);
            float.TryParse(tables[17],out FinalDamPerDefRatio);
            float.TryParse(tables[18],out AngerSkillPerRatio);
            float.TryParse(tables[18],out PhyDamPerRatio);
            float.TryParse(tables[19],out AngerSkillPerDefRatio);
            float.TryParse(tables[19],out PhyDamPerDefRatio);
            float.TryParse(tables[20],out SuperDamPerRatio);
            float.TryParse(tables[20],out MagDamPerRatio);
            float.TryParse(tables[21],out SuperDamPerDefRatio);
            float.TryParse(tables[21],out MagDamPerDefRatio);
            float.TryParse(tables[22],out ShieldPerRatio);
            float.TryParse(tables[22],out NormalSkillPerRatio);
            float.TryParse(tables[23],out ShieldPerDefRatio);
            float.TryParse(tables[23],out NormalSkillPerDefRatio);
            float.TryParse(tables[24],out AngerSkillPerRatio);
            float.TryParse(tables[25],out AngerSkillPerDefRatio);
            float.TryParse(tables[26],out SuperDamPerRatio);
            float.TryParse(tables[27],out SuperDamPerDefRatio);
            float.TryParse(tables[28],out CurePerRatio);
            float.TryParse(tables[29],out CurePerDefRatio);
            float.TryParse(tables[30],out ShieldPerRatio);
            float.TryParse(tables[31],out ShieldPerDefRatio);
            float.TryParse(tables[32],out DOTPerRatio);
            float.TryParse(tables[33],out DOTPerDefRatio);
            float.TryParse(tables[34],out WeiFinalDamPerRatio);
            float.TryParse(tables[35],out WeiFinalDamPerDefRatio);
            float.TryParse(tables[36],out ShuFinalDamPerRatio);
            float.TryParse(tables[37],out ShuFinalDamPerDefRatio);
            float.TryParse(tables[38],out WuFinalDamPerRatio);
            float.TryParse(tables[39],out WuFinalDamPerDefRatio);
            float.TryParse(tables[40],out QunFinalDamPerRatio);
            float.TryParse(tables[41],out QunFinalDamPerDefRatio);
        }
        catch (Exception exception)
        {
Main/Config/Configs/FuncOpenLVConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月5日
//    [  Date ]:           2025年8月20日
//--------------------------------------------------------
using System.Collections.Generic;
@@ -18,15 +18,13 @@
    public int FuncId;
    public int LimitLV;
    public int LimitMagicWeapon;
    public int LimiRealmLV;
    public int LimitMissionID;
    public string Remark;
    public string State;
    public string Name;
    public string Desc;
    public string Tip;
    public string Icon;
    public int open;
    public int ContinueTask;
    public override int LoadKey(string _key)
    {
@@ -42,23 +40,19 @@
            int.TryParse(tables[1],out LimitLV); 
            int.TryParse(tables[2],out LimitMagicWeapon);
            int.TryParse(tables[2],out LimiRealmLV);
            int.TryParse(tables[3],out LimiRealmLV);
            int.TryParse(tables[3],out LimitMissionID);
            int.TryParse(tables[4],out LimitMissionID);
            Name = tables[4];
            Remark = tables[5];
            Desc = tables[5];
            State = tables[6];
            Tip = tables[6];
            Tip = tables[7];
            Icon = tables[7];
            Icon = tables[8];
            int.TryParse(tables[9],out open);
            int.TryParse(tables[10],out ContinueTask);
            int.TryParse(tables[8],out open);
        }
        catch (Exception exception)
        {
Main/Config/Configs/InvestConfig.cs
New file
@@ -0,0 +1,56 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月22日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class InvestConfig : ConfigBase<int, InvestConfig>
{
    static InvestConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int id;
    public int type;
    public int needDay;
    public int needLV;
    public int needNPCID;
    public Dictionary<int, int[][]> award;
    public string info;
    public override int LoadKey(string _key)
    {
        int key = GetKey(_key);
        return key;
    }
    public override void LoadConfig(string input)
    {
        try {
        string[] tables = input.Split('\t');
        int.TryParse(tables[0],out id);
            int.TryParse(tables[1],out type);
            int.TryParse(tables[2],out needDay);
            int.TryParse(tables[3],out needLV);
            int.TryParse(tables[4],out needNPCID);
            award = ConfigParse.ParseIntArray2Dict(tables[5]);
            info = tables[6];
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/InvestConfig.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Config/Configs/InvestConfig.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: ff3d77591e2aeaa438955b2b6322cfba
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Config/Configs/SkillConfig.cs
@@ -1,227 +1,230 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           Wednesday, August 20, 2025
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class SkillConfig : ConfigBase<int, SkillConfig>
{
    static SkillConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int SkillID;
    public int SkillTypeID;
    public int SkillMaxLV;
    public string SkillName;
    public string Description;
    public int FuncType;
    public int SkillType;
    public int HurtType;
    public int AtkType;
    public int TagAim;
    public int TagFriendly;
    public int TagAffect;
    public int TagCount;
    public int HappenRate;
    public int EffectID1;
    public int[] EffectValues1;
    public int EffectID2;
    public int[] EffectValues2;
    public int EffectID3;
    public int[] EffectValues3;
    public int ConnSkill;
    public int CoolDownTime;
    public int[] EnhanceSkillList;
    public int FightPower;
    public int StartupFrames;
    public int[] ActiveFrames;
    public int RecoveryFrames;
    public int LoopCount;
    public int CastPosition;
    public int CastIndexNum;
    public float CastDistance;
    public int[][] DamageDivide;
    public int BulletEffectId;
    public int BulletPos;
    public int BulletPath;
    public int BulletFlyTime;
    public int ExplosionEffectId;
    public int ExplosionPos;
    public string SkillMotionName;
    public int EffectId;
    public int EffectPos;
    public int EffectType;
    public string IconName;
    public int ExplosionEffect2;
    public override int LoadKey(string _key)
    {
        int key = GetKey(_key);
        return key;
    }
    public override void LoadConfig(string input)
    {
        try {
        string[] tables = input.Split('\t');
        int.TryParse(tables[0],out SkillID);
            int.TryParse(tables[1],out SkillTypeID);
            int.TryParse(tables[2],out SkillMaxLV);
            SkillName = tables[3];
            Description = tables[4];
            int.TryParse(tables[5],out FuncType);
            int.TryParse(tables[6],out SkillType);
            int.TryParse(tables[7],out HurtType);
            int.TryParse(tables[8],out AtkType);
            int.TryParse(tables[9],out TagAim);
            int.TryParse(tables[10],out TagFriendly);
            int.TryParse(tables[11],out TagAffect);
            int.TryParse(tables[12],out TagCount);
            int.TryParse(tables[13],out HappenRate);
            int.TryParse(tables[14],out EffectID1);
            if (tables[15].Contains("["))
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           Friday, August 22, 2025
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class SkillConfig : ConfigBase<int, SkillConfig>
{
    static SkillConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int SkillID;
    public int SkillTypeID;
    public int SkillLV;
    public int SkillMaxLV;
    public string SkillName;
    public string Description;
    public int FuncType;
    public int SkillType;
    public int HurtType;
    public int AtkType;
    public int TagAim;
    public int TagFriendly;
    public int TagAffect;
    public int TagCount;
    public int HappenRate;
    public int EffectID1;
    public int[] EffectValues1;
    public int EffectID2;
    public int[] EffectValues2;
    public int EffectID3;
    public int[] EffectValues3;
    public int ConnSkill;
    public int CoolDownTime;
    public int[] EnhanceSkillList;
    public int FightPower;
    public int StartupFrames;
    public int[] ActiveFrames;
    public int RecoveryFrames;
    public int LoopCount;
    public int CastPosition;
    public int CastIndexNum;
    public float CastDistance;
    public int[][] DamageDivide;
    public int BulletEffectId;
    public int BulletPos;
    public int BulletPath;
    public int BulletFlyTime;
    public int ExplosionEffectId;
    public int ExplosionPos;
    public string SkillMotionName;
    public int EffectId;
    public int EffectPos;
    public int EffectType;
    public string IconName;
    public int ExplosionEffect2;
    public override int LoadKey(string _key)
    {
        int key = GetKey(_key);
        return key;
    }
    public override void LoadConfig(string input)
    {
        try {
        string[] tables = input.Split('\t');
        int.TryParse(tables[0],out SkillID);
            int.TryParse(tables[1],out SkillTypeID);
            int.TryParse(tables[2],out SkillLV);
            int.TryParse(tables[3],out SkillMaxLV);
            SkillName = tables[4];
            Description = tables[5];
            int.TryParse(tables[6],out FuncType);
            int.TryParse(tables[7],out SkillType);
            int.TryParse(tables[8],out HurtType);
            int.TryParse(tables[9],out AtkType);
            int.TryParse(tables[10],out TagAim);
            int.TryParse(tables[11],out TagFriendly);
            int.TryParse(tables[12],out TagAffect);
            int.TryParse(tables[13],out TagCount);
            int.TryParse(tables[14],out HappenRate);
            int.TryParse(tables[15],out EffectID1);
            if (tables[16].Contains("["))
            {
                EffectValues1 = JsonMapper.ToObject<int[]>(tables[15]);
                EffectValues1 = JsonMapper.ToObject<int[]>(tables[16]);
            }
            else
            {
                string[] EffectValues1StringArray = tables[15].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                string[] EffectValues1StringArray = tables[16].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                EffectValues1 = new int[EffectValues1StringArray.Length];
                for (int i=0;i<EffectValues1StringArray.Length;i++)
                {
                     int.TryParse(EffectValues1StringArray[i],out EffectValues1[i]);
                }
            }
            int.TryParse(tables[16],out EffectID2);
            if (tables[17].Contains("["))
            }
            int.TryParse(tables[17],out EffectID2);
            if (tables[18].Contains("["))
            {
                EffectValues2 = JsonMapper.ToObject<int[]>(tables[17]);
                EffectValues2 = JsonMapper.ToObject<int[]>(tables[18]);
            }
            else
            {
                string[] EffectValues2StringArray = tables[17].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                string[] EffectValues2StringArray = tables[18].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                EffectValues2 = new int[EffectValues2StringArray.Length];
                for (int i=0;i<EffectValues2StringArray.Length;i++)
                {
                     int.TryParse(EffectValues2StringArray[i],out EffectValues2[i]);
                }
            }
            int.TryParse(tables[18],out EffectID3);
            if (tables[19].Contains("["))
            }
            int.TryParse(tables[19],out EffectID3);
            if (tables[20].Contains("["))
            {
                EffectValues3 = JsonMapper.ToObject<int[]>(tables[19]);
                EffectValues3 = JsonMapper.ToObject<int[]>(tables[20]);
            }
            else
            {
                string[] EffectValues3StringArray = tables[19].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                string[] EffectValues3StringArray = tables[20].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                EffectValues3 = new int[EffectValues3StringArray.Length];
                for (int i=0;i<EffectValues3StringArray.Length;i++)
                {
                     int.TryParse(EffectValues3StringArray[i],out EffectValues3[i]);
                }
            }
            int.TryParse(tables[20],out ConnSkill);
            int.TryParse(tables[21],out CoolDownTime);
            if (tables[22].Contains("["))
            }
            int.TryParse(tables[21],out ConnSkill);
            int.TryParse(tables[22],out CoolDownTime);
            if (tables[23].Contains("["))
            {
                EnhanceSkillList = JsonMapper.ToObject<int[]>(tables[22]);
                EnhanceSkillList = JsonMapper.ToObject<int[]>(tables[23]);
            }
            else
            {
                string[] EnhanceSkillListStringArray = tables[22].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                string[] EnhanceSkillListStringArray = tables[23].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                EnhanceSkillList = new int[EnhanceSkillListStringArray.Length];
                for (int i=0;i<EnhanceSkillListStringArray.Length;i++)
                {
                     int.TryParse(EnhanceSkillListStringArray[i],out EnhanceSkillList[i]);
                }
            }
            int.TryParse(tables[23],out FightPower);
            int.TryParse(tables[24],out StartupFrames);
            if (tables[25].Contains("["))
            }
            int.TryParse(tables[24],out FightPower);
            int.TryParse(tables[25],out StartupFrames);
            if (tables[26].Contains("["))
            {
                ActiveFrames = JsonMapper.ToObject<int[]>(tables[25]);
                ActiveFrames = JsonMapper.ToObject<int[]>(tables[26]);
            }
            else
            {
                string[] ActiveFramesStringArray = tables[25].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                string[] ActiveFramesStringArray = tables[26].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                ActiveFrames = new int[ActiveFramesStringArray.Length];
                for (int i=0;i<ActiveFramesStringArray.Length;i++)
                {
                     int.TryParse(ActiveFramesStringArray[i],out ActiveFrames[i]);
                }
            }
            int.TryParse(tables[26],out RecoveryFrames);
            int.TryParse(tables[27],out LoopCount);
            int.TryParse(tables[28],out CastPosition);
            int.TryParse(tables[29],out CastIndexNum);
            float.TryParse(tables[30],out CastDistance);
            DamageDivide = JsonMapper.ToObject<int[][]>(tables[31].Replace("(", "[").Replace(")", "]"));
            int.TryParse(tables[32],out BulletEffectId);
            int.TryParse(tables[33],out BulletPos);
            int.TryParse(tables[34],out BulletPath);
            int.TryParse(tables[35],out BulletFlyTime);
            int.TryParse(tables[36],out ExplosionEffectId);
            int.TryParse(tables[37],out ExplosionPos);
            SkillMotionName = tables[38];
            int.TryParse(tables[39],out EffectId);
            int.TryParse(tables[40],out EffectPos);
            int.TryParse(tables[41],out EffectType);
            IconName = tables[42];
            int.TryParse(tables[43],out ExplosionEffect2);
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
            }
            int.TryParse(tables[27],out RecoveryFrames);
            int.TryParse(tables[28],out LoopCount);
            int.TryParse(tables[29],out CastPosition);
            int.TryParse(tables[30],out CastIndexNum);
            float.TryParse(tables[31],out CastDistance);
            DamageDivide = JsonMapper.ToObject<int[][]>(tables[32].Replace("(", "[").Replace(")", "]"));
            int.TryParse(tables[33],out BulletEffectId);
            int.TryParse(tables[34],out BulletPos);
            int.TryParse(tables[35],out BulletPath);
            int.TryParse(tables[36],out BulletFlyTime);
            int.TryParse(tables[37],out ExplosionEffectId);
            int.TryParse(tables[38],out ExplosionPos);
            SkillMotionName = tables[39];
            int.TryParse(tables[40],out EffectId);
            int.TryParse(tables[41],out EffectPos);
            int.TryParse(tables[42],out EffectType);
            IconName = tables[43];
            int.TryParse(tables[44],out ExplosionEffect2);
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/XBGetItemConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月5日
//    [  Date ]:           2025年8月20日
//--------------------------------------------------------
using System.Collections.Generic;
@@ -19,9 +19,9 @@
    public int ID;
    public int TreasureType;
    public int MinLV;
    public string GridItemInfo;
    public string GridLibInfo;
    public string JobItemList;
    public Dictionary<int, int[]> GridItemInfo;
    public Dictionary<int, int> GridLibInfo;
    public int[][] JobItemList;
    public int[][] GridItemRateList1;
    public override int LoadKey(string _key)
@@ -40,11 +40,11 @@
            int.TryParse(tables[2],out MinLV); 
            GridItemInfo = tables[3];
            GridItemInfo = ConfigParse.ParseIntArrayDict(tables[3]);
            GridLibInfo = tables[4];
            GridLibInfo = ConfigParse.ParseIntDict(tables[4]);
            JobItemList = tables[5];
            JobItemList = JsonMapper.ToObject<int[][]>(tables[5].Replace("(", "[").Replace(")", "]"));
            GridItemRateList1 = JsonMapper.ToObject<int[][]>(tables[6].Replace("(", "[").Replace(")", "]")); 
        }
Main/Config/PartialConfigs/PlayerPropertyConfig.cs
@@ -107,7 +107,7 @@
    public static string GetValueDescription(int id, long value)
    {
        return GetValueDescription(id, value, false);
        return GetValueDescription(id, value, true);
    }
    public static string GetValueDescription(int id, long value, bool largeValue)
Main/Config/PartialConfigs/TreasureItemLibConfig.cs
New file
@@ -0,0 +1,25 @@
using System.Collections.Generic;
public partial class TreasureItemLibConfig : ConfigBase<int, TreasureItemLibConfig>
{
    private static Dictionary<int, List<int>> resultDict = new Dictionary<int, List<int>>();
    protected override void OnConfigParseCompleted()
    {
        if (!resultDict.ContainsKey(LibID))
        {
            resultDict[LibID] = new List<int>() { ItemID };
        }
        else
        {
            resultDict[LibID].Add(ItemID);
        }
    }
    public static List<int> GetItemIDList(int libID)
    {
        return resultDict[libID];
    }
}
Main/Config/PartialConfigs/TreasureItemLibConfig.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Config/PartialConfigs/TreasureItemLibConfig.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: db3f92a327a7d7f48800c8eb069ae7a7
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/GameEngine/Player/PlayerBaseData.cs
@@ -11,18 +11,18 @@
    public int TitleID;
    public uint ExpPoint;    //扩充经验点数(亿)
    public uint TotalExp;    //总经验(小于亿部分)
    public ulong curExp { get { return TotalExp + ExpPoint * Constants.ExpPointValue; } }
    public long curExp { get { return TotalExp + ExpPoint * Constants.ExpPointValue; } }
    public uint FamilyId;    //家族
    public string FamilyName;    //家族名称
    public uint diamond;    //仙玉
    public uint bindDiamond;  //灵石
    public uint copper;    //铜钱
    public ulong allCopper { get { return (ulong)copper + (ulong)copperExtend * Constants.ExpPointValue; } }
    public ulong FightPoint;    //战斗值
    public long allCopper { get { return copper + copperExtend * Constants.ExpPointValue; } }
    public long FightPoint;    //战斗值
    public ushort MapID;    //角色所在地图  地图规则:C/S一一对应的常规地图,C假地图(ExAttr14),多C一个S地图(ExAttr3)
    public ushort PosX;    //角色坐标
    public ushort PosY;
    public ulong HP;    //当前HP
    public long HP;    //当前HP
    public uint FreePoint;    //未分配点数
    public uint FreeSkillPoint;    //未分配的技能点
    public int STR;    //力量
Main/Core/GameEngine/Player/PlayerDatas.cs
@@ -38,7 +38,7 @@
    public event Action<long> spNewGetEvent;
    private Dictionary<PlayerDataType, ulong> PlayerDataDict = new Dictionary<PlayerDataType, ulong>();
    private Dictionary<PlayerDataType, long> PlayerDataDict = new Dictionary<PlayerDataType, long>();
    public void InitPlayerData(H0102_tagCDBPlayer data)
    {
@@ -526,9 +526,9 @@
        }
    }
    public ulong GetPlayerDataByType(PlayerDataType type)
    public long GetPlayerDataByType(PlayerDataType type)
    {
        ulong value = 0;
        long value = 0;
        PlayerDataDict.TryGetValue(type, out value);
        return value;
    }
Main/Core/GameEngine/Player/PlayerExtersionData.cs
@@ -4,7 +4,7 @@
public class PlayerExtersionData
{
    public ulong MaxHP;             // 最大HP    28,
    public long MaxHP;             // 最大HP    28,
    public int MaxMP;              // 最大MP    30,
    public int ExpRate;            // 当前经验倍率    单位为百分比  35,
    public int DEF;                // 外防     42
Main/Core/NetworkPackage/ClientPack/CA1_Sys/CA125_tagCMCoinBuyOrderInfo.cs
New file
@@ -0,0 +1,24 @@
using UnityEngine;
using System.Collections;
// A1 25 代币购买充值商品编号商品 #tagCMCoinBuyOrderInfo
public class CA125_tagCMCoinBuyOrderInfo : GameNetPackBasic {
    public byte AppIDLen;
    public string AppID;
    public byte OrderInfoLen;
    public string OrderInfo;    //商品编号
    public CA125_tagCMCoinBuyOrderInfo () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xA125;
    }
    public override void WriteToBytes () {
        WriteBytes (AppIDLen, NetDataType.BYTE);
        WriteBytes (AppID, NetDataType.Chars, AppIDLen);
        WriteBytes (OrderInfoLen, NetDataType.BYTE);
        WriteBytes (OrderInfo, NetDataType.Chars, OrderInfoLen);
    }
}
Main/Core/NetworkPackage/ClientPack/CA1_Sys/CA125_tagCMCoinBuyOrderInfo.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Core/NetworkPackage/ClientPack/CA1_Sys/CA125_tagCMCoinBuyOrderInfo.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 05e91755d9d173640b5df5e6449852a4
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA541_tagCMGetInvestReward.cs
New file
@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
// A5 41 领取投资理财回报 #tagCMGetInvestReward
public class CA541_tagCMGetInvestReward : GameNetPackBasic {
    public byte InvestType;    // 投资类型
    public byte RewardIndex;    // 回报索引
    public CA541_tagCMGetInvestReward () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xA541;
    }
    public override void WriteToBytes () {
        WriteBytes (InvestType, NetDataType.BYTE);
        WriteBytes (RewardIndex, NetDataType.BYTE);
    }
}
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA541_tagCMGetInvestReward.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Core/NetworkPackage/ClientPack/CA5_Function/CA541_tagCMGetInvestReward.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 1752ebc635762534790398ccd1c3c413
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ClientPack/CA5_Function/CA568_tagCMRequestTreasure.cs
@@ -1,12 +1,12 @@
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
// A5 68 请求寻宝 #tagCMRequestTreasure
public class CA568_tagCMRequestTreasure : GameNetPackBasic {
    public byte TreasureType;    //寻宝类型
    public byte TreasureIndex;    //寻宝索引
    public byte CostType;    //消耗类型:0-默认仙玉;1-免费次数;2-寻宝道具
    public byte CostType;    //消耗类型:0-货币;1-免费次数;2-寻宝道具
    public CA568_tagCMRequestTreasure () {
        combineCmd = (ushort)0x03FE;
Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA338_tagMCInvestInfo.cs
New file
@@ -0,0 +1,13 @@
using UnityEngine;
using System.Collections;
// A3 38 投资理财信息 #tagMCInvestInfo
public class DTCA338_tagMCInvestInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack)
    {
        base.Done(vNetPack);
        HA338_tagMCInvestInfo vNetData = vNetPack as HA338_tagMCInvestInfo;
        InvestModel.Instance.UpdateInvestInfo(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA338_tagMCInvestInfo.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA338_tagMCInvestInfo.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 642095ebf906d974e8bfb5c7d45d7fc8
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -108,6 +108,8 @@
        Register(typeof(H0722_tagItemDeadLockRefresh), typeof(DTC0722_tagItemDeadLockRefresh));
        Register(typeof(HB125_tagSCPlayerHeroInfo), typeof(DTCB125_tagSCPlayerHeroInfo));
        Register(typeof(HA814_tagMCMakeItemAnswer), typeof(DTCA814_tagMCMakeItemAnswer));
        Register(typeof(HB122_tagSCHeroInfo), typeof(DTCB122_tagSCHeroInfo));
        Register(typeof(HA338_tagMCInvestInfo), typeof(DTCA338_tagMCInvestInfo));
    }
    //主工程注册封包
Main/Core/NetworkPackage/ServerPack/HA3_Function/HA338_tagMCInvestInfo.cs
New file
@@ -0,0 +1,25 @@
using UnityEngine;
using System.Collections;
// A3 38 投资理财信息 #tagMCInvestInfo
public class HA338_tagMCInvestInfo : GameNetPackBasic {
    public byte InvestType;    // 投资类型
    public ushort CurDay;    // 当前天数,投资第一天为1
    public byte ValueCount;
    public  uint[] RewardValue;    //领奖记录值,按投资回报索引位记录是否已领取
    public  uint[] ProgressValue;    //投资相关可领取进度记录值:  9登录投资-记录已登录天数;11Boss投资-按回报索引位记录是否已击杀该boss
    public HA338_tagMCInvestInfo () {
        _cmd = (ushort)0xA338;
    }
    public override void ReadFromBytes (byte[] vBytes) {
        TransBytes (out InvestType, vBytes, NetDataType.BYTE);
        TransBytes (out CurDay, vBytes, NetDataType.WORD);
        TransBytes (out ValueCount, vBytes, NetDataType.BYTE);
        TransBytes (out RewardValue, vBytes, NetDataType.DWORD, ValueCount);
        TransBytes (out ProgressValue, vBytes, NetDataType.DWORD, ValueCount);
    }
}
Main/Core/NetworkPackage/ServerPack/HA3_Function/HA338_tagMCInvestInfo.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/Core/NetworkPackage/ServerPack/HA3_Function/HA338_tagMCInvestInfo.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 9e48c8be42d2313489b38b738ddf52c6
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Main.cs
@@ -72,6 +72,7 @@
        managers.Add(RankModel.Instance);
        managers.Add(PlayerMainDate.Instance);
        managers.Add(HeroUIManager.Instance);
        managers.Add(InvestModel.Instance);
        foreach (var manager in managers)
        {
Main/SDK/SDKUtils.cs
@@ -374,7 +374,7 @@
        var _result = "default";
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
            case RuntimePlatform.Android:
                _result = "android";
                break;
            case RuntimePlatform.IPhonePlayer:
@@ -955,53 +955,53 @@
    public void FreePlatformPay(string title, float money, string cpInfo)
    {
        // 提示是否使用代金券
        // var gameCash = UIHelper.GetAllVourcher();
        var gameCash = UIHelper.GetAllVourcher();
        // bool isBuyGameCash = false; //代金券本身的充值不能用代金券购买 造成循环
        // int ctgID = ModelCenter.Instance.GetModel<VipModel>().orderInfoToCTGID[cpInfo];
        // if (ctgID != 0)
        // {
        //     isBuyGameCash = CTGConfig.Get(ctgID).PayType == 17;
        // }
        bool isBuyGameCash = false; //代金券本身的充值不能用代金券购买 造成循环
        int ctgID = RechargeManager.Instance.orderInfoToCTGID[cpInfo];
        if (ctgID != 0)
        {
            isBuyGameCash = CTGConfig.Get(ctgID).PayType == 17;
        }
        // if (!isBuyGameCash && gameCash >= money * 100 && !LoginAwardModel.rechargeLimit.Contains(ctgID))
        // {
        if (!isBuyGameCash && gameCash >= money * 100)
        {
        //     WindowCenter.Instance.Close<GotoChargeWin>();
        //     if (DayRemind.Instance.GetDayRemind(DayRemind.DJQTip))
        //     {
        //         var pack = new CA125_tagCMCoinBuyOrderInfo();
        //         pack.AppID = VersionConfig.Get().appId;
        //         pack.AppIDLen = (byte)pack.AppID.Length;
        //         pack.OrderInfo = cpInfo;
        //         pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
        //         GameNetSystem.Instance.SendInfo(pack);
        //     }
        //     else
        //     {
        //         ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("GameCashRule1", money), Language.Get("TodayNoNotify"), (bool isOk, bool isToggle) =>
        //         {
        //             if (isOk)
        //             {
        //                 var pack = new CA125_tagCMCoinBuyOrderInfo();
        //                 pack.AppID = VersionConfig.Get().appId;
        //                 pack.AppIDLen = (byte)pack.AppID.Length;
        //                 pack.OrderInfo = cpInfo;
        //                 pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
        //                 GameNetSystem.Instance.SendInfo(pack);
        //             }
        //             if (isToggle)
        //             {
        //                 DayRemind.Instance.SetDayRemind(DayRemind.DJQTip, true);
        //             }
        //         });
        //     }
        // }
        // else
        // {
        //     FreePlatformPayEx(title, money, cpInfo);
        // }
            UIManager.Instance.CloseWindow<GotoChargeWin>();
            if (DayRemind.Instance.GetDayRemind(DayRemind.DJQTip))
            {
                var pack = new CA125_tagCMCoinBuyOrderInfo();
                pack.AppID = VersionConfig.Get().appId;
                pack.AppIDLen = (byte)pack.AppID.Length;
                pack.OrderInfo = cpInfo;
                pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
                GameNetSystem.Instance.SendInfo(pack);
            }
            else
            {
                ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("GameCashRule1", money), Language.Get("TodayNoNotify"), (bool isOk, bool isToggle) =>
                {
                    if (isOk)
                    {
                        var pack = new CA125_tagCMCoinBuyOrderInfo();
                        pack.AppID = VersionConfig.Get().appId;
                        pack.AppIDLen = (byte)pack.AppID.Length;
                        pack.OrderInfo = cpInfo;
                        pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
                        GameNetSystem.Instance.SendInfo(pack);
                    }
                    if (isToggle)
                    {
                        DayRemind.Instance.SetDayRemind(DayRemind.DJQTip, true);
                    }
                });
            }
        }
        else
        {
            FreePlatformPayEx(title, money, cpInfo);
        }
    }
    public void FreePlatformPayEx(string title, float money, string cpInfo)
Main/System/Battle/BattleField/OperationAgent/HandModeOperationAgent.cs
@@ -40,9 +40,9 @@
                //    检查一下锤子的消耗
                //FightPoint             用于记录消耗战锤倍数,小于等于1时默认1倍,大于1时为对应消耗倍值,0418刷新类型22
                BattleDebug.LogError("HandModeOperationAgent DoNext  2");
                ulong costRate = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.FightPoint);
                long costRate = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.FightPoint);
                ulong cost = (costRate > 1 ? costRate : 1) * 1; // 1是默认消耗
                long cost = (costRate > 1 ? costRate : 1) * 1; // 1是默认消耗
Main/System/Battle/BattleManager.cs
@@ -32,8 +32,8 @@
    protected void OnPlayerLoginOk()
    {
        ulong exAttr1 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr1);
        ulong exAttr2 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr2);
        long exAttr1 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr1);
        long exAttr2 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr2);
        int MapID = 1;
        int FuncLineID = (int)exAttr2;
Main/System/CustomizedGift/CustomizedGiftChooseCell.cs
@@ -26,7 +26,7 @@
                int selectID = selectItemInfo[CustomizedRechargeModel.Instance.chooseWinIndex][itemIndex];
                int itemId = CTGSelectItemConfig.Get(selectID).ItemID;
                int count = CTGSelectItemConfig.Get(selectID).ItemCount;
                var itemData = new ItemCellModel((int)itemId, false, (ulong)count);
                var itemData = new ItemCellModel(itemId, false, count);
                images[i].SetActive(CustomizedRechargeModel.Instance.GetChooseSubIndex(CustomizedRechargeModel.Instance.chooseWinIndex) - 1 == i);
                itemCells[i].SetActive(true);
                itemCells[i].Init(itemData);
Main/System/CustomizedGift/CustomizedGiftChooseWin.cs
@@ -105,7 +105,7 @@
                if (chooseIndex != 0)
                {
                    int selectID = ctgConfig.SelectItemInfo[i][chooseIndex - 1];
                    var itemData = new ItemCellModel(CTGSelectItemConfig.Get(selectID).ItemID, false, (ulong)CTGSelectItemConfig.Get(selectID).ItemCount);
                    var itemData = new ItemCellModel(CTGSelectItemConfig.Get(selectID).ItemID, false, CTGSelectItemConfig.Get(selectID).ItemCount);
                    itemCellList[i].Init(itemData);
                    if (i == CustomizedRechargeModel.Instance.chooseWinIndex)
                    {
Main/System/CustomizedGift/CustomizedRechargeModel.cs
@@ -52,7 +52,7 @@
            {
                int selectID = selectItemInfo[j][selectedItemIndexs[j] - 1];
                items.Add(new Item(CTGSelectItemConfig.Get(selectID).ItemID, (ulong)CTGSelectItemConfig.Get(selectID).ItemCount));
                items.Add(new Item(CTGSelectItemConfig.Get(selectID).ItemID, CTGSelectItemConfig.Get(selectID).ItemCount));
            }
        }
        else
@@ -143,7 +143,7 @@
                if (i < awards.Count)
                {
                    var award = awards[i];
                    var itemData = new ItemCellModel(award.id, false, (ulong)award.countEx);
                    var itemData = new ItemCellModel(award.id, false, award.countEx);
                    itemCells[i].Init(itemData);
                    itemCells[i].button.SetListener(() =>
                    {
Main/System/HappyXB/HappyXBModel.cs
@@ -8,348 +8,79 @@
public class HappyXBModel : GameSystemManager<HappyXBModel>
{
    private Dictionary<string, XBGetItemConfig> xbGetItemDict = new Dictionary<string, XBGetItemConfig>();
    private Dictionary<int, List<XBGetItemConfig>> xbTypeItemDict = new Dictionary<int, List<XBGetItemConfig>>();
    private Dictionary<string, Dictionary<int, XBGetItem>> jobXBItemDict = new Dictionary<string, Dictionary<int, XBGetItem>>();
    private Dictionary<int, XBFuncSet> xbFuncSetDict = new Dictionary<int, XBFuncSet>();
    public Dictionary<int, int> XBCostTypeDict = new Dictionary<int, int>();
    public HappXBTitle title = HappXBTitle.Best;
    //寻宝产出库
    private Dictionary<int, Dictionary<int, XBGetItemConfig>> xbGetItemDict = new Dictionary<int, Dictionary<int, XBGetItemConfig>>(); //奖池的所有物品(按类型+等级)
    private Dictionary<int, List<XBGetItemConfig>> xbTypeItemDict = new Dictionary<int, List<XBGetItemConfig>>(); //奖池的所有物品(按类型)
    float xbLastTime = 0;   //等待服务端回复 如果太长就重置为不等待
    bool m_IsWaitServerXB = false;  // 等待服务端回复
    public bool isXBCoolTime
    {
        get
        {
            #if UNITY_EDITOR
            if (Time.time - xbLastTime > 1)
            #else
            if (Time.time - xbLastTime > 10)
            #endif
            {
                m_IsWaitServerXB = false;
                return m_IsWaitServerXB;
            }
    public string USETOOLXBKey = string.Empty;
    public static string HAPPYXBITEMKEY;
    public List<ArrayList> XBNotifyParms = new List<ArrayList>();
    public bool isXBCoolTime { get; set; }
            return m_IsWaitServerXB;
        }
    public bool isJumpBestXB { get; set; }
    public bool isJumpRuneXB { get; set; }
    public bool isJumpGubaoXB { get; set; }
    public bool isJumpGatherSoulXB { get; set; } //聚魂寻宝:是否跳过动画
        set
        {
            m_IsWaitServerXB = value;
            xbLastTime = Time.time;
        }
    }
    private Dictionary<int, XBTypeInfo> xbTypeInfoDict = new Dictionary<int, XBTypeInfo>(); //抽奖状态相关的 服务器记录
    public override void Init()
    {
        isJumpBestXB = false;
        isJumpRuneXB = false;
        isJumpGubaoXB = false;
        isJumpGatherSoulXB = false;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        FuncOpen.Instance.OnFuncStateChangeEvent += UpdateFuncState;
        PackManager.Instance.RefreshItemEvent += RefreshXBTool;
        xbGetItemDict.Clear();
        xbTypeItemDict.Clear();
        xbFuncSetDict.Clear();
        List<XBGetItemConfig> list = XBGetItemConfig.GetValues();
        for (int i = 0; i < list.Count; i++)
        {
            string key = StringUtility.Contact(list[i].TreasureType, list[i].MinLV);
            if (!xbGetItemDict.ContainsKey(key))
            if (!xbGetItemDict.ContainsKey(list[i].TreasureType))
            {
                xbGetItemDict.Add(key, list[i]);
                xbGetItemDict.Add(list[i].TreasureType, new Dictionary<int, XBGetItemConfig>());
            }
            xbGetItemDict[list[i].TreasureType].Add(list[i].MinLV, list[i]);
            if (!xbTypeItemDict.ContainsKey(list[i].TreasureType))
            {
                List<XBGetItemConfig> typeItemlist = new List<XBGetItemConfig>();
                typeItemlist.Add(list[i]);
                xbTypeItemDict.Add(list[i].TreasureType, typeItemlist);
                xbTypeItemDict.Add(list[i].TreasureType, new List<XBGetItemConfig>());
            }
            else
            {
                xbTypeItemDict[list[i].TreasureType].Add(list[i]);
            }
            xbTypeItemDict[list[i].TreasureType].Add(list[i]);
        }
    }
        SetXBFuncDict(1);
        SetXBFuncDict(2);
        // var treasureIDArr = JsonMapper.ToObject<int[]>(FuncConfigConfig.Get("TreasureLuckyDraw").Numerical1);
        // for (int i = 0; i < treasureIDArr.Length; i++)
        // {
        //     int type = XBGetItemConfig.Get(treasureIDArr[i]).TreasureType;
        //     SetXBFuncDict(type);
        // }
        SetXBFuncDict(105);
        SetXBFuncDict(106);
        SetXBFuncDict(107);
        SetXBFuncDict(108);
        SysNotifyMgr.Instance.RegisterCondition("HappyXB", SatisfyNotifyCondition);
        XBCostTypeDict.Clear();
        XBCostTypeDict[(int)HappXBTitle.Best] = TreasureSetConfig.Get(1).CostMoneyType;
        XBCostTypeDict[(int)HappXBTitle.Rune] = TreasureSetConfig.Get(2).CostMoneyType;
        // for (int i = 0; i < treasureIDArr.Length; i++)
        // {
        //     int type = XBGetItemConfig.Get(treasureIDArr[i]).TreasureType;
        //     XBCostTypeDict[(int)HappXBTitle.Gubao1 + i] = TreasureSetConfig.Get(type).CostMoneyType;
        // }
        XBCostTypeDict[(int)HappXBTitle.YunShi1] = TreasureSetConfig.Get(105).CostMoneyType;
        XBCostTypeDict[(int)HappXBTitle.YunShi2] = TreasureSetConfig.Get(106).CostMoneyType;
        XBCostTypeDict[(int)HappXBTitle.YunShi3] = TreasureSetConfig.Get(107).CostMoneyType;
        XBCostTypeDict[(int)HappXBTitle.YunShi4] = TreasureSetConfig.Get(108).CostMoneyType;
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
        FuncOpen.Instance.OnFuncStateChangeEvent -= UpdateFuncState;
        PackManager.Instance.RefreshItemEvent -= RefreshXBTool;
    }
    public void OnBeforePlayerDataInitialize()
    {
        PlayerDatas.Instance.playerDataRefreshEvent -= RefreshStoreScore;
        FuncOpen.Instance.OnFuncStateChangeEvent -= UpdateFuncState;
        PackManager.Instance.RefreshItemEvent -= RefreshXBTool;
        isXBCoolTime = false;
        XBNotifyParms.Clear();
        xbTypeInfoDict.Clear();
    }
    public void OnAfterPlayerDataInitialize()
    {
        SetXBGetItemModel();
    }
    public void OnPlayerLoginOk()
    {
        int playerId = (int)PlayerDatas.Instance.baseData.PlayerID;
        HAPPYXBITEMKEY = StringUtility.Contact(playerId, "HappyXBItemTime");
        USETOOLXBKey = StringUtility.Contact(playerId, "UseToolXB");
        XBWarehouseRedPoint();
        PlayerDatas.Instance.playerDataRefreshEvent += RefreshStoreScore;
        PackManager.Instance.RefreshItemEvent += RefreshXBTool;
        FuncOpen.Instance.OnFuncStateChangeEvent += UpdateFuncState;
    }
    /// <summary>
    /// 检测自身玩家是否需要信息提示
    /// </summary>
    /// <param name="key"></param>
    /// <param name="paramArray"></param>
    /// <returns></returns>
    private bool SatisfyNotifyCondition(string key, ArrayList paramArray)
    {
        switch (title)
        {
            case HappXBTitle.Best:
                if (isJumpBestXB)
                {
                    return true;
                }
                break;
            case HappXBTitle.Rune:
                if (isJumpRuneXB)
                {
                    return true;
                }
                break;
            case HappXBTitle.Gubao1:
            case HappXBTitle.Gubao2:
            case HappXBTitle.Gubao3:
            case HappXBTitle.Gubao4:
                if (isJumpGubaoXB)
                {
                    return true;
                }
                break;
            case HappXBTitle.GatherSoul:
                if (isJumpGatherSoulXB)
                {
                    return true;
                }
                break;
            case HappXBTitle.YunShi1:
            case HappXBTitle.YunShi2:
            case HappXBTitle.YunShi3:
            case HappXBTitle.YunShi4:
                // if (ModelCenter.Instance.GetModelEx<YunShiXBActModel>().isSkipXB)
                // {
                //     return true;
                // }
                break;
        }
        XBNotifyParms.Add(new ArrayList(paramArray));
        if (paramArray != null && paramArray.Count > 0 &&
            paramArray[0].Equals(UIHelper.ServerStringTrim(PlayerDatas.Instance.baseData.PlayerName)))
        {
            return false;
        }
        return true;
    }
    public void GetNotifyResult(int itemId, int itemCount)
    {
        int notifyIndex = 0;
        if (CheckNotifyItemByIdAndCnt(itemId, itemCount, out notifyIndex))
        {
            SysNotifyMgr.Instance.ShowTip("HappyXB", XBNotifyParms[notifyIndex].ToArray());
        }
    }
    private bool CheckNotifyItemByIdAndCnt(int itemId, int itemCnt, out int notifyIndex)
    {
        notifyIndex = 0;
        for (int i = 0; i < XBNotifyParms.Count; i++)
        {
            if (XBNotifyParms[i] != null && XBNotifyParms[i].Count > 3)
            {
                int notifyItemId = 0;
                int.TryParse(XBNotifyParms[i][1].ToString(), out notifyItemId);
                int notifyItemCnt = 0;
                int.TryParse(XBNotifyParms[i][3].ToString(), out notifyItemCnt);
                if (notifyItemId == itemId && notifyItemCnt == itemCnt)
                {
                    notifyIndex = i;
                    return true;
                }
            }
        }
        return false;
    }
    private void SetXBFuncDict(int type)
    {
        var treasureSetCfg = TreasureSetConfig.Get(type);
        if (!xbFuncSetDict.ContainsKey(type))
        {
            XBFuncSet funcSet = new XBFuncSet();
            funcSet.xbType = type;
            funcSet.xbNums = treasureSetCfg.TreasureCountList;
            funcSet.xbPrices = treasureSetCfg.CostMoneyList;
            funcSet.costToolIds = new int[] { treasureSetCfg.CostItemID, treasureSetCfg.CostItemID };
            funcSet.costToolNums = treasureSetCfg.CostItemCountList;
            funcSet.dailyFreeCount = treasureSetCfg.DailyFreeCount;
            funcSet.xbScores = new int[] { treasureSetCfg.AwardMoneyValue, treasureSetCfg.AwardMoneyValue * treasureSetCfg.TreasureCountList[1] };
            xbFuncSetDict.Add(funcSet.xbType, funcSet);
        }
    }
    public XBFuncSet GetXBFuncSet(int type)
    {
        XBFuncSet funcSet = null;
        xbFuncSetDict.TryGetValue(type, out funcSet);
        return funcSet;
    }
    //默认优先使用道具寻宝
    public bool IsUseToolXB()
    {
        return true;
        //if (!PlayerPrefs.HasKey(USETOOLXBKey))
        //{
        //    LocalSave.SetBool(USETOOLXBKey, true);
        //    return true;
        //}
        //else
        //{
        //    return LocalSave.GetBool(USETOOLXBKey);
        //}
    }
    public void SetUseToolXB(bool isToolXB)
    {
        //LocalSave.SetBool(USETOOLXBKey, isToolXB);
    }
    private void SetXBGetItemModel()
    {
        jobXBItemDict.Clear();
        Dictionary<int, XBGetItem> getItemDict = new Dictionary<int, XBGetItem>();
        Dictionary<int, List<int>> jobItemDict = new Dictionary<int, List<int>>();
        int playerJob = PlayerDatas.Instance.baseData.Job;
        foreach (var key in xbGetItemDict.Keys)
        {
            getItemDict.Clear();
            jobItemDict.Clear();
            Dictionary<int, XBGetItem> jobGetItemDict = new Dictionary<int, XBGetItem>();
            XBGetItemConfig getItemConfig = xbGetItemDict[key];
            jobXBItemDict.Add(key, jobGetItemDict);
            JsonData getItemJson = JsonMapper.ToObject(getItemConfig.GridItemInfo);
            foreach (var grid in getItemJson.Keys)
            {
                int id = int.Parse(getItemJson[grid][0].ToString());
                int count = int.Parse(getItemJson[grid][1].ToString());
                XBGetItem getItem = new XBGetItem();
                getItem.SetModel(int.Parse(grid), id, count);
                getItemDict.Add(getItem.gridIndex, getItem);
            }
            JsonData jobReplaceJson = JsonMapper.ToObject(getItemConfig.JobItemList);
            if (jobReplaceJson.IsArray)
            {
                for (int i = 0; i < jobReplaceJson.Count; i++)
                {
                    List<int> itemIdlist = new List<int>();
                    jobItemDict.Add(i, itemIdlist);
                    if (jobReplaceJson[i].IsArray)
                    {
                        for (int j = 0; j < jobReplaceJson[i].Count; j++)
                        {
                            int id = int.Parse(jobReplaceJson[i][j].ToString());
                            itemIdlist.Add(id);
                        }
                    }
                }
            }
            foreach (var model in getItemDict.Values)
            {
                ItemConfig itemConfig = ItemConfig.Get(model.itemId);
                if (itemConfig.JobLimit == 0)
                {
                    jobGetItemDict.Add(model.gridIndex, model);
                }
                else
                {
                    bool isReplace = false;
                    foreach (var list in jobItemDict.Values)
                    {
                        if (list.Contains(model.itemId))
                        {
                            for (int i = 0; i < list.Count; i++)
                            {
                                int equipJob = int.Parse(list[i].ToString().Substring(0, 1));
                                if (playerJob == equipJob)
                                {
                                    isReplace = true;
                                    XBGetItem getItem = new XBGetItem();
                                    getItem.SetModel(model.gridIndex, list[i], model.count);
                                    jobGetItemDict.Add(getItem.gridIndex, getItem);
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!isReplace)
                    {
                        jobGetItemDict.Add(model.gridIndex, model);
                    }
                }
            }
        }
    }
    public Dictionary<int, XBGetItem> GetXBGetItemByID(int type)
    {
        int lv = 0;
        List<XBGetItemConfig> configlist = null;
        xbTypeItemDict.TryGetValue(type, out configlist);
        if (configlist != null)
        {
            for (int i = configlist.Count - 1; i > -1; i--)
            {
                if (PlayerDatas.Instance.baseData.LV >= configlist[i].MinLV)
                {
                    lv = configlist[i].MinLV;
                    break;
                }
            }
        }
        string key = StringUtility.Contact(type, lv);
        Dictionary<int, XBGetItem> dict = null;
        jobXBItemDict.TryGetValue(key, out dict);
        return dict;
    }
    public XBGetItemConfig GetXBItemConfigByType(int type)
    {
@@ -363,14 +94,11 @@
                if (PlayerDatas.Instance.baseData.LV >= configlist[i].MinLV)
                {
                    lv = configlist[i].MinLV;
                    break;
                    return configlist[i];
                }
            }
        }
        XBGetItemConfig xbItemConfig = null;
        string key = StringUtility.Contact(type, lv);
        xbGetItemDict.TryGetValue(key, out xbItemConfig);
        return xbItemConfig;
        return null;
    }
    #region 处理服务端数据
@@ -379,10 +107,9 @@
    public int addXBScore { get; private set; }
    public int addXBScoreType { get; private set; } //寻宝积分货币类型
    public int addXBLuckValue { get; private set; }
    private Dictionary<int, XBGetItem> xbResultDict = new Dictionary<int, XBGetItem>();
    public Dictionary<int, XBGetItem> xbResultDict { get; private set; } = new Dictionary<int, XBGetItem>(); //奖品顺序:奖品
    public void GetServerXBResult(HA350_tagMCTreasureResult result)
    {
        XBNotifyParms.Clear();
        xbResultDict.Clear();
        addXBScore = result.AddMoneyValue;
        addXBScoreType = result.AddMoneyType;
@@ -410,105 +137,41 @@
                }
            }
        }
        SetXBResultRecord();
        isXBCoolTime = false;
        if (RefreshXBResultAct != null)
        {
            RefreshXBResultAct();
        }
        if (!UIManager.Instance.IsOpened<HeroCallResultWin>())
        {
            UIManager.Instance.OpenWindow<HeroCallResultWin>();
        }
    }
    List<string> itemGetTimeArray = new List<string>();
    List<string> getNewItemLoglist = new List<string>();
    List<XBGetItem> xbItemRecordlist = new List<XBGetItem>();
    public void SetXBResultRecord()
    {
        if (PlayerPrefs.HasKey(HAPPYXBITEMKEY))
    public int GetCountInResult(int itemID)
    {
        int count = 0;
        if (xbResultDict != null && xbResultDict.Count > 0)
        {
            itemGetTimeArray = LocalSave.GeStringArray(HappyXBModel.HAPPYXBITEMKEY).ToList();
        }
        else
        {
            itemGetTimeArray.Clear();
        }
        xbItemRecordlist.Clear();
        getNewItemLoglist.Clear();
        xbItemRecordlist.AddRange(GetXBResultlist());
        if (xbItemRecordlist != null)
        {
            int remianLogNum = (itemGetTimeArray.Count + xbItemRecordlist.Count) - 30;
            if (remianLogNum > 0)
            foreach (var item in xbResultDict)
            {
                int startIndex = itemGetTimeArray.Count - remianLogNum;
                itemGetTimeArray.RemoveRange(startIndex, remianLogNum);
                if (item.Value.itemId == itemID)
                {
                    count++;
                }
            }
            xbItemRecordlist.Sort(CompareByTime);
            for (int i = 0; i < xbItemRecordlist.Count; i++)
            {
                string log = Language.Get("HappyXBGetItemTime", xbItemRecordlist[i].createTimeStr, UIHelper.ServerStringTrim(PlayerDatas.Instance.baseData.PlayerName),
                    xbItemRecordlist[i].itemId, xbItemRecordlist[i].count);
                getNewItemLoglist.Add(log);
            }
            if (getNewItemLoglist.Count > 0)
            {
                itemGetTimeArray.InsertRange(0, getNewItemLoglist);
                LocalSave.SetStringArray(HappyXBModel.HAPPYXBITEMKEY, itemGetTimeArray.ToArray());
            }
        }
        return count;
    }
    public int CompareByTime(XBGetItem start, XBGetItem end)
    {
        DateTime startTime = start.createTime;
        DateTime endTime = end.createTime;
        if (startTime.CompareTo(endTime) != 0) return -startTime.CompareTo(endTime);
        return 0;
    }
    public List<XBGetItem> rangelist = new List<XBGetItem>();
    List<int> index = new List<int>();
    public List<XBGetItem> GetXBResultlist()
    {
        rangelist.Clear();
        index.Clear();
        List<XBGetItem> xbItemlist = xbResultDict.Values.ToList();
        for (int i = 0; i < xbItemlist.Count; i++)
        {
            index.Add(i);
        }
        SetRandomList(xbItemlist);
        return rangelist;
    }
    public void SetRandomList(List<XBGetItem> xbItemlist)
    {
        int currentRandom = UnityEngine.Random.Range(0, index.Count);
        XBGetItem current = xbItemlist[index[currentRandom]];
        if (!rangelist.Contains(current))
        {
            rangelist.Add(current);
            index.Remove(index[currentRandom]);
        }
        if (index.Count > 0)
        {
            SetRandomList(xbItemlist);
        }
    }
    public Dictionary<int, XBGetItem> GetXbResultDict()
    {
        return xbResultDict;
    }
    public void ClearXBRusltData()
    {
        xbResultDict.Clear();
    }
    private Dictionary<int, XBTypeInfo> xbTypeInfoDict = new Dictionary<int, XBTypeInfo>();
    public void GetServerXBInfo(HA351_tagMCTreasureInfo info)
    {
        for (int i = 0; i < info.InfoCount; i++)
@@ -556,7 +219,7 @@
            RefreshXBTypeInfoAct();
        }
        BestAndRuneXBRedPoint();
        HeroCallRedPoint();
    }
    public XBTypeInfo GetXBInfoByType(int type)
@@ -567,14 +230,16 @@
    }
    /// <summary>
    /// type 1 极品寻宝 2 符印寻宝  index 0 单次寻宝 1 多次寻宝
    ///costType 0-默认仙玉;1-免费次数;2-寻宝道具
    /// 请求寻宝
    /// </summary>
    /// <param name="type"></param>
    /// <param name="index"></param>
    /// <param name="type">寻宝类型</param>
    /// <param name="index">0 单次寻宝 1 多次寻宝</param>
    /// <param name="costType">0-货币;1-免费次数;2-寻宝道具</param>
    public event Action<int> StartXBEvent;
    public void SendXBQuest(int type, int index, int costType)
    {
        if (isXBCoolTime) return;
        isXBCoolTime = true;
        CA568_tagCMRequestTreasure treasure = new CA568_tagCMRequestTreasure();
        treasure.TreasureType = (byte)type;
@@ -593,14 +258,14 @@
    {
        switch (type)
        {
            case PackType.Treasure:
                SinglePack singlePack = PackManager.Instance.GetSinglePack(type);
                if (GeneralDefine.maxXBGridCount - singlePack.GetAllItems().Count < needGrid)
                {
                    SysNotifyMgr.Instance.ShowTip("XBWarehouseFull");
                    return false;
                }
                break;
            // case PackType.Treasure:
            //     SinglePack singlePack = PackManager.Instance.GetSinglePack(type);
            //     if (GeneralDefine.maxXBGridCount - singlePack.GetAllItems().Count < needGrid)
            //     {
            //         SysNotifyMgr.Instance.ShowTip("XBWarehouseFull");
            //         return false;
            //     }
            //     break;
            case PackType.Item:
                if (PackManager.Instance.GetEmptyGridCount(type) < needGrid)
                {
@@ -608,11 +273,19 @@
                    return false;
                }
                break;
            case PackType.Hero:
                if (PackManager.Instance.GetEmptyGridCount(type) < needGrid)
                {
                    SysNotifyMgr.Instance.ShowTip("HeroBagFull");
                    return false;
                }
                break;
        }
        return true;
    }
    public void SendOneXBQuest(PackType type, int xbType)
    public void SendOneXBQuest(int xbType)
    {
        var config = TreasureSetConfig.Get(xbType);
        if (GetXBInfoByType(xbType).treasureCountToday + config.TreasureCountList[0] > config.DailyMaxCount)
@@ -621,38 +294,48 @@
            return;
        }
        var funcSet = GetXBFuncSet(xbType);
        if (CheckIsEmptyGrid(type))
        var funcSet = TreasureSetConfig.Get(xbType);
        if (CheckIsEmptyGrid((PackType)config.PackType))
        {
            if (IsHaveOneXBTool(xbType))
            //道具寻宝
            if (funcSet.CostItemID != 0 && IsHaveOneXBTool(xbType))
            {
                SendXBQuest(xbType, 0, 2);
                return;
            }
            //货币寻宝
            int moneyType = funcSet.CostMoneyType;
            int xbOneMoney = funcSet.CostMoneyList[0];
            int moneyType = XBCostTypeDict[xbType];
            int xbOneMoney = funcSet.xbPrices[0];
            if (UIHelper.GetMoneyCnt(moneyType) >= (ulong)xbOneMoney)
            if (UIHelper.GetMoneyCnt(moneyType) >= xbOneMoney)
            {
                StoreModel.Instance.UseMoneyCheck(xbOneMoney, () =>
                //暂定充值货币需要二次确认
                if (moneyType == 1)
                {
                    StoreModel.Instance.UseMoneyCheck(xbOneMoney, moneyType, () =>
                    {
                        SendXBQuest(xbType, 0, 0);
                    }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, xbOneMoney,
                    UIHelper.GetIconNameWithMoneyType(moneyType), funcSet.CostItemCountList[0]));
                }
                else
                {
                    SendXBQuest(xbType, 0, 0);
                }, xbType == 1 ? 5 : 6, fullTip: Language.Get("TreasurePavilion08", xbOneMoney, moneyType, funcSet.costToolIds[0], 1));
                }
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
                ItemTipUtility.ShowMoneyTip(moneyType);
            }
        }
    }
    public void SendXBManyQuest(PackType type, int xbType)
    public void SendXBManyQuest(int xbType)
    {
        var config = TreasureSetConfig.Get(xbType);
        if (GetXBInfoByType(xbType).treasureCountToday + config.TreasureCountList[1] > config.DailyMaxCount)
        {
@@ -660,83 +343,68 @@
            return;
        }
        var funcSet = GetXBFuncSet(xbType);
        if (CheckIsEmptyGrid(type))
        var funcSet = TreasureSetConfig.Get(xbType);
        if (CheckIsEmptyGrid((PackType)config.PackType, 10))
        {
            int toolCnt = 0;
            int needToolCnt = 0;
            int needMoney = 0;
            if (IsHaveManyXBToolEx(xbType, out toolCnt, out needToolCnt, out needMoney))
            {
                if (toolCnt >= needToolCnt)
                {
                    CheckXBManyLimit(0, xbType, 2);
                    return;
                }
                SendXBQuest(xbType, 1, 2);
            }
            int moneyType = XBCostTypeDict[xbType];
            int xbManyMoney = needMoney == 0 ? funcSet.xbPrices[1] : needMoney;
            if (UIHelper.GetMoneyCnt(moneyType) >= (ulong)xbManyMoney)
            //货币寻宝
            int moneyType = funcSet.CostMoneyType;
            if (UIHelper.GetMoneyCnt(moneyType) >= needMoney)
            {
                StoreModel.Instance.UseMoneyCheck(xbManyMoney, () =>
                //暂定充值货币需要二次确认
                if (moneyType == 1)
                {
                    StoreModel.Instance.UseMoneyCheck(needMoney, moneyType, () =>
                    {
                        //只要有道具就是道具寻宝,不足部分服务端扣货币
                        SendXBQuest(xbType, 1, toolCnt > 0 ? 2 : 0);
                    }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, needMoney,
                    UIHelper.GetIconNameWithMoneyType(moneyType), needToolCnt - toolCnt));
                }
                else
                {
                    SendXBQuest(xbType, 1, toolCnt > 0 ? 2 : 0);
                }, xbType == 1 ? 5 : 6, fullTip: Language.Get("TreasurePavilion08", xbManyMoney, moneyType, funcSet.costToolIds[1], needToolCnt - toolCnt));
                }
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
                ItemTipUtility.ShowMoneyTip(moneyType);
            }
        }
    }
    public void CheckXBManyLimit(int needMoney, int xbtype, int costType)
    {
        int moneyType = XBCostTypeDict[xbtype];
        if (UIHelper.GetMoneyCnt(moneyType) >= (ulong)needMoney)
        {
            SendXBQuest(xbtype, 1, costType);
        }
        else
        {
            //WindowCenter.Instance.Open<RechargeTipWin>();
            SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
        }
    }
    #endregion
    public bool IsHaveFreeXB(int type)
    {
        int freeCountToday = 0;
        XBTypeInfo typeInfo = GetXBInfoByType(type);
        if (typeInfo == null)
        if (typeInfo != null)
        {
            typeInfo = new XBTypeInfo()
            {
                xbType = type,
                luckValue = 0,
                freeCountToday = 0,
                treasureCount = 0,
            };
            freeCountToday = typeInfo.freeCountToday;
        }
        //判断是否有免费次数,且免费次数是否用完
        var funcSet = GetXBFuncSet(type);
        return typeInfo.freeCountToday < funcSet.dailyFreeCount;
        var funcSet = TreasureSetConfig.Get(type);
        return freeCountToday < funcSet.DailyFreeCount;
    }
    public bool CheckIsXBTool(int itemId, int type)
    {
        XBFuncSet funcSet = GetXBFuncSet(type);
        var funcSet = TreasureSetConfig.Get(type);
        if (funcSet == null) return false;
        if (funcSet.costToolIds.Contains(itemId))
        if (funcSet.CostItemID == itemId)
        {
            return true;
        }
@@ -744,11 +412,11 @@
    }
    public bool IsHaveOneXBTool(int type)
    {
        XBFuncSet funcSet = GetXBFuncSet(type);
        var funcSet = TreasureSetConfig.Get(type);
        if (funcSet == null) return false;
        int toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.costToolIds[0]);
        if (toolCnt >= funcSet.costToolNums[0])
        int toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.CostItemID);
        if (toolCnt >= funcSet.CostItemCountList[0])
        {
            return true;
        }
@@ -756,22 +424,6 @@
        return false;
    }
    //needToolCnt 为配表中需要的道具数量
    public bool IsHaveManyXBTool(int type, out int toolCnt, out int needToolCnt)
    {
        toolCnt = 0;
        needToolCnt = 0;
        XBFuncSet funcSet = GetXBFuncSet(type);
        if (funcSet == null) return false;
        toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.costToolIds[1]);
        needToolCnt = funcSet.costToolNums[1];
        if (toolCnt > 0)
        {
            return true;
        }
        return false;
    }
    //needToolCnt 为配表中需要的道具数量
    // 可获得真正需要补足购买道具的金额
@@ -780,240 +432,117 @@
        toolCnt = 0;
        needToolCnt = 0;    //配置中需要的道具数量
        needMoney = 0;  //真正需要补足购买道具的金额
        XBFuncSet funcSet = GetXBFuncSet(type);
        var funcSet = TreasureSetConfig.Get(type);
        if (funcSet == null) return false;
        toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.costToolIds[1]);
        needToolCnt = funcSet.costToolNums[1];
        toolCnt = (int)PackManager.Instance.GetItemCountByID(PackType.Item, funcSet.CostItemID);
        needToolCnt = funcSet.CostItemCountList[1];
        if (toolCnt > 0)
        if (toolCnt >= needToolCnt)
        {
            if (toolCnt < needToolCnt)
            {
                needMoney = funcSet.xbPrices[1] / needToolCnt * (needToolCnt - toolCnt);
            }
            //道具足够
            return true;
        }
        if (funcSet.CostMoneyType != 0)
        {
            if (toolCnt != 0 && toolCnt < needToolCnt)
            {
                //部分不足的按单次价格算
                needMoney = funcSet.CostMoneyList[0] * (needToolCnt - toolCnt);
            }
            else
            {
                //全部不足的按多次价格算 可能配置了折扣
                needMoney = funcSet.CostMoneyList[1];
            }
        }
        return false;
    }
    public event Action<float> RefreshBestXBTimeAct;
    public event Action<float> RefreshRuneXBTimeAct;
    public void RefreshBestXBTime(float time)
    public int GetCostType(int type)
    {
        if (RefreshBestXBTimeAct != null)
        {
            RefreshBestXBTimeAct(time);
        }
        if (time <= 0)
        {
            BestAndRuneXBRedPoint();
        }
    }
    public void RefreshRuneXBTime(float time)
    {
        if (RefreshRuneXBTimeAct != null)
        {
            RefreshRuneXBTimeAct(time);
        }
        if (time <= 0)
        {
            BestAndRuneXBRedPoint();
        }
        var funcSet = TreasureSetConfig.Get(type);
        if (funcSet == null) return 0;
        return funcSet.CostMoneyType;
    }
    public event Action<HappXBTitle, int> RefreshAgainXBAct;
    /// <summary>
    /// xbtype 0-单次 1 多次
    /// </summary>
    /// <param name="xBTitle"></param>
    /// <param name="xbType"></param>
    public void SetAgainXBEvent(HappXBTitle xBTitle, int xbType)
    {
        if (RefreshAgainXBAct != null)
        {
            RefreshAgainXBAct(xBTitle, xbType);
        }
    public int GetCostItemID(int type)
    {
        var funcSet = TreasureSetConfig.Get(type);
        if (funcSet == null) return 0;
        return funcSet.CostItemID;
    }
    #region 红点逻辑
    public const int HappyXB_RedKey = 203;
    public const int BestXB_RedKey = 20301;
    public const int RuneXB_RedKey = 20302;
    public const int XBStore_RedKey = 20303;
    public const int XBWarehouse_RedKey = 20304;
    public const int BestXB_OneRedKey = 20301001;
    public const int BestXB_ManyRedKey = 20301002;
    public const int BestXB_FreeRedKey = 20301003;
    public const int RuneXB_OneRedKey = 20302001;
    public const int RuneXB_ManyRedKey = 20302002;
    public const int RuneXB_FreeRedKey = 20302003;
    public const int XBHeroCall1_RedKey = 20300;    //武将免费召唤
    public Redpoint happyXBRed = new Redpoint(HappyXB_RedKey);
    public Redpoint bestXBRed = new Redpoint(HappyXB_RedKey, BestXB_RedKey);
    public Redpoint runeXBRed = new Redpoint(HappyXB_RedKey, RuneXB_RedKey);
    public Redpoint xbStoreRed = new Redpoint(HappyXB_RedKey, XBStore_RedKey);
    public Redpoint xbWarehouseRed = new Redpoint(HappyXB_RedKey, XBWarehouse_RedKey);
    public Redpoint bestXBOneRed = new Redpoint(BestXB_RedKey, BestXB_OneRedKey);
    public Redpoint bestXBManyRed = new Redpoint(BestXB_RedKey, BestXB_ManyRedKey);
    public Redpoint bestXBFreeRed = new Redpoint(BestXB_RedKey, BestXB_FreeRedKey);
    public Redpoint runeXBOneRed = new Redpoint(RuneXB_RedKey, RuneXB_OneRedKey);
    public Redpoint runeXBManyRed = new Redpoint(RuneXB_RedKey, RuneXB_ManyRedKey);
    public Redpoint runeXBFreeRed = new Redpoint(RuneXB_RedKey, RuneXB_FreeRedKey);
    public Redpoint bestXBFreeRed = new Redpoint(HappyXB_RedKey, XBHeroCall1_RedKey);
    private void UpdateFuncState(int funcId)
    {
        if (funcId == (int)FuncOpenEnum.HappyFindTreasure
            || funcId == 184)
        {
            XBWarehouseRedPoint();
            BestAndRuneXBRedPoint();
            XBStoreRedPoint();
        }
        HeroCallRedPoint();
    }
    public void RefreshXBWarehouse()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HappyFindTreasure)) return;
        xbWarehouseRed.state = RedPointState.Simple;
    }
    public void XBWarehouseRedPoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HappyFindTreasure)) return;
        SinglePack singlePack = PackManager.Instance.GetSinglePack(PackType.Treasure);
        if (singlePack == null) return;
        if (singlePack.GetAllItems().Count > 0)
        {
            xbWarehouseRed.state = RedPointState.Simple;
        }
        else
        {
            xbWarehouseRed.state = RedPointState.None;
        }
    }
    private void RefreshXBTool(PackType type, int index, int id)
    {
        if (type != PackType.Item) return;
        if (!CheckIsXBTool(id, 1) && !CheckIsXBTool(id, 2)) return;
        BestAndRuneXBRedPoint();
        if (!CheckIsXBTool(id, (int)HappXBTitle.HeroCallAdvanced))
            return;
        HeroCallRedPoint();
    }
    public void BestAndRuneXBRedPoint()
    //英雄招募
    public void HeroCallRedPoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HappyFindTreasure)) return;
        // 免费 10连 积分
        happyXBRed.state = RedPointState.None;
        int xbtoolCnt = 0;
        int needtoolCnt = 0;
        if (IsHaveFreeXB(1))
        if (IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced))
        {
            bestXBFreeRed.state = RedPointState.Simple;
            return;
        }
        else
        {
            bestXBFreeRed.state = RedPointState.None;
        }
        if (IsHaveManyXBTool(1, out xbtoolCnt, out needtoolCnt))
        if (IsHaveManyXBToolEx((int)HappXBTitle.HeroCallAdvanced, out int xbtoolCnt, out int needtoolCnt, out int needMoney))
        {
            if (xbtoolCnt >= needtoolCnt)
            {
                bestXBManyRed.state = RedPointState.Simple;
            }
            else
            {
                bestXBManyRed.state = RedPointState.None;
            }
            bestXBOneRed.state = RedPointState.Simple;
        }
        else
        {
            bestXBOneRed.state = RedPointState.None;
            bestXBManyRed.state = RedPointState.None;
            happyXBRed.state = RedPointState.Simple;
            return;
        }
        if (FuncOpen.Instance.IsFuncOpen(184) && IsHaveFreeXB(2))
        {
            runeXBFreeRed.state = RedPointState.Simple;
        }
        else
        {
            runeXBFreeRed.state = RedPointState.None;
        }
        //积分足够
        if (FuncOpen.Instance.IsFuncOpen(184) &&
            IsHaveManyXBTool(2, out xbtoolCnt, out needtoolCnt))
        {
            if (xbtoolCnt >= needtoolCnt)
            {
                runeXBManyRed.state = RedPointState.Simple;
            }
            else
            {
                runeXBManyRed.state = RedPointState.None;
            }
            runeXBOneRed.state = RedPointState.Simple;
        }
        else
        {
            runeXBOneRed.state = RedPointState.None;
            runeXBManyRed.state = RedPointState.None;
        }
    }
    private void RefreshStoreScore(PlayerDataType type)
    //按格子库配置的奖池 获得获取物品
    public List<int> GetAllGridLibItemIDByType(int type)
    {
        if (type != PlayerDataType.CDBPlayerRefresh_TreasureScore) return;
        XBStoreRedPoint();
    }
    private List<StoreModel.StoreData> storelist = null;
    public void XBStoreRedPoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HappyFindTreasure)) return;
        ulong moneyNum = UIHelper.GetMoneyCnt(25);
        for (int i = 11; i < 14; i++)
        List<int> itemIDListTemp = new List<int>();
        foreach (var kv in GetXBItemConfigByType(type).GridLibInfo)
        {
            storelist = StoreModel.Instance.TryGetStoreDatas((StoreFunc)i);
            if (storelist.Count > 0)
            {
                List<StoreModel.StoreData> orderlist = new List<StoreModel.StoreData>();
                orderlist.AddRange(storelist);
                orderlist.Sort(CompareByMoney);
                if (moneyNum >= (ulong)orderlist[0].storeConfig.MoneyNumber)
                {
                    xbStoreRed.state = RedPointState.Simple;
                    return;
                }
            }
            itemIDListTemp.AddRange(TreasureItemLibConfig.GetItemIDList(kv.Value));
        }
        xbStoreRed.state = RedPointState.None;
    }
        return itemIDListTemp.Distinct().ToList();
    public int CompareByMoney(StoreModel.StoreData start, StoreModel.StoreData end)
    {
        int money1 = start.storeConfig.MoneyNumber;
        int money2 = end.storeConfig.MoneyNumber;
        if (money1.CompareTo(money2) != 0) return money1.CompareTo(money2);
        int index1 = storelist.IndexOf(start);
        int index2 = storelist.IndexOf(end);
        if (index1.CompareTo(index2) != 0) return index1.CompareTo(index2);
        return 0;
    }
    #endregion
}
    }
public class XBTypeInfo
{
@@ -1026,17 +555,7 @@
    public Dictionary<int, int> gridLimitCntDict;        //<有限制抽取次数的格子编号,已抽到次数> 有限制抽取次数的格子次数信息
}
public class XBFuncSet
{
    public int xbType;// 1 极品寻宝 2 符印寻宝
    public int[] xbNums;
    public int[] xbPrices;
    public int[] costToolIds;
    public int[] costToolNums;
    public int[] xbFreeCDs;
    public int[] xbScores;
    public int dailyFreeCount;
}
public class XBGetItem
{
@@ -1044,7 +563,6 @@
    public int itemId;
    public int count;
    public DateTime createTime;
    public string createTimeStr;
    public void SetModel(int index, int id, int count)
    {
@@ -1052,7 +570,6 @@
        this.itemId = id;
        this.count = count;
        createTime = TimeUtility.ServerNow;
        createTimeStr = TimeUtility.ServerNow.ToString("yyyy-MM-dd HH:mm:ss");
    }
}
@@ -1067,6 +584,9 @@
    Gubao2 = 6,
    Gubao3 = 7,
    Gubao4 = 8,
    HeroCallNormal = 11,    //11-普通招募
    HeroCallAdvanced = 12,  //12-高级招募
    HeroCallScore = 13, //13-积分招募
    YunShi1 = 105,
    YunShi2 = 106,
    YunShi3 = 107,
Main/System/HappyXB/HeroCallResultCell.cs
New file
@@ -0,0 +1,98 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
public class HeroCallResultCell : MonoBehaviour
{
    [SerializeField] UIHeroController heroModel;
    [SerializeField] Image newMarkImg;
    [SerializeField] UIEffectPlayer starEffect;
    [SerializeField] UIEffectPlayer lightEffect;
    [SerializeField] UIEffectPlayer boomEffect;
    [SerializeField] UIEffectPlayer tableEffect;
    /// <summary>
    /// 抽奖结果的小人展示
    /// </summary>
    /// <param name="heroID"></param>
    /// <param name="index">第几抽,0代表单抽</param>
    /// <param name="isForceSkip">强制跳过动画</param>
    public void Display(int heroID, int index, bool isForceSkip=false)
    {
        DisplayAsync(heroID, index, isForceSkip).Forget();
    }
    async UniTask DisplayAsync(int heroID, int index, bool isForceSkip=false)
    {
        this.transform.localScale = Vector3.zero;
        int delaytime = LocalSave.GetBool(HeroUIManager.skipKey, false) ? 50 * index : 100 * index;
        await UniTask.Delay(delaytime);
        this.transform.localScale = Vector3.one;
        //先显示台子,再显示小人
        heroModel.SetActive(false);
        newMarkImg.SetActive(false);
        var heroConfig = HeroConfig.Get(heroID);
        var quality = heroConfig.Quality;
        //是否跳过动画
        if (isForceSkip || LocalSave.GetBool(HeroUIManager.skipKey, false))
        {
            //红色特殊
            if (!isForceSkip)
            {
                boomEffect.playDelayTime = 0;
                boomEffect.PlayByArrIndex(quality > 4 ? 0 : 1);
            }
            DisplayNewMark(heroID);
            DisplayHero(heroConfig);
            tableEffect.Stop();
            tableEffect.isPlaySpineLoop = true;
            tableEffect.PlayByArrIndex(quality);
            return;
        }
        starEffect.PlayByArrIndex(index);
        //紫色开始有播放
        if (quality <= 1)
        {
            lightEffect.Stop();
        }
        else
        {
            lightEffect.PlayByArrIndex(quality - 2);
        }
        boomEffect.playDelayTime = lightEffect.playDelayTime;
        //红色特殊
        boomEffect.PlayByArrIndex(quality > 4 ? 0 : 1);
        //先播放灰色台子上升,再播放小人
        tableEffect.onComplete = () =>
        {
            DisplayNewMark(heroID);
            DisplayHero(heroConfig);
            tableEffect.isPlaySpineLoop = true;
            tableEffect.PlayByArrIndex(quality);
        };
        tableEffect.Stop();
        tableEffect.isPlaySpineLoop = false;
        tableEffect.PlayByArrIndex(0);
    }
    public void DisplayNewMark(int heroID)
    {
        newMarkImg.SetActive(HeroUIManager.Instance.IsNewHero(heroID));
    }
    public void DisplayHero(HeroConfig heroConfig)
    {
        heroModel.SetActive(true);
        heroModel.Create(heroConfig.SkinIDList[0], 0.7f);
    }
}
Main/System/HappyXB/HeroCallResultCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallResultCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 4ba832e02f465a44d9aa977fc15d9f4f
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroCallResultWin.cs
New file
@@ -0,0 +1,285 @@
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 招募结果展示
/// </summary>
public class HeroCallResultWin : UIBase
{
    [SerializeField] GameObject moneyObj;   //立绘时候隐藏
    [SerializeField] OwnItemCell ownItemCell;
    [SerializeField] OwnMoneyCell ownMoneyCell;
    [SerializeField] GameObject result1Obj; //单抽展示
    [SerializeField] HeroCallResultCell result1Cell;
    [SerializeField] GameObject result10Obj;    //十连展示
    [SerializeField] HeroCallResultCell[] result10Cells;
    [SerializeField] GameObject result10LihuiObj; //十连立绘展示
    [SerializeField] UIHeroController roleLHModel;
    [SerializeField] Image qualityImg;
    [SerializeField] HeroCallResultCell showLHResultCell;
    [SerializeField] Image newMarkLHImg;
    [SerializeField] Button showNextlhOrCloseBtn;
    [SerializeField] GameObject heroInfoObj;    //武将信息,单抽和立绘时候显示
    [SerializeField] Text heroNameText;
    [SerializeField] Image heroCountryImg;
    [SerializeField] Image heroJobImg;
    [SerializeField] Text jobPosNameText;
    //按钮区
    [SerializeField] GameObject btnsObj;
    [SerializeField] Button call1Btn;
    [SerializeField] Image call1ItemIcon;
    [SerializeField] Text call1Text;
    [SerializeField] Button call10Btn;
    [SerializeField] Image call10ItemIcon;
    [SerializeField] Text call10Text;
    [SerializeField] Button okBtn;
    int resultState = 0; //0单抽展示 1十连展示 2 十连开始展示 3 十连立绘展示
    bool isSkip = false;
    List<int> showLHHeroIDList = new List<int>();
    protected override void InitComponent()
    {
        okBtn.AddListener(CloseWindow);
        call1Btn.AddListener(SendHeroCall);
        call10Btn.AddListener(() =>
        {
            HeroUIManager.Instance.selectCallIndex = 1;
            HappyXBModel.Instance.SendXBManyQuest((int)HeroUIManager.Instance.selectCallType);
        });
        showNextlhOrCloseBtn.AddListener(RefreshLihui);
    }
    protected override void OnPreOpen()
    {
        isSkip = LocalSave.GetBool(HeroUIManager.skipKey, false);
        UIManager.Instance.CloseWindow<ScrollTipWin>();
        HappyXBModel.Instance.RefreshXBResultAct += UpdateState;
        HappyXBModel.Instance.RefreshXBTypeInfoAct += RefreshBtn;
        InitMoney();
        UpdateState();
        RefreshBtn();
    }
    protected override void OnPreClose()
    {
        HappyXBModel.Instance.RefreshXBResultAct -= UpdateState;
        HappyXBModel.Instance.RefreshXBTypeInfoAct -= RefreshBtn;
    }
    void UpdateState()
    {
        if (HeroUIManager.Instance.selectCallIndex == 0)
        {
            resultState = 0;
        }
        else if (isSkip)
        {
            resultState = 1;
        }
        else
        {
            resultState = 2;
            MoveToNextState().Forget();
        }
        RefreshState();
    }
    async UniTask MoveToNextState()
    {
        await UniTask.Delay(1500);
        showLHHeroIDList.Clear();
        for (int i = 0; i < HappyXBModel.Instance.xbResultDict.Count; i++)
        {
            var heroID = HappyXBModel.Instance.xbResultDict[i].itemId;
            if (HeroConfig.Get(heroID).Quality >= 4)
                showLHHeroIDList.Add(HappyXBModel.Instance.xbResultDict[i].itemId);
        }
        resultState = 3;
        try
        {
            RefreshState();
        }
        catch (System.Exception e)
        {
            Debug.LogWarning(e);
        }
    }
    void RefreshState()
    {
        if (resultState == 0)
        {
            btnsObj.SetActive(true);
            call1Btn.SetActive(HeroUIManager.Instance.selectCallType != HappXBTitle.HeroCallScore ? true : false);
            call10Btn.SetActive(false);
            result1Obj.SetActive(true);
            result10Obj.SetActive(false);
            result10LihuiObj.SetActive(false);
            ShowMoney(true);
            heroInfoObj.SetActive(true);
            result1Cell.Display(HappyXBModel.Instance.xbResultDict[0].itemId, 0);
            RefreshHeroInfo(HappyXBModel.Instance.xbResultDict[0].itemId);
        }
        else if (resultState == 1)
        {
            btnsObj.SetActive(true);
            call1Btn.SetActive(false);
            call10Btn.SetActive(true);
            result1Obj.SetActive(false);
            result10Obj.SetActive(true);
            result10LihuiObj.SetActive(false);
            ShowMoney(true);
            heroInfoObj.SetActive(false);
            if (isSkip)
                Refresh10Result();
        }
        else if (resultState == 2)
        {
            btnsObj.SetActive(false);
            result1Obj.SetActive(false);
            result10Obj.SetActive(true);
            result10LihuiObj.SetActive(false);
            ShowMoney(false);
            heroInfoObj.SetActive(false);
            Refresh10Result();
        }
        else if (resultState == 3)
        {
            btnsObj.SetActive(false);
            result1Obj.SetActive(false);
            result10Obj.SetActive(false);
            result10LihuiObj.SetActive(true);
            ShowMoney(false);
            heroInfoObj.SetActive(true);
            RefreshLihui();
        }
    }
    public void RefreshBtn()
    {
        var funcSet = TreasureSetConfig.Get((int)HeroUIManager.Instance.selectCallType);
        if (funcSet.CostItemID == 0)
        {
            call1ItemIcon.SetActive(false);
            call1Text.SetActive(false);
            call10ItemIcon.SetActive(false);
            call10Text.SetActive(false);
            return;
        }
        call1ItemIcon.SetActive(true);
        call1Text.SetActive(true);
        call10ItemIcon.SetActive(true);
        call10Text.SetActive(true);
        var item = ItemConfig.Get(funcSet.CostItemID);
        var IconKey = item.IconKey;
        call1ItemIcon.SetOrgSprite(IconKey);
        if (HappyXBModel.Instance.IsHaveFreeXB((int)HeroUIManager.Instance.selectCallType))
        {
            call1Text.text = Language.Get("L1127");
        }
        else
        {
            call1Text.text = Language.Get("L1100", item.ItemName, funcSet.CostItemCountList[0]);
        }
        call10ItemIcon.SetOrgSprite(IconKey);
        call10Text.text = Language.Get("L1100", item.ItemName, funcSet.CostItemCountList[1]);
    }
    void ShowMoney(bool show)
    {
        if (HeroUIManager.Instance.selectCallType == HappXBTitle.HeroCallScore)
        {
            moneyObj.SetActive(false);
            return;
        }
        moneyObj.SetActive(show);
    }
    void Refresh10Result()
    {
        for (int i = 0; i < result10Cells.Length; i++)
        {
            result10Cells[i].Display(HappyXBModel.Instance.xbResultDict[i].itemId, i + 1);
        }
    }
    void InitMoney()
    {
        ownItemCell.itemID = TreasureSetConfig.Get((int)HeroUIManager.Instance.selectCallType).CostItemID;
        ownMoneyCell.moneyType = TreasureSetConfig.Get((int)HeroUIManager.Instance.selectCallType).CostMoneyType;
    }
    void SendHeroCall()
    {
        heroInfoObj.SetActive(false);
        HeroUIManager.Instance.selectCallIndex = 0;
        if (HappyXBModel.Instance.IsHaveFreeXB((int)HeroUIManager.Instance.selectCallType))
        {
            HappyXBModel.Instance.SendXBQuest((int)HeroUIManager.Instance.selectCallType, 0, 1);
        }
        else
        {
            HappyXBModel.Instance.SendOneXBQuest((int)HeroUIManager.Instance.selectCallType);
        }
    }
    void RefreshLihui()
    {
        //汇总品质传说及以上的立绘
        int heroID = 0;
        if (showLHHeroIDList.Count > 0)
        {
            heroID = showLHHeroIDList[0];
            showLHHeroIDList.RemoveAt(0);
        }
        else
        {
            resultState = 1;
            RefreshState();
            return;
        }
        var hero = HeroConfig.Get(heroID);
        roleLHModel.Create(hero.SkinIDList[0], HeroUIManager.lihuiScale, motionName: "", isLh: true);
        qualityImg.SetSprite("HeroCallQuality" + hero.Quality);
        newMarkLHImg.SetActive(HeroUIManager.Instance.IsNewHero(heroID));
        showLHResultCell.Display(heroID, 0, true);
        RefreshHeroInfo(heroID);
    }
    void RefreshHeroInfo(int heroID)
    {
        var heroConfig = HeroConfig.Get(heroID);
        heroNameText.text = heroConfig.Name;
        heroNameText.color = UIHelper.GetUIColorByFunc(heroConfig.Quality);
        heroCountryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        heroJobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(heroConfig.Class) + "  " + heroConfig.Desc;
    }
}
Main/System/HappyXB/HeroCallResultWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallResultWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: f9f4600eaeadb9d4dac7b5bd662db641
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroCallRuleWin.cs
New file
@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 招募规则
/// </summary>
public class HeroCallRuleWin : UIBase
{
}
Main/System/HappyXB/HeroCallRuleWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallRuleWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: c9610763bde1ce744b918ba059286aff
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroCallScoreRuleWin.cs
New file
@@ -0,0 +1,63 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 积分招募规则
/// </summary>
public class HeroCallScoreRuleWin : UIBase
{
    [SerializeField] ScrollerController scrollerController;
    [SerializeField] HeroSelectBehaviour heroSelectBehaviour;
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.selectHeroCallListJob = 0;
        HeroUIManager.Instance.selectHeroCallListCountry = 0;
        HeroUIManager.Instance.SortHeroCallList();
        scrollerController.OnRefreshCell += OnRefreshCell;
        Refresh();
        CreateScroller();
    }
    protected override void OnPreClose()
    {
        scrollerController.OnRefreshCell -= OnRefreshCell;
    }
    public override void Refresh()
    {
        heroSelectBehaviour.Display(0, HeroUIManager.Instance.selectHeroListJob, HeroUIManager.Instance.selectHeroListCountry, SelectJobCountry);
    }
    void SelectJobCountry(int job, int country)
    {
        HeroUIManager.Instance.selectHeroCallListJob = job;
        HeroUIManager.Instance.selectHeroCallListCountry = country;
        HeroUIManager.Instance.SortHeroCallList();
        scrollerController.m_Scorller.RefreshActiveCellViews();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cellView)
    {
        var _cell = cellView as HeroSmallHeadLineCell;
        _cell.Display(cellView.index);
    }
    void CreateScroller()
    {
        scrollerController.Refresh();
        for (int i = 0; i < HeroUIManager.Instance.heroCallSortList.Count; i++)
        {
            if (i % 4 == 0)
            {
                scrollerController.AddCell(ScrollerDataType.Header, i);
            }
        }
        scrollerController.Restart();
    }
}
Main/System/HappyXB/HeroCallScoreRuleWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallScoreRuleWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: ebaa9682c49d10d41850e4940cd68934
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroCallScoreWin.cs
New file
@@ -0,0 +1,95 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 积分招募
/// </summary>
public class HeroCallScoreWin : UIBase
{
    [SerializeField] Button ruleBtn;
    [SerializeField] Image sliderImg;
    [SerializeField] Text scoreProcessText;
    [SerializeField] Text tryLockText;
    [SerializeField] Button call1Btn;
    protected override void InitComponent()
    {
        call1Btn.AddListener(SendHeroCall);
        ruleBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroCallScoreRuleWin>();
        });
    }
    protected override void OnPreOpen()
    {
        HappyXBModel.Instance.RefreshXBTypeInfoAct += Refresh;
        Refresh();
    }
    protected override void OnPreClose()
    {
        HappyXBModel.Instance.RefreshXBTypeInfoAct -= Refresh;
    }
    public override void Refresh()
    {
        scoreProcessText.text = UIHelper.GetMoneyCnt(51) + "/" + TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0];
        sliderImg.fillAmount = (float)UIHelper.GetMoneyCnt(51) / TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0];
        if (UIHelper.GetMoneyCnt(51) >= TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0])
        {
            scoreProcessText.color = UIHelper.GetUIColor(TextColType.LightWhite);
        }
        else
        {
            scoreProcessText.color = UIHelper.GetUIColor(TextColType.Red);
        }
        if (InvestModel.Instance.IsInvested(InvestModel.monthCardType))
        {
            tryLockText.SetActive(false);
            call1Btn.SetColorful(null, true);
        }
        else
        {
            tryLockText.SetActive(true);
            if (HappyXBModel.Instance.GetXBInfoByType((int)HappXBTitle.HeroCallScore).treasureCount == 0)
            {
                tryLockText.text = Language.Get("heroCall4", 1);
                call1Btn.SetColorful(null, true);
            }
            else
            {
                tryLockText.text = Language.Get("heroCall4", 0);
                call1Btn.SetColorful(null, false);
            }
        }
    }
    void SendHeroCall()
    {
        if (!InvestModel.Instance.IsInvested(InvestModel.monthCardType))
        {
            //未买月卡体验1次
            if (HappyXBModel.Instance.GetXBInfoByType((int)HappXBTitle.HeroCallScore).treasureCount != 0)
            {
                SysNotifyMgr.Instance.ShowTip("MonthCardNoActive");
                return;
            }
        }
        HeroUIManager.Instance.selectCallType = HappXBTitle.HeroCallScore;
        HeroUIManager.Instance.selectCallIndex = 0;
        HappyXBModel.Instance.SendOneXBQuest((int)HappXBTitle.HeroCallScore);
    }
}
Main/System/HappyXB/HeroCallScoreWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallScoreWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 4a39b88777149fb498604231bb29f255
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroCallWin.cs
New file
@@ -0,0 +1,138 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 招募
/// </summary>
public class HeroCallWin : UIBase
{
    [SerializeField] Button ruleBtn;
    [SerializeField] OwnItemCell ownItemCell;
    [SerializeField] Button scoreBtn;
    [SerializeField] Text scoreText;
    [SerializeField] GameObject scoreTween;
    [SerializeField] Toggle skipToggle;
    [SerializeField] Button call1Btn;
    [SerializeField] Image call1ItemIcon;
    [SerializeField] Text call1Text;
    [SerializeField] Text freeCDTime;
    [SerializeField] Button call10Btn;
    [SerializeField] Image call10ItemIcon;
    [SerializeField] Text call10Text;
    [SerializeField] Button closeBtn;
    protected override void InitComponent()
    {
        closeBtn.AddListener(CloseWindow);
        skipToggle.AddListener((value) =>
        {
            LocalSave.SetBool(HeroUIManager.skipKey, value);
        });
        ownItemCell.itemID = TreasureSetConfig.Get((int)HappXBTitle.HeroCallAdvanced).CostItemID;
        call1Btn.AddListener(SendHeroCall);
        call10Btn.AddListener(() =>
        {
            HeroUIManager.Instance.selectCallType = HappXBTitle.HeroCallAdvanced;
            HeroUIManager.Instance.selectCallIndex = 1;
            HappyXBModel.Instance.SendXBManyQuest((int)HappXBTitle.HeroCallAdvanced);
        });
        scoreBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroCallScoreWin>();
        });
        ruleBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroCallRuleWin>();
        });
    }
    protected override void OnPreOpen()
    {
        HappyXBModel.Instance.RefreshXBTypeInfoAct += Refresh;
        skipToggle.isOn = LocalSave.GetBool(HeroUIManager.skipKey, false);
        Refresh();
    }
    protected override void OnPreClose()
    {
        HappyXBModel.Instance.RefreshXBTypeInfoAct -= Refresh;
    }
    public override void Refresh()
    {
        var funcSet = TreasureSetConfig.Get((int)HappXBTitle.HeroCallAdvanced);
        var item = ItemConfig.Get(funcSet.CostItemID);
        var IconKey = item.IconKey;
        call1ItemIcon.SetOrgSprite(IconKey);
        call10ItemIcon.SetOrgSprite(IconKey);
        if (HappyXBModel.Instance.IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced))
        {
            call1Text.text = Language.Get("L1127");
        }
        else
        {
            call1Text.text = Language.Get("L1100", item.ItemName, funcSet.CostItemCountList[0]);
        }
        call10Text.text = Language.Get("L1100", item.ItemName, funcSet.CostItemCountList[1]);
        scoreText.text = UIHelper.GetMoneyCnt(51) + "/" + TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0];
        if (UIHelper.GetMoneyCnt(51) >= TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0])
        {
            scoreTween.SetActive(true);
        }
        else
        {
            scoreTween.SetActive(false);
        }
        RefreshFreeTime();
    }
    //每秒刷新免费CD的倒计时
    float cdTime = 0;
    void LateUpdate()
    {
        //每秒触发一次
        cdTime += Time.deltaTime;
        if (cdTime < 1) return;
        cdTime = 0;
        RefreshFreeTime();
    }
    void RefreshFreeTime()
    {
        if (!HappyXBModel.Instance.IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced))
        {
            freeCDTime.SetActive(false);
        }
        else
        {
            freeCDTime.SetActive(true);
            freeCDTime.text = Language.Get("L1128", TimeUtility.SecondsToHMS(TimeUtility.GetTodayRemainSeconds()));
        }
    }
    void SendHeroCall()
    {
        HeroUIManager.Instance.selectCallType = HappXBTitle.HeroCallAdvanced;
        HeroUIManager.Instance.selectCallIndex = 0;
        if (HappyXBModel.Instance.IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced))
        {
            HappyXBModel.Instance.SendXBQuest((int)HappXBTitle.HeroCallAdvanced, 0, 1);
        }
        else
        {
            HappyXBModel.Instance.SendOneXBQuest((int)HappXBTitle.HeroCallAdvanced);
        }
    }
}
Main/System/HappyXB/HeroCallWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroCallWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 2650df34f133d66499572823d050491e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroSmallHeadCell.cs
New file
@@ -0,0 +1,21 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HeroSmallHeadCell : MonoBehaviour
{
    [SerializeField] HeroHeadBaseCell heroHeadBaseCell;
    [SerializeField] Image jobImg;
    [SerializeField] Text nameText;
    public void Display(int heroID)
    {
        var hero = HeroConfig.Get(heroID);
        heroHeadBaseCell.Init(hero.HeroID, hero.SkinIDList[0]);
        nameText.text = hero.Name;
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.Class));
    }
}
Main/System/HappyXB/HeroSmallHeadCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroSmallHeadCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 15fea9a71f009e844acaccbf4f37c8c1
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HappyXB/HeroSmallHeadLineCell.cs
New file
@@ -0,0 +1,23 @@
using UnityEngine;
public class HeroSmallHeadLineCell : CellView
{
    [SerializeField] HeroSmallHeadCell[] cardList;
    public void Display(int index)
    {
        for (int i = 0; i < cardList.Length; i++)
        {
            if (i + index < HeroUIManager.Instance.heroCallSortList.Count)
            {
                cardList[i].SetActive(true);
                cardList[i].Display(HeroUIManager.Instance.heroCallSortList[index + i]);
            }
            else
            {
                cardList[i].SetActive(false);
            }
        }
    }
}
Main/System/HappyXB/HeroSmallHeadLineCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HappyXB/HeroSmallHeadLineCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 67434124635c2b447a4aae1fc5f1f21c
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Hero/HeroConfigUtility.cs
File was deleted
Main/System/Hero/HeroInfo.Awake.cs
@@ -36,6 +36,8 @@
            for(int j = 0; j < tmpAwakeConfig.AttrIDList.Length; j++)
            {
                int id = tmpAwakeConfig.AttrIDList[j];
                if (id == 0)
                    continue;
                if (!breakAttrs.ContainsKey(id))
                {
                    breakAttrs.Add(id, tmpAwakeConfig.AttrValueList[j]);
@@ -49,10 +51,15 @@
            if (tmpAwakeConfig.SkillID != 0)
            {
                var skillConfig = SkillConfig.Get(tmpAwakeConfig.SkillID);
                if (skillConfig == null)
                {
                    Debug.LogError("觉醒技能配置错误" + tmpAwakeConfig.SkillID);
                    continue;
                }
                if (allSkillTypeIDToID.ContainsKey(skillConfig.SkillTypeID))
                {
                    var tmpSkillConfig = SkillConfig.Get(allSkillTypeIDToID[skillConfig.SkillTypeID]);
                    if (skillConfig.SkillID > tmpSkillConfig.SkillID)
                    if (skillConfig.SkillLV > tmpSkillConfig.SkillLV)
                    {
                        //取最大技能
                        allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpAwakeConfig.SkillID;
Main/System/Hero/HeroInfo.Break.cs
@@ -35,6 +35,8 @@
            for(int j = 0; j < tmpBreakConfig.AttrIDList.Length; j++)
            {
                int id = tmpBreakConfig.AttrIDList[j];
                if (id == 0)
                    continue;
                if (!breakAttrs.ContainsKey(id))
                {
                    breakAttrs.Add(id, tmpBreakConfig.AttrValueList[j]);
@@ -52,7 +54,7 @@
                if (allSkillTypeIDToID.ContainsKey(skillConfig.SkillTypeID))
                {
                    var tmpSkillConfig = SkillConfig.Get(allSkillTypeIDToID[skillConfig.SkillTypeID]);
                    if (skillConfig.SkillID > tmpSkillConfig.SkillID)
                    if (skillConfig.SkillLV > tmpSkillConfig.SkillLV)
                    {
                        //取最大技能
                        allSkillTypeIDToID[skillConfig.SkillTypeID] = tmpBreakConfig.SkillID;
Main/System/Hero/HeroInfo.Fetter.cs
@@ -41,16 +41,16 @@
    }
    public int GetFetterAttrPer(int attrType)
    {
        if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
        {
            var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
            return fetterAttrs.ContainsKey(pertype) ? fetterAttrs[pertype] : 0;
        }
        return 0;
    {
        if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
        {
            var pertype = PlayerPropertyConfig.baseAttr2perDict[attrType];
            return fetterAttrs.ContainsKey(pertype) ? fetterAttrs[pertype] : 0;
        }
        return 0;
    }
    public List<int> GetActiveFetter(HeroConfig config, TeamBase teamBase)
    {
        List<int> list = new List<int>();
@@ -82,4 +82,6 @@
        return list;
    }
}
Main/System/Hero/HeroInfo.cs
@@ -115,6 +115,49 @@
        return TeamManager.Instance.GetTeam(teamType).HasHeroInServer(itemHero.guid);
    }
    //是否上任何阵容
    public bool IsInAnyTeam()
    {
        for (int i = 1; i < (int)TeamType.Max; i++)
        {
            if (TeamManager.Instance.GetTeam((TeamType)i).HasHeroInServer(itemHero.guid))
            {
                return true;
            }
        }
        return false;
    }
    //是否上任何阵容,且只有一只
    public bool IsInAnyTeamJustOne()
    {
        for (int i = 1; i < (int)TeamType.Max; i++)
        {
            var team = TeamManager.Instance.GetTeam((TeamType)i);
            if (team.HasHeroInServer(itemHero.guid))
            {
                if (team.GetTeamHeroCount() == 1)
                    return true;
            }
        }
        return false;
    }
    //下阵所有阵容
    public void LeaveAllTeam()
    {
        for (int i = 1; i < (int)TeamType.Max; i++)
        {
            int pos;
            var team = TeamManager.Instance.GetTeam((TeamType)i);
            if (TeamManager.Instance.GetTeam((TeamType)i).RemoveHero(this, out pos))
            {
                //如果是最后一个武将,则默认上阵一个
                team.SaveTeam();
            }
        }
    }
    public long GetSkillsFightPower()
    {
        long fightPower = 0;
@@ -124,5 +167,14 @@
        }
        return fightPower;
    }
    public void ChangeLockState()
    {
        var pack = new CB238_tagCSHeroLock();
        pack.ItemIndex = (ushort)itemHero.gridIndex;
        pack.IsLock = isLock ? (byte)0 : (byte)1;
        GameNetSystem.Instance.SendInfo(pack);
    }
}
Main/System/Hero/HeroManager.cs
@@ -155,4 +155,9 @@
    {
        return PackManager.Instance.GetSinglePack(PackType.Hero).HasItem(heroID);
    }
    public int GetHeroCountByID(int heroID)
    {
        return (int)PackManager.Instance.GetSinglePack(PackType.Hero).GetCountById(heroID);
    }
}
Main/System/Hero/UIHeroController.cs
@@ -13,7 +13,7 @@
    private GameObject instanceGO;
    private Action onComplete;
    public void Create(int _skinID, float scale = 1f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
    public void Create(int _skinID, float scale = 0.8f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
    {
        if (skinID == _skinID)
        { 
@@ -51,6 +51,17 @@
        { 
            skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
        }
        if (skeletonGraphic.skeletonDataAsset == null)
        {
            transform.SetActive(false);
            if (pool != null)
                pool.Release(instanceGO);
            skeletonGraphic = null;
            Destroy(instanceGO);
            Debug.LogError("未配置spine");
            return;
        }
        skeletonGraphic.Initialize(true);
        this.transform.localScale = Vector3.one * scale;
        spineAnimationState = skeletonGraphic.AnimationState;
Main/System/HeroUI/HeroAllAttrWin.cs
@@ -107,7 +107,7 @@
        var hero = HeroManager.Instance.GetHero(item.guid);
        if (hero == null)
            return;
        var dict = FightPowerManager.Instance.GetHeroTotalAttr(hero);
        foreach (var kv in attrBtns)
        {
            //每个按钮下有两个Text:name 和 value
@@ -117,7 +117,8 @@
            Text valueText = button.transform.Find("value").GetComponent<Text>();
            nameText.text = PlayerPropertyConfig.Get(id).ShowName;
            valueText.text = PlayerPropertyConfig.GetValueDescription(id, 123);
            var value = dict.TryGetValue(id, out long v) ? v : 0;
            valueText.text = PlayerPropertyConfig.GetValueDescription(id, value);
        }
    }
Main/System/HeroUI/HeroBaseWin.cs
@@ -8,11 +8,19 @@
/// </summary>
public class HeroBaseWin : FunctionsBaseWin
{
    [SerializeField] Button callBtn;
    /// </summary>
    protected override void InitComponent()
    {
        base.InitComponent();
        //招募为另外一个界面,避免关闭时显示空白
        callBtn.AddListener(()=>
        {
            //打开招募界面
            UIManager.Instance.OpenWindow<HeroCallWin>();
        });
    }
@@ -48,6 +56,8 @@
            case 1:
                //currentSubUI = UIManager.Instance.OpenWindow<HeroCollectionsWin>();
                break;
            case 2:
                break;
            default:
                Debug.LogWarning("未知的标签索引: " + functionOrder);
                break;
Main/System/HeroUI/HeroDeleteHeadCell.cs
New file
@@ -0,0 +1,94 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HeroDeleteHeadCell : MonoBehaviour
{
    [SerializeField] HeroHeadBaseCell heroHeadBaseCell;
    [SerializeField] Image jobImg;
    [SerializeField] Text nameText;
    [SerializeField] GameObject selectRect;
    [SerializeField] GameObject maskObj;
    [SerializeField] GameObject onTeamObj;
    [SerializeField] GameObject lockObj;
    [SerializeField] GameObject awakeObj;
    [SerializeField] Text awakeLVText;
    public void Display(int index)
    {
        var guid = HeroUIManager.Instance.heroDeleteSortList[index];
        var hero = HeroManager.Instance.GetHero(guid);
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        selectRect.SetActive(HeroUIManager.Instance.selectDeleteHeroList.Contains(guid));
        maskObj.SetActive(hero.isLock || hero.IsInAnyTeam()
            || HeroUIManager.Instance.selectDeleteHeroList.Contains(guid) || hero.awakeLevel > 0);
        lockObj.SetActive(hero.isLock);
        onTeamObj.SetActive(hero.IsInAnyTeam());
        awakeObj.SetActive(hero.awakeLevel > 0);
        awakeLVText.text = hero.awakeLevel.ToString();
        heroHeadBaseCell.Init(hero.heroId, hero.SkinID, hero.heroStar, hero.awakeLevel, hero.heroLevel, () =>
        {
            Click(hero, index);
        });
        nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel);
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class));
    }
    void Click(HeroInfo hero, int index)
    {
        //上阵 锁定 觉醒 的情况
        if (hero.awakeLevel > 0)
        {
            SysNotifyMgr.Instance.ShowTip("HeroReborn1");
            return;
        }
        if (hero.IsInAnyTeamJustOne())
        {
            //阵容至少要有一个武将上阵
            SysNotifyMgr.Instance.ShowTip("HeroFunc3");
            return;
        }
        if (hero.isLock)
        {
            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"),
            Language.Get("herocard66"), (bool isOK) =>
                {
                    if (isOK)
                    {
                        hero.ChangeLockState();
                    }
                });
            return;
        }
        if (hero.IsInAnyTeam())
        {
            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"),
            Language.Get("herocard65"), (bool isOK) =>
                {
                    if (isOK)
                    {
                        hero.LeaveAllTeam();
                    }
                });
            return;
        }
        if (HeroUIManager.Instance.selectDeleteHeroList.Contains(hero.itemHero.guid))
        {
            HeroUIManager.Instance.selectDeleteHeroList.Remove(hero.itemHero.guid);
        }
        else
        {
            HeroUIManager.Instance.selectDeleteHeroList.Add(hero.itemHero.guid);
        }
        Display(index);
    }
}
Main/System/HeroUI/HeroDeleteHeadCell.cs.meta
File was renamed from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: c612a8c9405b7504197e93a1c71d9fc7
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HeroUI/HeroDeleteLineCell.cs
New file
@@ -0,0 +1,23 @@
using UnityEngine;
public class HeroDeleteLineCell : CellView
{
    [SerializeField] HeroDeleteHeadCell[] cardList;
    public void Display(int index)
    {
        for (int i = 0; i < cardList.Length; i++)
        {
            if (i + index < HeroUIManager.Instance.heroDeleteSortList.Count)
            {
                cardList[i].SetActive(true);
                cardList[i].Display(index + i);
            }
            else
            {
                cardList[i].SetActive(false);
            }
        }
    }
}
Main/System/HeroUI/HeroDeleteLineCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HeroUI/HeroDeleteLineCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: bbe0726ecc72b50449e34339b7d9af94
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HeroUI/HeroDeleteWin.cs
New file
@@ -0,0 +1,232 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 武将培养界面
/// </summary>
public class HeroDeleteWin : UIBase
{
    [SerializeField] Button storeBtn;
    [SerializeField] ScrollerController scroller;
    [SerializeField] HeroSelectBehaviour heroSelectBehaviour;
    [SerializeField] GameObject noHeroObj;
    [SerializeField] Button quickSelectBtn;
    [SerializeField] Button deleteBtn;
    protected override void InitComponent()
    {
        storeBtn.AddListener(() =>
        {
            // UIManager.Instance.OpenWindow<StoreWin>();
        });
        quickSelectBtn.AddListener(QuickSelect);
        deleteBtn.AddListener(DeleteHero);
    }
    protected override void OnPreOpen()
    {
        scroller.OnRefreshCell += OnRefreshCell;
        TeamManager.Instance.OnTeamChange += OnTeamChange;
        PackManager.Instance.RefreshItemLockEvent += RefreshItemLockEvent;
        ItemLogicUtility.Instance.OnGetItemShowEvent += OnGetItemShowEvent;
        HeroUIManager.Instance.selectHeroDeleteListJob = 0;
        HeroUIManager.Instance.selectHeroDeleteListCountry = 0;
        HeroUIManager.Instance.SortHeroDeleteList();
        heroSelectBehaviour.Display(0, HeroUIManager.Instance.selectHeroDeleteListJob, HeroUIManager.Instance.selectHeroDeleteListCountry, SelectJobCountry);
        RefreshEmptyTip();
        CreateScroller();
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        TeamManager.Instance.OnTeamChange -= OnTeamChange;
        PackManager.Instance.RefreshItemLockEvent -= RefreshItemLockEvent;
        ItemLogicUtility.Instance.OnGetItemShowEvent -= OnGetItemShowEvent;
        HeroUIManager.Instance.selectDeleteHeroList.Clear();
    }
    void CreateScroller()
    {
        scroller.Refresh();
        for (int i = 0; i < HeroUIManager.Instance.heroDeleteSortList.Count; i++)
        {
            if (i % 5 == 0)
            {
                scroller.AddCell(ScrollerDataType.Header, i);
            }
        }
        scroller.Restart();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as HeroDeleteLineCell;
        _cell.Display(cell.index);
    }
    void SelectJobCountry(int job, int country)
    {
        HeroUIManager.Instance.selectHeroDeleteListJob = job;
        HeroUIManager.Instance.selectHeroDeleteListCountry = country;
        HeroUIManager.Instance.SortHeroDeleteList();
        CreateScroller();
        RefreshEmptyTip();
    }
    void RefreshEmptyTip()
    {
        if (HeroUIManager.Instance.heroDeleteSortList.Count <= 0)
        {
            noHeroObj.SetActive(true);
            scroller.SetActive(false);
        }
        else
        {
            noHeroObj.SetActive(false);
            scroller.SetActive(true);
        }
    }
    void OnTeamChange(TeamType type)
    {
        scroller.m_Scorller.RefreshActiveCellViews();
    }
    void RefreshItemLockEvent(PackType type, string guid, bool lockState)
    {
        scroller.m_Scorller.RefreshActiveCellViews();
    }
    void QuickSelect()
    {
        //只选精英
        for (int i = 0; i < HeroUIManager.Instance.heroDeleteSortList.Count; i++)
        {
            HeroInfo hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.heroDeleteSortList[i]);
            if (hero == null)
                continue;
            if (hero.Quality > 2)
                continue;
            if (hero.awakeLevel > 0)
                    continue;
            if (hero.isLock)
                continue;
            if (hero.IsInAnyTeam())
                continue;
            if (HeroUIManager.Instance.selectDeleteHeroList.Contains(hero.itemHero.guid))
                continue;
            HeroUIManager.Instance.selectDeleteHeroList.Add(hero.itemHero.guid);
        }
        if (HeroUIManager.Instance.selectDeleteHeroList.Count == 0)
        {
            SysNotifyMgr.Instance.ShowTip("HeroReborn2");
            return;
        }
        scroller.m_Scorller.RefreshActiveCellViews();
    }
    void DeleteHero()
    {
        if (HeroUIManager.Instance.selectDeleteHeroList.Count == 0)
        {
            SysNotifyMgr.Instance.ShowTip("HeroReborn3");
            return;
        }
        bool hasStarHero = false;
        for (int i = 0; i < HeroUIManager.Instance.selectDeleteHeroList.Count; i++)
        {
            HeroInfo hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectDeleteHeroList[i]);
            if (hero == null)
                continue;
            if (hero.heroStar > 1)
            {
                hasStarHero = true;
                break;
            }
        }
        if (hasStarHero)
        {
            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("herocard67"), (bool isOK) =>
                {
                    if (isOK)
                    {
                        ShowDeleteItems();
                    }
                });
            return;
        }
        ShowDeleteItems();
    }
    void ShowDeleteItems()
    {
        Dictionary<int, long> allItemDict = new Dictionary<int, long>();
        for (int i = 0; i < HeroUIManager.Instance.selectDeleteHeroList.Count; i++)
        {
            HeroInfo hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectDeleteHeroList[i]);
            if (hero == null)
                continue;
            allItemDict = CommonFunc.AddDict(allItemDict, CommonFunc.AddDict(HeroUIManager.Instance.GetHeroLVPayBack(hero.Quality, hero.heroLevel),
            HeroUIManager.Instance.GetHeroBreakPayBack(hero.Quality, hero.breakLevel)));
            Dictionary<int, long> tmpDict = new Dictionary<int, long>();
            foreach (var itemInfo in hero.qualityConfig.DismissReturnItems)
            {
                if (!tmpDict.ContainsKey(itemInfo[0]))
                {
                    tmpDict.Add(itemInfo[0], itemInfo[1] * (1 + hero.heroStar));
                }
                else
                {
                    tmpDict[itemInfo[0]] += itemInfo[1] * (1 + hero.heroStar);
                }
            }
            allItemDict = CommonFunc.AddDict(allItemDict, tmpDict);
        }
        List<Item> items = CommonFunc.ChangeToItemList(allItemDict);
        ConfirmCancel.ShowItemsConfirm(items, Language.Get("herocard25"), Language.Get("herocard26"), (bool isOk) =>
        {
            if (isOk)
            {
                //发包
                var pack = new CB240_tagCSHeroDismiss();
                List<ushort> indexList = new List<ushort>();
                for (int i = 0; i < HeroUIManager.Instance.selectDeleteHeroList.Count; i++)
                {
                    indexList.Add((ushort)HeroManager.Instance.GetHero(HeroUIManager.Instance.selectDeleteHeroList[i]).itemHero.gridIndex);
                }
                pack.ItemIndexList = indexList.ToArray();
                pack.Count = (ushort)pack.ItemIndexList.Length;
                GameNetSystem.Instance.SendInfo(pack);
                HeroUIManager.Instance.selectDeleteHeroList.Clear();
            }
        });
    }
    void OnGetItemShowEvent()
    {
        HeroUIManager.Instance.SortHeroDeleteList();
        CreateScroller();
    }
}
Main/System/HeroUI/HeroDeleteWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/HeroUI/HeroDeleteWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: d70030f1a7e3bc74fb1ed762daa7a2d3
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HeroUI/HeroLVBreakSuccessWin.cs
@@ -74,7 +74,10 @@
        List<string> attrStrArr = new List<string>();
        for (int i = 0; i < nextQualityBreakConfig.AttrIDList.Length; i++)
        {
            attrStrArr.Add(PlayerPropertyConfig.GetFullDescription(nextQualityBreakConfig.AttrIDList[i], nextQualityBreakConfig.AttrValueList[i]));
            var id = nextQualityBreakConfig.AttrIDList[i];
            if (id == 0)
                continue;
            attrStrArr.Add(PlayerPropertyConfig.GetFullDescription(id, nextQualityBreakConfig.AttrValueList[i]));
        }
        if (nextQualityBreakConfig.SkillID != 0)
        {
Main/System/HeroUI/HeroLVBreakWin.cs
@@ -65,7 +65,7 @@
        }
        moneyIcon.SetOrgSprite(ItemConfig.Get(nextBreakLVConfig.UPCostItem[0]).IconKey);
        moneyText.text = UIHelper.ShowUseItem(PackType.Item, nextBreakLVConfig.UPCostItem[0], (ulong)nextBreakLVConfig.UPCostItem[1]);
        moneyText.text = UIHelper.ShowUseItem(PackType.Item, nextBreakLVConfig.UPCostItem[0], nextBreakLVConfig.UPCostItem[1]);
        var nextQualityBreakConfig = HeroBreakConfig.GetHeroBreakConfig(hero.heroId, hero.breakLevel + 1);
        if (nextQualityBreakConfig == null)
@@ -76,22 +76,35 @@
        List<string> attrStrArr = new List<string>();
        for (int i = 0; i < nextQualityBreakConfig.AttrIDList.Length; i++)
        {
            if (nextQualityBreakConfig.AttrIDList[i] == 0)
            {
                continue;
            }
            attrStrArr.Add(PlayerPropertyConfig.GetFullDescription(nextQualityBreakConfig.AttrIDList[i], nextQualityBreakConfig.AttrValueList[i]));
        }
        if (nextQualityBreakConfig.SkillID != 0)
        {
            attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID)?.Description);
            var skill = SkillConfig.Get(nextQualityBreakConfig.SkillID);
            if (skill != null)
            {
                attrStrArr.Add(skill.Description);
            }
            else
            {
                Debug.LogError("未配置技能" + nextQualityBreakConfig.SkillID);
            }
        }
        potentialText.text = Language.Get("L1100", Language.Get("herocard56"), string.Join(Language.Get("L1112"), attrStrArr));
    }
    void BreakLV()
    {
        if (ItemLogicUtility.CheckItemCount(PackType.Item, hero.qualityBreakConfig.UPCostItem[0], (ulong)hero.qualityBreakConfig.UPCostItem[1], 2))
        if (ItemLogicUtility.CheckItemCount(PackType.Item, hero.qualityBreakConfig.UPCostItem[0], hero.qualityBreakConfig.UPCostItem[1], 2))
        {
            var pack = new CB232_tagCSHeroBreak();
            pack.ItemIndex = (ushort)hero.itemHero.gridIndex;
            GameNetSystem.Instance.SendInfo(pack);
            HeroUIManager.Instance.lastFightPower = new KeyValuePair<string, long>(hero.itemHero.guid, hero.CalculatePower(false));
            CloseWindow();
            //设置个等待回复的标识 显示成功界面
            HeroUIManager.Instance.waitResponse = new WaitHeroFuncResponse()
Main/System/HeroUI/HeroListWin.cs
@@ -48,6 +48,7 @@
        heroListScroller.OnRefreshCell += OnRefreshCell;
        PackManager.Instance.gridRefreshEvent += GridRefreshEvent;
        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        HeroUIManager.Instance.SortHeroList();
        CreateScroller();
        Refresh();
@@ -58,6 +59,21 @@
        heroListScroller.OnRefreshCell -= OnRefreshCell;
        PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
        PackManager.Instance.gridRefreshEvent -= GridRefreshEvent;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
    }
    private void OnCloseWindow(UIBase closeUI)
    {
        //其他武将功能产生数据变化,需要刷新武将列表
        if (closeUI is HeroTrainWin ||
            closeUI is HeroCallWin ||
            closeUI is HeroPosWin)
        {
            HeroUIManager.Instance.SortHeroList();
            CreateScroller();
            Refresh();
        }
    }
Main/System/HeroUI/HeroPosWin.cs
@@ -232,7 +232,8 @@
        //上阵属性
        for (int i = 0; i < attrOnList.Length; i++)
        {
            attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
            string format = valuePer == 0 ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}", false);
            attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i], valuePer, format);
        }
    }
@@ -345,7 +346,7 @@
            else
            {
                sceneHero[i].SetActive(true);
                sceneHero[i].Display(teamHero.guid, i, flyFrom >= 0);
                sceneHero[i].Display(teamHero.guid, i, flyFrom >= 0, true);
                //按scenePosImgs 顺序排序对应位置
                sceneHero[i].transform.position = scenePosImgs[i].transform.position;
                sceneHero[i].transform.localScale = Vector3.one;
Main/System/HeroUI/HeroScenePosCell.cs
@@ -21,7 +21,7 @@
    [SerializeField] Transform objForfly;  //点击飞入的时候的显隐控制
    public void Display(string guid, int index, bool isFly = false)
    public void Display(string guid, int index, bool isFly = false, bool showSuggest = false)
    {
        var hero = HeroManager.Instance.GetHero(guid);
        this.transform.localScale = Vector3.one;
@@ -29,14 +29,15 @@
        lvText.text = Language.Get("L1099", hero.heroLevel);
        var heroConfig = hero.heroConfig;
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex]);
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale);
        nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, hero.breakLevel);
        posCircleImg.SetSprite("heroposcircle" + heroConfig.Quality);
        //不是推荐位则提示
        if (heroConfig.Position == 1 && TeamConst.TeamPos2Array.Contains(index) ||
            heroConfig.Position == 2 && TeamConst.TeamPos1Array.Contains(index))
        //  if (heroConfig.Position == 1 && TeamConst.TeamPos2Array.Contains(index) ||
        //     heroConfig.Position == 2 && TeamConst.TeamPos1Array.Contains(index))
        if (showSuggest)
        {
            suggestForm.SetActive(true);
            jobTip.text = HeroUIManager.Instance.GetJobName(heroConfig.Class);
Main/System/HeroUI/HeroSelectBehaviour.cs
@@ -62,6 +62,13 @@
    }
    /// <summary>
    /// 国家职业筛选
    /// </summary>
    /// <param name="state"> 0收起,1展开</param>
    /// <param name="job"></param>
    /// <param name="country"></param>
    /// <param name="onRefresh"> 点击按钮需通知响应外部事件</param>
    public void Display(int state, int job, int country, Action<int, int> onRefresh)
    {
        foldState = state;
Main/System/HeroUI/HeroTrainWin.cs
@@ -39,6 +39,7 @@
    [SerializeField] Image countryImg;
    [SerializeField] Text awakeLVText;
    //属性区
    [SerializeField] Button attrBtn;
    [SerializeField] Image unfoldImg; //展开时按钮的图标
    [SerializeField] Image foldImg; //收起时按钮的图标
@@ -59,8 +60,15 @@
    [SerializeField] LongPressButton lvupBtn;
    [SerializeField] Button allAttrBtn;
    [SerializeField] Text allPotentialText; //潜能
    [SerializeField] Text[] fetterText;   //羁绊
    [SerializeField] Text[] fetterNameText;   //羁绊
    string guid;
    HeroInfo hero;
    protected override void InitComponent()
    {
        showFuncBtn.AddListener(() =>
@@ -81,7 +89,7 @@
            ChangeHero(-1);
        });
        lockBtn.AddListener(SetLockState);
        lockBtn.AddListener(() => { hero.ChangeLockState(); });
        resetBtn.AddListener(ResetBtnClick);
        deleteBtn.AddListener(DeleteHero);
        awakeBtn.AddListener(() =>
@@ -119,6 +127,7 @@
    {
        PackManager.Instance.RefreshItemLockEvent += RefreshItemLockEvent;
        HeroManager.Instance.onHeroChangeEvent += RefreshHeroEvent;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        guid = HeroUIManager.Instance.selectHeroGuid;
        hero = HeroManager.Instance.GetHero(guid);
        unfoldState = false;
@@ -130,17 +139,30 @@
    {
        PackManager.Instance.RefreshItemLockEvent -= RefreshItemLockEvent;
        HeroManager.Instance.onHeroChangeEvent -= RefreshHeroEvent;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
    }
    private void OnCloseWindow(UIBase closeUI)
    {
        //其他界面删除武将会影响逻辑
        if (closeUI is HeroDeleteWin)
        {
            HeroUIManager.Instance.SortHeroList();
            if (HeroManager.Instance.GetHero(guid) == null)
            {
                CloseWindow();
            }
        }
    }
    public override void Refresh()
    {
        roleLhModel.Create(hero.SkinID, 0.6f, motionName: "", isLh: true);
        roleLhModel.Create(hero.SkinID, HeroUIManager.lihuiScale, motionName: "", isLh: true);
        roleXsModel.Create(hero.SkinID);
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class));
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(hero.heroConfig.Class);
        descText.text = hero.heroConfig.Desc;
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(hero.CalculatePower());
        PlayerMainDate.Instance.AddPowerNotOnTeam(hero);
        lockImg.SetActive(hero.isLock);
        unLockImg.SetActive(!hero.isLock);
        nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel);
@@ -161,6 +183,7 @@
        RefreshFoldState();
        RefreshAttr();
        RefreshAllPotential();
        RefreshFetter();
    }
    void RefreshItemLockEvent(PackType type, string guid, bool lockState)
@@ -210,14 +233,6 @@
        Refresh();
    }
    void SetLockState()
    {
        var pack = new CB238_tagCSHeroLock();
        pack.ItemIndex = (ushort)hero.itemHero.gridIndex;
        pack.IsLock = hero.isLock ? (byte)0 : (byte)1;
        GameNetSystem.Instance.SendInfo(pack);
    }
    void ResetBtnClick()
    {
        //升级、突破、觉醒
@@ -231,7 +246,7 @@
        var payBack1 = CommonFunc.AddDict(HeroUIManager.Instance.GetHeroLVPayBack(hero.Quality, hero.heroLevel),
        HeroUIManager.Instance.GetHeroBreakPayBack(hero.heroId, hero.breakLevel));
        HeroUIManager.Instance.GetHeroBreakPayBack(hero.Quality, hero.breakLevel));
        //已觉醒的需要消耗货币
        if (hero.awakeLevel == 0)
@@ -248,17 +263,30 @@
        }
        else
        {
            payBack1 = CommonFunc.AddDict(payBack1, HeroUIManager.Instance.GetHeroQualityAwakePayBack(hero.heroId, hero.awakeLevel));
            if (HeroUIManager.Instance.awakeRebirthCnt >= HeroUIManager.Instance.rebornAwakeHeroMaxCount)
            {
                SysNotifyMgr.Instance.ShowTip("HeroRebornAwakeMax");
                return;
            }
            payBack1 = CommonFunc.AddDict(payBack1, HeroUIManager.Instance.GetHeroQualityAwakePayBack(hero.Quality, hero.awakeLevel));
            items = CommonFunc.ChangeToItemList(payBack1);
            var info2 = Language.Get("herocard44", HeroUIManager.Instance.awakeRebirthCnt);
            var payBackMoney = HeroQualityAwakeConfig.GetQualityAwakeConfig(hero.Quality, hero.awakeLevel).RebirthCostMoney;
            ConfirmCancel.ShowItemsConfirm(items, Language.Get("herocard42"), Language.Get("herocard43"), (bool isOk) =>
            {
                if (isOk)
                {
                    if (UIHelper.GetMoneyCnt(HeroUIManager.Instance.payBackMoneyType) < payBackMoney)
                    {
                        ItemTipUtility.ShowMoneyTip(HeroUIManager.Instance.payBackMoneyType);
                        return;
                    }
                    //发包
                    SendReborn(hero.itemHero.gridIndex);
                }
            }, info2, "", HeroUIManager.Instance.payBackMoney, HeroUIManager.Instance.payBackMoneyType);
            }, info2, "", payBackMoney, HeroUIManager.Instance.payBackMoneyType);
        }
@@ -269,15 +297,20 @@
        var pack = new CB239_tagCSHeroRebirth();
        pack.ItemIndex = (ushort)index;
        GameNetSystem.Instance.SendInfo(pack);
        HeroUIManager.Instance.lastFightPower = new KeyValuePair<string, long>(hero.itemHero.guid, hero.CalculatePower(false));
    }
    void DeleteHero()
    {
        if (hero.isLock)
        {
            SysNotifyMgr.Instance.ShowTip("UnlockHero");
            return;
        }
        // if (hero.isLock)
        // {
        //     SysNotifyMgr.Instance.ShowTip("UnlockHero");
        //     return;
        // }
        UIManager.Instance.OpenWindow<HeroDeleteWin>();
    }
    void RefreshStars()
@@ -376,14 +409,14 @@
                lvupBtnText.text = Language.Get("L1111");
                var breakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(hero.Quality, hero.breakLevel);
                lvupMoneyIcon.SetOrgSprite(ItemConfig.Get(breakConfig.UPCostItem[0]).IconKey);
                lvupMoneyText.text = UIHelper.ShowUseItem(PackType.Item, breakConfig.UPCostItem[0], (ulong)breakConfig.UPCostItem[1]);
                lvupMoneyText.text = UIHelper.ShowUseItem(PackType.Item, breakConfig.UPCostItem[0], breakConfig.UPCostItem[1], TextColType.NavyBrown);
            }
            else
            {
                lvupBtnText.text = Language.Get("L1109");
                var lvupConfig = HeroQualityLVConfig.GetQualityLVConfig(hero.Quality, hero.heroLevel);
                lvupMoneyIcon.SetOrgSprite(ItemConfig.Get(lvupConfig.UPCostItem[0]).IconKey);
                lvupMoneyText.text = UIHelper.ShowUseItem(PackType.Item, lvupConfig.UPCostItem[0], (ulong)lvupConfig.UPCostItem[1]);
                lvupMoneyText.text = UIHelper.ShowUseItem(PackType.Item, lvupConfig.UPCostItem[0], lvupConfig.UPCostItem[1], TextColType.NavyBrown);
            }
        }
@@ -400,7 +433,7 @@
    void LVUp()
    {
        int itemID = 0;
        ulong needCount = 0;
        long needCount = 0;
        if (HeroUIManager.Instance.IsLVMaxByBreakLevel(hero))
        {
            //突破
@@ -415,7 +448,7 @@
            //升级
            var lvupConfig = HeroQualityLVConfig.GetQualityLVConfig(hero.Quality, hero.heroLevel);
            itemID = lvupConfig.UPCostItem[0];
            needCount = (ulong)lvupConfig.UPCostItem[1];
            needCount = lvupConfig.UPCostItem[1];
            if (ItemLogicUtility.CheckItemCount(PackType.Item, itemID, needCount, 2))
            {
                var pack = new CB230_tagCSHeroLVUP();
@@ -432,6 +465,7 @@
                {
                    addPerObject.SetActive(false);
                });
                HeroUIManager.Instance.lastFightPower = new KeyValuePair<string, long>(hero.itemHero.guid, hero.CalculatePower(false));
            }
        }
@@ -456,13 +490,26 @@
            List<string> attrStrArr = new List<string>();
            for (int j = 0; j < nextQualityBreakConfig.AttrIDList.Length; j++)
            {
                if (nextQualityBreakConfig.AttrIDList[j] == 0)
                    continue;
                string format = i < hero.breakLevel ? "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}") : "{0}+{1}";
                attrStrArr.Add(PlayerPropertyConfig.GetFullDescription(nextQualityBreakConfig.AttrIDList[j], nextQualityBreakConfig.AttrValueList[j], format));
            }
            if (nextQualityBreakConfig.SkillID != 0)
            {
                attrStrArr.Add(SkillConfig.Get(nextQualityBreakConfig.SkillID)?.Description);
                var skill = SkillConfig.Get(nextQualityBreakConfig.SkillID);
                if (skill != null)
                {
                    attrStrArr.Add(skill.Description);
                }
                else
                {
                    Debug.LogError("未配置技能" + nextQualityBreakConfig.SkillID);
                }
            }
            if (i < hero.breakLevel)
            {
                allAttrStr += Language.Get("herocard63", i + 1, string.Join(Language.Get("L1112"), attrStrArr)) + "\n";
@@ -475,6 +522,48 @@
        }
        allPotentialText.text = allAttrStr.Trim();
    }
    //羁绊
    void RefreshFetter()
    {
        for (int i = 0; i < fetterText.Length; i++)
        {
            if (i < hero.heroConfig.FetterIDList.Length)
            {
                fetterText[i].SetActive(true);
                var fetterID = hero.heroConfig.FetterIDList[i];
                HeroFetterConfig fetterConfig = HeroFetterConfig.Get(fetterID);
                List<string> heroNames = new List<string>();
                bool isAllCollect = true; //是否全收集
                foreach (var tmpHeroID in fetterConfig.HeroIDList)
                {
                    heroNames.Add(HeroConfig.Get(tmpHeroID).Name);
                    if (HeroManager.Instance.GetHeroCountByID(tmpHeroID) == 0)
                    {
                        isAllCollect = false;
                    }
                }
                var attrStr = string.Join(Language.Get("SplitString1"), heroNames) + Language.Get("herocard38");
                for (int j = 0; j < fetterConfig.AttrIDList.Length; j++)
                {
                    string format = !isAllCollect ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}");
                    attrStr += Language.Get("L1112") + PlayerPropertyConfig.GetFullDescription(fetterConfig.AttrIDList[j], fetterConfig.AttrValueList[j], format);
                }
                fetterText[i].text = attrStr;
                fetterText[i].color = UIHelper.GetUIColor(isAllCollect ? TextColType.NavyBrown : TextColType.Gray);
                fetterNameText[i].text = fetterConfig.FetterName;
                fetterNameText[i].color = UIHelper.GetUIColor(isAllCollect ? TextColType.NavyBrown : TextColType.Gray);
            }
            else
            {
                fetterText[i].SetActive(false);
            }
        }
    }
}
Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -41,6 +41,15 @@
        return per;
    }
    public HB122_tagSCHeroInfo.tagSCHero GetHeroBookInfo(int heroID)
    {
        if (heroCollectInfoDic.ContainsKey(heroID))
        {
            return heroCollectInfoDic[heroID];
        }
        return null;
    }
    #endregion
}
Main/System/HeroUI/HeroUIManager.Reborn.cs
@@ -6,46 +6,60 @@
public partial class HeroUIManager : GameSystemManager<HeroUIManager>
{
    #region 重生 遣散
    public int awakeRebirthCnt { get; private set; }
    public int payBackMoneyType;
    public int payBackMoney;
    public Dictionary<int, ulong> GetHeroLVPayBack(int quality, int lv)
    public int rebornAwakeHeroMaxCount; //觉醒武将每日的最大重生次数
    public List<string> heroDeleteSortList { get; private set; } = new List<string>();
    public int selectHeroDeleteListJob = 0;    //筛选职业
    public int selectHeroDeleteListCountry = 0;    //筛选国家
    public List<string> selectDeleteHeroList { get; private set; } = new List<string>();
    public Dictionary<int, long> GetHeroLVPayBack(int quality, int lv)
    {
        //汇总返还总数量
        Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
        Dictionary<int, long> itemCounDic = new Dictionary<int, long>();
        for (int i = 1; i < lv; i++)
        {
            var config = HeroQualityLVConfig.GetQualityLVConfig(quality, lv);
            var config = HeroQualityLVConfig.GetQualityLVConfig(quality, i);
            var itemID = config.UPCostItem[0];
            var count = (ulong)config.UPCostItem[1];
            var count = config.UPCostItem[1];
            if (!itemCounDic.ContainsKey(itemID))
            {
                itemCounDic[itemID] = count;
            }
            itemCounDic[itemID] = itemCounDic[itemID] + count;
            else
            {
                itemCounDic[itemID] += count;
            }
        }
        return itemCounDic;
    }
    public Dictionary<int, ulong> GetHeroBreakPayBack(int quality, int lv)
    public Dictionary<int, long> GetHeroBreakPayBack(int quality, int lv)
    {
        //汇总返还总数量
        Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
        Dictionary<int, long> itemCounDic = new Dictionary<int, long>();
        for (int i = 0; i < lv; i++)
        {
            var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, lv);
            var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, i);
            var itemID = config.UPCostItem[0];
            var count = (ulong)config.UPCostItem[1];
            var count = config.UPCostItem[1];
            if (!itemCounDic.ContainsKey(itemID))
            {
                itemCounDic[itemID] = count;
            }
            itemCounDic[itemID] = itemCounDic[itemID] + count;
            else
            {
                itemCounDic[itemID] += count;
            }
        }
        return itemCounDic;
@@ -53,20 +67,23 @@
    }
    public Dictionary<int, ulong> GetHeroQualityAwakePayBack(int quality, int lv)
    public Dictionary<int, long> GetHeroQualityAwakePayBack(int quality, int lv)
    {
        //汇总返还总数量
        Dictionary<int, ulong> itemCounDic = new Dictionary<int, ulong>();
        Dictionary<int, long> itemCounDic = new Dictionary<int, long>();
        for (int i = 0; i < lv; i++)
        {
            var config = HeroQualityAwakeConfig.GetQualityAwakeConfig(quality, lv);
            var itemID = config.UPCostItem[0];
            var count = (ulong)config.UPCostItem[1];
            var count = config.UPCostItem[1];
            if (!itemCounDic.ContainsKey(itemID))
            {
                itemCounDic[itemID] = count;
            }
            itemCounDic[itemID] = itemCounDic[itemID] + count;
            else
            {
                itemCounDic[itemID] = itemCounDic[itemID] + count;
            }
        }
        return itemCounDic;
@@ -77,7 +94,56 @@
        awakeRebirthCnt = netPack.AwakeRebirthCnt;
    }
    public void SortHeroDeleteList()
    {
        heroDeleteSortList = HeroManager.Instance.GetHeroGuidList(selectHeroDeleteListJob, selectHeroDeleteListCountry);
        heroDeleteSortList.Sort(CmpDeleteHero);
    }
    int CmpDeleteHero(string guidA, string guidB)
    {
        HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
        HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
        if (heroA == null || heroB == null)
        {
            return 0;
        }
        // 排序规则:上阵>武将等级>突破等级>武将觉醒阶级>武将品质>武将吞噬星级>武将ID
        bool isInTeamA = heroA.IsInAnyTeam();
        bool isInTeamB = heroB.IsInAnyTeam();
        if (isInTeamA != isInTeamB)
        {
            return isInTeamA ? 1 : -1;
        }
        if (heroA.heroLevel != heroB.heroLevel)
        {
            return heroA.heroLevel < heroB.heroLevel ? -1 : 1;
        }
        if (heroA.breakLevel != heroB.breakLevel)
        {
            return heroA.breakLevel < heroB.breakLevel ? -1 : 1;
        }
        if (heroA.awakeLevel != heroB.awakeLevel)
        {
            return heroA.awakeLevel < heroB.awakeLevel ? -1 : 1;
        }
        if (heroA.Quality != heroB.Quality)
        {
            return heroA.Quality < heroB.Quality ? -1 : 1;
        }
        if (heroA.heroStar != heroA.heroStar)
        {
            return heroA.heroStar < heroB.heroStar ? -1 : 1;
        }
        return heroB.heroId.CompareTo(heroA.heroId);
    }
    #endregion
}
Main/System/HeroUI/HeroUIManager.cs
@@ -16,6 +16,10 @@
    public WaitHeroFuncResponse waitResponse;    //请求武将功能,与服务端交互
    public const float lihuiScale = 0.6f;   //立绘缩放大小
    //用于非上阵武将战力变化时 武将ID:上次战力
    public KeyValuePair<string, long> lastFightPower = new KeyValuePair<string, long>();
    public override void Init()
    {
@@ -34,7 +38,7 @@
    {
        var config = FuncConfigConfig.Get("HeroRebirth");
        payBackMoneyType = int.Parse(config.Numerical1);
        payBackMoney = int.Parse(config.Numerical2);
        rebornAwakeHeroMaxCount = int.Parse(config.Numerical2);
    }
    public void OnBeforePlayerDataInitialize()
@@ -124,7 +128,6 @@
        return hero.heroLevel == GetMaxLVByBreakLV(hero.Quality, hero.breakLevel);
    }
    #endregion
@@ -144,7 +147,7 @@
            {
                if (isOK)
                {
                    if (UIHelper.GetMoneyCnt(buyInfo[0]) < (ulong)buyInfo[1])
                    if (UIHelper.GetMoneyCnt(buyInfo[0]) < buyInfo[1])
                    {
                        SysNotifyMgr.Instance.ShowTip("LackMoney", buyInfo[0]);
                        return;
@@ -203,10 +206,99 @@
    }
    #region 招募
    public HappXBTitle selectCallType;  //寻宝枚举类型
    public int selectCallIndex;//0:1抽 1:10抽 对应配置顺序
    public const string skipKey = "SkipHeroCall";
    //积分招募预览
    public List<int> heroCallSortList { get; private set; } = new List<int>();  //积分招募列表
    public int selectHeroCallListJob = 0;    //筛选职业
    public int selectHeroCallListCountry = 0;    //筛选国家
    public bool IsNewHero(int heroID)
    {
        var bookInfo = GetHeroBookInfo(heroID);
        if (bookInfo != null)
        {
            if (bookInfo.BookInitState < 2)
            {
                //更精准的 需要比较本次抽的同武将个数 和 背包里有的个数再比较
                if (HappyXBModel.Instance.GetCountInResult(heroID) >= HeroManager.Instance.GetHeroCountByID(heroID))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        return true;
    }
    List<int> allHeroCallScoreList = new List<int>();  //积分招募列表
    public void SortHeroCallList()
    {
        if (allHeroCallScoreList.IsNullOrEmpty())
        {
            allHeroCallScoreList = HappyXBModel.Instance.GetAllGridLibItemIDByType((int)HappXBTitle.HeroCallScore);
        }
        heroCallSortList = new List<int>();
        if (selectHeroCallListJob == 0 && selectHeroCallListCountry == 0)
        {
            heroCallSortList = allHeroCallScoreList;
        }
        else
        {
            foreach (var item in allHeroCallScoreList)
            {
                HeroConfig heroConfig = HeroConfig.Get(item);
                if (heroConfig == null)
                {
                    continue;
                }
                if (selectHeroCallListJob != 0 && selectHeroCallListJob != heroConfig.Class)
                {
                    continue;
                }
                if (selectHeroCallListCountry != 0 && selectHeroCallListCountry != heroConfig.Country)
                {
                    continue;
                }
                heroCallSortList.Add(item);
            }
        }
        heroCallSortList.Sort(CmpHeroID);
    }
    int CmpHeroID(int idA, int idB)
    {
        HeroConfig heroA = HeroConfig.Get(idA);
        HeroConfig heroB = HeroConfig.Get(idB);
        // 排序规则:武将品质>武将ID
        if (heroA.Quality != heroB.Quality)
        {
            return heroA.Quality > heroB.Quality ? -1 : 1;
        }
        return heroA.HeroID.CompareTo(heroB.HeroID);
    }
    #endregion
}
public struct WaitHeroFuncResponse
Main/System/Invest.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8b5c73a4ffdc4c64da1462264f99720f
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Invest/InvestModel.cs
New file
@@ -0,0 +1,377 @@
using System;
using System.Collections.Generic;
using UnityEngine.UI;
using System.Linq;
using LitJson;
public class InvestModel : GameSystemManager<InvestModel>
{
    public ILOpenServerActivityProxy activity;
    public const int FuncID = 119;
    //投资对应奖励
    Dictionary<int, Dictionary<int, List<Item>>> m_InvestItems = new Dictionary<int, Dictionary<int, List<Item>>>();
    //投资对应充值ID
    Dictionary<int, int[]> m_InvestRechargeIds = new Dictionary<int, int[]>();
    //投资对应购买情况
    Dictionary<int, InvestInfo> m_InvestInfos = new Dictionary<int, InvestInfo>();
    //{投资类型:[领取天,当前天]} 天从1开始
    Dictionary<int, List<List<int>>> m_InvestSingleInfos = new Dictionary<int, List<List<int>>>();
    //投资对应的红点
    Dictionary<int, Redpoint> m_Redpoints = new Dictionary<int, Redpoint>();
    //投资类型
    public List<int> investTypes = new List<int>();
    //永久卡 权限
    public const int foreverCardType = 12; //投资类型
    public const int monthCardType = 7; // 月卡7
    public event Action onSelectUpdate;
    public event Action onInvestUpdate;
    public const int redpointID = 20931;
    public Redpoint redpoint = new Redpoint(MainRedDot.REDPOINT_OPENSERVER, redpointID);
    public override void Init()
    {
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
        //通过配置决定是否有此投资项,如港台没有登录投资
        ParseConfig();
    }
    public override void Release()
    {
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
    }
    public bool IsOpen()
    {
        return FuncOpen.Instance.IsFuncOpen(FuncID);
    }
    public void OnBeforePlayerDataInitialize()
    {
        m_InvestInfos.Clear();
        m_InvestSingleInfos.Clear();
    }
    public void OnPlayerLoginOk()
    {
        UpdateRedpoint();
    }
    void ParseConfig()
    {
        investTypes.Clear();
        var funcConfig = FuncConfigConfig.Get("InvestCost");
        m_InvestRechargeIds = ConfigParse.ParseIntArrayDict(funcConfig.Numerical3);
        //m_Redpoints
        investTypes = m_InvestRechargeIds.Keys.ToList();
        investTypes.Sort();
        var configs = InvestConfig.GetValues();
        for (int i = 0; i < configs.Count; i++)
        {
            var config = configs[i];
            if (!investTypes.Contains(config.type))
            {
                continue;
            }
            Dictionary<int, List<Item>> dict;
            if (!m_InvestItems.TryGetValue(config.type, out dict))
            {
                dict = new Dictionary<int, List<Item>>();
                m_InvestItems.Add(config.type, dict);
            }
            List<Item> items;
            if (!dict.TryGetValue(config.id, out items))
            {
                items = new List<Item>();
                dict.Add(config.id, items);
            }
            var itemArray = config.award[1];    //1暂时约定月卡 永久卡,其他的自定义后续再定
            for (int j = 0; j < itemArray.Length; j++)
            {
                items.Add(new Item()
                {
                    id = itemArray[j][0],
                    countEx = itemArray[j][1],
                    bind = itemArray[j][2],
                });
            }
        }
    }
    public OrderInfoConfig GetOrderInfoId(int type)
    {
        var ids = m_InvestRechargeIds[type];
        for (int i = 0; i < ids.Length; i++)
        {
            OrderInfoConfig config;
            if (RechargeManager.Instance.TryGetOrderInfo(ids[i], out config))
            {
                return config;
            }
        }
        return null;
    }
    public bool hasInvestType(int type)
    {
        return investTypes.Contains(type);
    }
    public int GetInvestPassDays(int type)
    {
        return m_InvestInfos.ContainsKey(type) ? m_InvestInfos[type].days : 0;
    }
    //获得单投资的总收益
    public long GetTotalIncome(int type)
    {
        long income = 0;
        if (m_InvestItems.ContainsKey(type))
        {
            var keyList = m_InvestItems[type].Keys.ToList();
            for (int i = 0; i < keyList.Count; i++)
            {
                var items = m_InvestItems[type][keyList[i]];
                for (var j = 0; j < items.Count; j++)
                {
                    var item = items[j];
                    if (item.id == 20 || item.id == 30)
                        income += item.countEx;
                }
            }
        }
        return income;
    }
    //id 为表里的ID
    //0-未投资 1-未达成 2-可领取 3-已领取
    public int GetSingleInvestState(int type, int id)
    {
        if (IsInvested(type))
        {
            var day = GetInvestPassDays(type);
            if (m_InvestItems.ContainsKey(type)
                && m_InvestItems[type].ContainsKey(id))
            {
                if (IsRewardGot(type, id))
                {
                    return 3;
                }
                var config = InvestConfig.Get(id);
                if (!m_InvestSingleInfos.ContainsKey(type))
                {
                    return 0;
                }
                var index = id % 100;
                //每个数按位存31个激活索引
                var listIndex = index / 31;
                var bitIndex = index % 31;
                return day < config.needDay ? 1 : 2;
            }
        }
        return 0;
    }
    public bool TryGetItems(int type, int id, out List<Item> items)
    {
        items = null;
        if (m_InvestItems.ContainsKey(type))
        {
            return m_InvestItems[type].TryGetValue(id, out items);
        }
        return false;
    }
    public List<int> GetIdsByType(int type)
    {
        if (m_InvestItems.ContainsKey(type))
        {
            return m_InvestItems[type].Keys.ToList();
        }
        return null;
    }
    //判断是否购买了投资
    public bool IsInvested(int type)
    {
        return m_InvestInfos.ContainsKey(type) && m_InvestInfos[type].money > 0;
    }
    //奖励是否已领取
    public bool IsRewardGot(int type, int id)
    {
        if (m_InvestSingleInfos.ContainsKey(type))
        {
            var index = id % 100;
            //每个数按位存31个激活索引
            var listIndex = index / 31;
            var bitIndex = index % 31;
            return ((int)Math.Pow(2, bitIndex) & m_InvestSingleInfos[type][1][listIndex]) != 0;
        }
        return false;
    }
    private void OnFuncStateChangeEvent(int id)
    {
        if (id == FuncID)
        {
            activity.StateUpdate(id);
            UpdateRedpoint();
        }
    }
    public void SendGetReward(int type, int id)
    {
        var pak = new CA541_tagCMGetInvestReward();
        pak.InvestType = (byte)type;
        pak.RewardIndex = (byte)(id % 100);
        GameNetSystem.Instance.SendInfo(pak);
    }
    //购买投资
    public void BuyInvest(int type)
    {
        RechargeManager.Instance.CTG(GetOrderInfoId(type));
    }
    public void UpdateInvestInfo(HA338_tagMCInvestInfo package)
    {
        if (!investTypes.Contains(package.InvestType))
        {
            return;
        }
        m_InvestInfos[package.InvestType] = new InvestInfo()
        {
            days = (int)package.CurDay,
            money = package.CurDay >= 1 ? 1 : 0,
        };
        List<List<int>> singleInfos;
        if (!m_InvestSingleInfos.TryGetValue(package.InvestType, out singleInfos))
        {
            singleInfos = new List<List<int>>();
            m_InvestSingleInfos.Add(package.InvestType, singleInfos);
        }
        singleInfos.Clear();
        singleInfos.Add(new List<int>());
        singleInfos.Add(new List<int>());
        singleInfos.Add(new List<int>());
        singleInfos[0].Add((int)package.CurDay);
        for (int i = 0; i < package.ValueCount; i++)
        {
            singleInfos[1].Add((int)package.RewardValue[i]);
            singleInfos[2].Add((int)package.ProgressValue[i]);
        }
        UpdateRedpoint();
        if (onInvestUpdate != null)
        {
            onInvestUpdate();
        }
    }
    void UpdateRedpoint()
    {
        List<int> redpointTypes = new List<int>();
        if (IsOpen())
        {
            for (var i = 0; i < investTypes.Count; i++)
            {
                var type = investTypes[i];
                if (!IsInvested(type))
                {
                    continue;
                }
                var keyList = m_InvestItems[type].Keys.ToList();
                for (int j = 0; j < keyList.Count; j++)
                {
                    var id = keyList[j];
                    if (GetSingleInvestState(type, id) == 2)
                    {
                        redpointTypes.Add(type);
                        break;
                    }
                }
            }
        }
        var redList = m_Redpoints.Keys.ToList();
        for (int j = 0; j < redList.Count; j++)
        {
            var type = redList[j];
            m_Redpoints[type].state = redpointTypes.Contains(type) ? RedPointState.Simple : RedPointState.None;
        }
    }
    //已经购买并领取所有物品
    public bool IsFinish()
    {
        for (int i = 0; i < investTypes.Count; i++)
        {
            int type = investTypes[i];
            //忽略永久卡
            if (type == foreverCardType)
                continue;
            var idsList = GetIdsByType(type);
            if (idsList.IsNullOrEmpty())
                continue;
            for (int j = 0; j < idsList.Count; j++)
            {
                int id = idsList[j];
                if (GetSingleInvestState(type, id) != 3)
                {
                    return false;
                }
            }
        }
        return true;
    }
    public struct InvestInfo
    {
        public int money;
        public int days;
    }
}
Main/System/Invest/InvestModel.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/Invest/InvestModel.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 2b3e856e57feb8b48aff823cacee137c
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/ItemTip/BoxGetItemModel.cs
@@ -2,6 +2,7 @@
using LitJson;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 宝箱功能 + 获取奖励界面
@@ -76,14 +77,19 @@
        //     ModelCenter.Instance.GetModel<FairySiegeActModel>()?.OnUpdateAwardInfoAction(netPack);
        //     return;
        // }
        if (!commonShowAwardEvents.Contains(eventName))
        // if (!commonShowAwardEvents.Contains(eventName))
        //     return;
        if (string.IsNullOrEmpty(eventName))
        {
            Debug.Log("获得物品展示 无事件名");
            return;
        }
        List<Item> showItems = new List<Item>();
        if (netPack.Exp != 0 || netPack.ExpPoint != 0)
        {
            ulong expValue = netPack.Exp + netPack.ExpPoint * (ulong)Constants.ExpPointValue;
            long expValue = netPack.Exp + netPack.ExpPoint * Constants.ExpPointValue;
            showItems.Add(new Item(GeneralDefine.expDisplayId, expValue));
        }
        if (netPack.MoneyList.Length != 0)
@@ -305,7 +311,7 @@
            var selectlistDict = ConfigParse.GetDic<int, int>(config.SelectList);
            foreach (var item in selectlistDict)
            {
                itemIDs.Add(new Item(item.Key, (ulong)item.Value));
                itemIDs.Add(new Item(item.Key, item.Value));
            }
        }
@@ -314,7 +320,7 @@
            var itemListDict = ConfigParse.GetDic<int, int>(config.FixedItem);
            foreach (var item in itemListDict)
            {
                itemIDs.Add(new Item(item.Key, (ulong)item.Value));
                itemIDs.Add(new Item(item.Key, item.Value));
            }
        }
@@ -324,7 +330,7 @@
            for (int i = 0; i < arr.Count; i++)
            {
                itemIDs.Add(new Item(int.Parse(arr[i][1][0].ToString()), ulong.Parse(arr[i][1][1].ToString())));
                itemIDs.Add(new Item(int.Parse(arr[i][1][0].ToString()), long.Parse(arr[i][1][1].ToString())));
            }
        }
@@ -334,7 +340,7 @@
            for (int i = 0; i < arr.Count; i++)
            {
                itemIDs.Add(new Item(int.Parse(arr[i][1][0].ToString()), ulong.Parse(arr[i][1][1].ToString())));
                itemIDs.Add(new Item(int.Parse(arr[i][1][0].ToString()), long.Parse(arr[i][1][1].ToString())));
            }
        }
Main/System/ItemTip/BoxItemWin.cs
@@ -53,7 +53,7 @@
        itemCount = ItemTipUtility.mainTipData.baseInfo.count;
        guid = ItemTipUtility.mainTipData.guid;
        itemCell.Init(new ItemCellModel(itemID, false, (ulong)itemCount));
        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
        var itemConfig = ItemConfig.Get(itemID);
        nameText.text = itemConfig.ItemName;
        descText.text = itemConfig.Description;
Main/System/ItemTip/ChooseItemsCell.cs
@@ -20,7 +20,7 @@
        this.guid = _guid;
        ItemConfig itemConfig = ItemConfig.Get(itemId);
        int count = itemArr[1];
        itemCell.Init(new ItemCellModel(itemId, false, (ulong)count));
        itemCell.Init(new ItemCellModel(itemId, false, count));
        itemCell.button.SetListener(() =>
        {
            ItemTipUtility.Show(itemId);
Main/System/ItemTip/ChooseItemsWin.cs
@@ -43,7 +43,7 @@
        guid = ItemTipUtility.mainTipData.guid;
        InitItemsData();
        itemCell.Init(new ItemCellModel(itemID, false, (ulong)itemCount));
        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
        var itemConfig = ItemConfig.Get(itemID);
        nameText.text = itemConfig.ItemName;
        descText.text = itemConfig.Description;
Main/System/ItemTip/ItemTipUtility.cs
@@ -223,6 +223,20 @@
    public static TipData mainTipData { get; private set; }     // 注意当递进点击打开多个tip界面会变更数据,不能依赖此值
    public static TipData secondaryData { get; private set; }
    public static void ShowMoneyTip(int moneyType)
    {
        if (GeneralDefine.MoneyDisplayModel.ContainsKey(moneyType))
        {
            Show(GeneralDefine.MoneyDisplayModel[moneyType], true);
        }
        else
        {
            SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
            // Debug.LogErrorFormat("配置MoneyDisplayModel 查无此货币:{0}", moneyType);
        }
    }
    public static void Show(int itemId, bool showGetWay = false)
    {
        if (!ItemConfig.HasKey(itemId))
Main/System/ItemTip/ItemTipWin.cs
@@ -19,7 +19,7 @@
        var item = ItemTipUtility.mainTipData.baseInfo;
        if (string.IsNullOrEmpty(ItemTipUtility.mainTipData.guid))
        {
            itemCell.Init(new ItemCellModel(item.itemId, false, (ulong)item.count));
            itemCell.Init(new ItemCellModel(item.itemId, false, item.count));
        }
        else
        {
Main/System/ItemTip/OwnItemCell.cs
New file
@@ -0,0 +1,59 @@
using UnityEngine;
using UnityEngine.UI;
//拥有的物品:数量显示,点击按钮显示途径tip
public class OwnItemCell : MonoBehaviour
{
    [SerializeField] Image itemIcon;
    [SerializeField] Text numText;
    [SerializeField] Button wayBtn;
    public int itemID;
    void Start()
    {
        if (itemID != 0)
            itemIcon.SetOrgSprite(ItemConfig.Get(itemID).IconKey);
        wayBtn.AddListener(()=>
        {
            ItemTipUtility.Show(itemID, true);
        });
    }
    void OnEnable()
    {
        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
        Display();
    }
    void OnDisable()
    {
        PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
    }
    public void RefreshItemEvent(PackType packType, int index, int itemID)
    {
        if (packType != PackType.Item && this.itemID != itemID)
        {
            return;
        }
        Display();
    }
    public void Display(bool resetIcon = false)
    {
        if (itemID == 0)
        {
            Debug.LogError("itemID == 0");
            return;
        }
        numText.text = UIHelper.ReplaceLargeNum(PackManager.Instance.GetItemCountByID(PackType.Item, itemID));
        if (resetIcon)
        {
            itemIcon.SetOrgSprite(ItemConfig.Get(itemID).IconKey);
        }
    }
}
Main/System/ItemTip/OwnItemCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/ItemTip/OwnItemCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 276c484af2e519e4fa34d4143606ac0c
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/ItemTip/OwnMoneyCell.cs
New file
@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.UI;
//拥有的货币:数量显示,点击按钮打开对应获取界面
public class OwnMoneyCell : MonoBehaviour
{
    [SerializeField] Image moneyIcon;
    [SerializeField] Text numText;
    [SerializeField] Button wayBtn;
    public int moneyType;
    void Start()
    {
        if (moneyType != 0)
            moneyIcon.SetIconWithMoneyType(moneyType);
        if (wayBtn != null)
        {
            wayBtn.AddListener(()=>
            {
                switch (moneyType)
                {
                    // case 1:
                    //     {
                    //         //UIManager.Instance.OpenWindow<RechargeWin>();
                    //     }
                    //     break;
                    default:
                        {
                            ItemTipUtility.ShowMoneyTip(moneyType);
                        }
                        break;
                }
            });
        }
    }
    void OnEnable()
    {
        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
        Display();
    }
    void OnDisable()
    {
        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
    }
    void PlayerDataRefresh(PlayerDataType type)
    {
        if (type != UIHelper.moneyTypeToPlayerDataType[moneyType])
        {
            return;
        }
        Display();
    }
    public void Display(bool resetIcon = false)
    {
        if (moneyType == 0)
        {
            Debug.LogError("moneyType == 0");
            return;
        }
        numText.text = UIHelper.ReplaceLargeNum(UIHelper.GetMoneyCnt(moneyType));
        if (resetIcon)
        {
            moneyIcon.SetIconWithMoneyType(moneyType);
        }
    }
}
Main/System/ItemTip/OwnMoneyCell.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/ItemTip/OwnMoneyCell.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: 60eea7a00f3be64488810a1daa59c712
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/KnapSack/BackpackData.cs
@@ -9,11 +9,11 @@
public struct Item
{
    public int id;
    public ulong countEx;
    public long countEx;
    public int quality;
    public int bind;    //绑定 或者 拍卖 交易
    public Item(int _id, ulong _count)
    public Item(int _id, long _count)
    {
        this.id = _id;
        this.quality = 0;
@@ -22,7 +22,7 @@
    }
    
    public Item(int _id, ulong _count, int _quality)
    public Item(int _id, long _count, int _quality)
    {
        this.id = _id;
        this.quality = _quality;
@@ -30,7 +30,7 @@
        this.countEx = _count;
    }
    public Item(int _id, ulong _count, int _bind = 0, int _quality = 0)
    public Item(int _id, long _count, int _bind = 0, int _quality = 0)
    {
        this.id = _id;
        this.quality = _quality;
Main/System/KnapSack/Logic/ItemLogicUtility.cs
@@ -270,7 +270,7 @@
    /// <param name="needCount 需要数量"></param>
    /// <param name="needTips">0 不响应 1 弹提示 2 弹获取途径tips</param>
    /// <returns></returns>
    public static bool CheckItemCount(PackType packType, int itemId, ulong needCount, int needTips = 0)
    public static bool CheckItemCount(PackType packType, int itemId, long needCount, int needTips = 0)
    {
        if (needCount <= 0)
        {
@@ -296,14 +296,14 @@
        return isEnough;
    }
    public static bool CheckCurrencyCount(int moneyType, ulong needCount, bool needTips = false)
    public static bool CheckCurrencyCount(int moneyType, long needCount, bool needTips = false)
    {
        if (needCount <= 0)
        {
            return true;
        }
        ulong haveCount = UIHelper.GetMoneyCnt(moneyType);
        long haveCount = UIHelper.GetMoneyCnt(moneyType);
        bool isEnough = haveCount >= needCount;
@@ -895,7 +895,7 @@
    #endregion
    //设置玩家货币显示
    public string OnChangeCoinsUnit(ulong value)
    public string OnChangeCoinsUnit(long value)
    {
        return UIHelper.ReplaceLargeNum(value);
    }
Main/System/KnapSack/Logic/SinglePack.cs
@@ -182,9 +182,9 @@
        return list;
    }
    public ulong GetCountById(int itemId, bool includeAuction = true)
    public long GetCountById(int itemId, bool includeAuction = true)
    {
        ulong count = 0;
        long count = 0;
        //部分货币和物品绑定
        if (GeneralDefine.itemMoneyCountDict.ContainsKey(itemId))
@@ -202,7 +202,7 @@
                {
                    continue;
                }
                count += (ulong)item.count;
                count += item.count;
            }
        }
        return count;
Main/System/KnapSack/New/CommonItemBaisc.cs
@@ -195,7 +195,7 @@
    public virtual void Init(ItemModel model, bool isCompare = false)
    {
        itemId = model.itemId;
        InitUI(model.guid, model.itemId, (ulong)model.count, model.isAuction, model.packType, isCompare, model.useDataDict);
        InitUI(model.guid, model.itemId, model.count, model.isAuction, model.packType, isCompare, model.useDataDict);
    }
    /// <summary>
@@ -208,7 +208,7 @@
        InitUI(model.guid, model.itemId, model.count, false, model.packType, model.isCompare, model.useDataDic);
    }
    private void InitUI(string guid, int itemId, ulong count, bool isAuction, PackType type, bool isCompare, Dictionary<int, List<int>> useDataDic)
    private void InitUI(string guid, int itemId, long count, bool isAuction, PackType type, bool isCompare, Dictionary<int, List<int>> useDataDic)
    {
        var config = ItemConfig.Get(itemId);
        if (config == null) return;
@@ -371,7 +371,7 @@
{
    public string guid { get; private set; }
    public int itemId { get; private set; }
    public ulong count { get; private set; }
    public long count { get; private set; }
    public int score { get; private set; }
    public bool isCompare { get; private set; }
    public ItemConfig itemConfig { get { return ItemConfig.Get(itemId); } }
@@ -379,7 +379,7 @@
    public Dictionary<int, List<int>> useDataDic { get; private set; }
    public ItemCellModel(int itemId, bool isPreview = false, ulong count = 0, string guid = "", PackType type = PackType.Deleted, bool isCompare = false, Dictionary<int, List<int>> useDataDic = null)
    public ItemCellModel(int itemId, bool isPreview = false, long count = 0, string guid = "", PackType type = PackType.Deleted, bool isCompare = false, Dictionary<int, List<int>> useDataDic = null)
    {
        this.itemId = AdjustItemId(itemId);
        this.guid = guid;
@@ -402,7 +402,7 @@
        this.score = 0;
    }
    public ItemCellModel(int itemId, bool isPreview, ulong count)
    public ItemCellModel(int itemId, bool isPreview, long count)
    {
        this.itemId = AdjustItemId(itemId);
        this.guid = "";
Main/System/KnapSack/PackManager.cs
@@ -779,9 +779,9 @@
    /// <param name="type"></param>
    /// <param name="id"></param>
    /// <returns></returns>
    public ulong GetItemCountByID(PackType type, int id, bool includeAuction = true)
    public long GetItemCountByID(PackType type, int id, bool includeAuction = true)
    {
        ulong count = 0;
        long count = 0;
        var singlePack = GetSinglePack(type);
        if (singlePack != null)
        {
Main/System/Launch/LaunchBackGroundWin.cs
@@ -8,8 +8,8 @@
public class LaunchBackGroundWin : UIBase
{
    // 组件引用
    [SerializeField] RectTransform m_StaticBackGround;
    [SerializeField] Image m_BackGroundImage;
    // [SerializeField] RectTransform m_StaticBackGround;
    // [SerializeField] Image m_BackGroundImage;
    [SerializeField] TextEx info;
    // 生命周期
    protected override void Awake()
@@ -33,10 +33,10 @@
        LoginManager.Instance.loginErrorEvent += OnLoginError;
        var sprite = BuiltInLoader.LoadSprite("LoginBackGround");
        m_BackGroundImage.overrideSprite = sprite;
        // var sprite = BuiltInLoader.LoadSprite("LoginBackGround");
        // m_BackGroundImage.overrideSprite = sprite;
        //m_BackGroundImage.preserveAspect = true;
        m_StaticBackGround.SetActive(true);
        // m_StaticBackGround.SetActive(true);
        this.transform.SetAsFirstSibling();
        info.text = LoginManager.Instance.loginErrorInfo;
Main/System/Launch/LaunchWin.cs
@@ -14,7 +14,7 @@
    public class LaunchWin : UIBase
    {
        // [SerializeField] UIAlphaTween m_AlphaTween;
        [SerializeField] Image m_BackGround;
        // [SerializeField] Image m_BackGround;
        [SerializeField] RectTransform m_AndroidProgressContainer;
        [SerializeField] RectTransform m_NetworkContainer;
        [SerializeField] SmoothSlider m_PartProgressSlider;
@@ -42,25 +42,25 @@
        protected override void InitComponent()
        {
            base.InitComponent();
            m_BackGround.preserveAspect = true;
            if (Application.isEditor)
            {
                var sprite = BuiltInLoader.LoadSprite("Launch_1");
                m_BackGround.overrideSprite = sprite;
            }
            else
            {
                for (var i = 0; i < 3; i++)
                {
                    var sprite = BuiltInLoader.LoadSprite(StringUtility.Contact("Launch_", i + 1));
                    if (sprite != null)
                    {
                        backGrounds.Add(sprite);
                    }
                }
            // m_BackGround.preserveAspect = true;
            // if (Application.isEditor)
            // {
            //     var sprite = BuiltInLoader.LoadSprite("Launch_1");
            //     m_BackGround.overrideSprite = sprite;
            // }
            // else
            // {
            //     for (var i = 0; i < 3; i++)
            //     {
            //         var sprite = BuiltInLoader.LoadSprite(StringUtility.Contact("Launch_", i + 1));
            //         if (sprite != null)
            //         {
            //             backGrounds.Add(sprite);
            //         }
            //     }
                m_BackGround.overrideSprite = backGrounds[0];
            }
            //     m_BackGround.overrideSprite = backGrounds[0];
            // }
        }
@@ -175,15 +175,15 @@
        {
            UpdateProgress();
            backGroundTimer += Time.deltaTime;
            if (backGroundTimer >= 3f)
            {
                backGroundTimer = 0f;
                if (backGrounds.Count > 1)
                {
                    m_BackGround.overrideSprite = backGrounds[(++backGroundIndex) % backGrounds.Count];
                }
            }
            // backGroundTimer += Time.deltaTime;
            // if (backGroundTimer >= 3f)
            // {
            //     backGroundTimer = 0f;
            //     if (backGrounds.Count > 1)
            //     {
            //         m_BackGround.overrideSprite = backGrounds[(++backGroundIndex) % backGrounds.Count];
            //     }
            // }
            if (HttpBehaviour.ConnectAllTimes >= AllTimes && m_NetworkContainer != null)
            {
@@ -283,7 +283,7 @@
            return new LaunchWinData(){
                backGroundTimer = backGroundTimer,
                backGroundIndex = backGroundIndex,
                sprite = m_BackGround.overrideSprite,
                // sprite = m_BackGround.overrideSprite,
                sprites = backGrounds,
            };
        }
Main/System/Launch/LoadingWin.cs
@@ -10,7 +10,7 @@
    protected int targetProgress = 0;
    // [SerializeField] UIAlphaTween m_AlphaTween;
    [SerializeField] Image m_BackGround;
    [SerializeField] RawImage m_BackGround;
    [SerializeField] SmoothSlider m_PartProgressSlider;
    [SerializeField] SmoothSlider m_TotalProgressSlider;
    [SerializeField] Text m_StageDescription;
@@ -26,30 +26,30 @@
    {
        base.InitComponent();
        if (Application.isEditor)
        {
            if (m_BackGround.overrideSprite == null)
            {
                var sprite = BuiltInLoader.LoadSprite("Launch_1");
                m_BackGround.overrideSprite = sprite;
            }
        }
        else
        {
            if (backGrounds.Count <= 0)
            {
                for (var i = 0; i < 3; i++)
                {
                    var sprite = BuiltInLoader.LoadSprite(StringUtility.Contact("Launch_", i + 1));
                    if (sprite != null)
                    {
                        backGrounds.Add(sprite);
                    }
                }
        // if (Application.isEditor)
        // {
        //     if (m_BackGround.overrideSprite == null)
        //     {
        //         var sprite = BuiltInLoader.LoadSprite("Launch_1");
        //         m_BackGround.overrideSprite = sprite;
        //     }
        // }
        // else
        // {
        //     if (backGrounds.Count <= 0)
        //     {
        //         for (var i = 0; i < 3; i++)
        //         {
        //             var sprite = BuiltInLoader.LoadSprite(StringUtility.Contact("Launch_", i + 1));
        //             if (sprite != null)
        //             {
        //                 backGrounds.Add(sprite);
        //             }
        //         }
                m_BackGround.overrideSprite = backGrounds[0];
            }
        }
        //         m_BackGround.overrideSprite = backGrounds[0];
        //     }
        // }
    }
    protected override void OnPreOpen()
@@ -116,30 +116,30 @@
    protected void LateUpdate()
    {
        UpdateProgress();
        CopiedLogic_LateUpdate();
        // CopiedLogic_LateUpdate();
    }
    private void CopiedLogic_LateUpdate()
    {
        backGroundTimer += Time.deltaTime;
        if (backGroundTimer >= 3f)
        {
            backGroundTimer -= 3f;
            if (backGrounds.Count > 1)
            {
                m_BackGround.overrideSprite = backGrounds[(++backGroundIndex) % backGrounds.Count];
            }
        // backGroundTimer += Time.deltaTime;
        // if (backGroundTimer >= 3f)
        // {
        //     backGroundTimer -= 3f;
        //     if (backGrounds.Count > 1)
        //     {
        //         m_BackGround.overrideSprite = backGrounds[(++backGroundIndex) % backGrounds.Count];
        //     }
            //  考虑在这里做这个描述的切换 或者根据图片来做提示词
            // m_StageDescription.text = "";
        }
        //     //  考虑在这里做这个描述的切换 或者根据图片来做提示词
        //     // m_StageDescription.text = "";
        // }
    }
    public void SetData(LaunchWinData _launchWinData)
    {
        backGroundTimer = _launchWinData.backGroundTimer;
        backGroundIndex = _launchWinData.backGroundIndex;
        m_BackGround.overrideSprite = _launchWinData.sprite;
        // m_BackGround.overrideSprite = _launchWinData.sprite;
        backGrounds = _launchWinData.sprites;
        m_StageDescription.text = Language.GetFromLocal(44);//最后Completed一定是这个 考虑要不要塞入LaunchWinData..
    }
Main/System/Login/GameAgeWarnWin.cs
@@ -14,26 +14,19 @@
    [SerializeField] Transform m_Info2;
    [SerializeField] Transform m_Title3;    //年龄
    [SerializeField] Transform m_Info3;
    [SerializeField] Button m_Close;
    public static int data = 1;
    protected override void InitComponent()
    {
        m_Close.AddListener(CloseWindow);
    }
    // UI事件
    protected override void OnOpen()
    {
        m_Title1.SetActive(data == 1);
        m_Info1.SetActive(data == 1);
        m_Title2.SetActive(data == 2);
        m_Info2.SetActive(data == 2);
        m_Title3.SetActive(data == 3);
        m_Title1.SetActive(data == 1);
        m_Info1.SetActive(data == 1);
        m_Title2.SetActive(data == 2);
        m_Info2.SetActive(data == 2);
        m_Title3.SetActive(data == 3);
        m_Info3.SetActive(data == 3);
    }
Main/System/Mail/MailInfoAwardItemCell.cs
@@ -13,7 +13,7 @@
        if (index < 0 || index >= mailData.Items.Count)
            return;
        MailItemData data = mailData.Items[index];
        itemCell.Init(new ItemCellModel((int)data.ItemID, true, (ulong)data.Count));
        itemCell.Init(new ItemCellModel((int)data.ItemID, true, data.Count));
        itemCell.button.SetListener(() => ItemTipUtility.Show((int)data.ItemID));
        imgHave.SetActive(mailState == 3);
Main/System/Main/FightPowerManager.cs
@@ -385,6 +385,24 @@
        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);
@@ -474,6 +492,36 @@
    #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;
    }
}
Main/System/Main/HomeWin.cs
@@ -29,6 +29,10 @@
    [SerializeField] Button autoBtn;
    //其他功能入口
    [SerializeField] Button monthCardBtn;
    /// <summary>
    /// 初始化组件
    /// </summary>
@@ -46,7 +50,7 @@
            UIManager.Instance.OpenWindow<HeroPosWin>();
        });
        autoBtn.AddListener(()=>
        autoBtn.AddListener(() =>
        {
            //测试拾取所有物品
            var items = PackManager.Instance.GetItems(PackType.DropItem);
@@ -64,9 +68,15 @@
            }
            if (dropindexs.Count > 0)
            {
                EquipModel.Instance.NotifyItemDrop(dropindexs, BattleManager.Instance.storyBattleField.battleRootNode.blueTeamNodeList[Random.Range(0,5)].GetComponent<RectTransform>());
                EquipModel.Instance.NotifyItemDrop(dropindexs, BattleManager.Instance.storyBattleField.battleRootNode.blueTeamNodeList[Random.Range(0, 5)].GetComponent<RectTransform>());
                dropindexs.Clear();
            }
        });
        monthCardBtn.AddListener(() =>
        {
            InvestModel.Instance.BuyInvest(InvestModel.monthCardType);
        });
    }
@@ -77,6 +87,7 @@
    {
        UpdatePlayerInfo();
        UpdateTask();
        RefreshRecharge();
    }
    protected override void OnPreOpen()
@@ -119,6 +130,11 @@
    }
    void RefreshRecharge()
    {
        monthCardBtn.SetActive(!InvestModel.Instance.IsInvested(InvestModel.monthCardType));
    }
    /// <summary>
    /// 更新玩家信息
    /// </summary>
Main/System/Main/MainWin.cs
@@ -13,8 +13,6 @@
    [SerializeField] Text playerNameText;
    [SerializeField] Text powerText;
    [SerializeField] OfficialTitleCell officialRankText;
    [SerializeField] Text goldText;
    [SerializeField] Text sparText;
    public Text hammerText;
@@ -74,12 +72,6 @@
            case PlayerDataType.RealmLevel:
                officialRankText.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
                break;
            case PlayerDataType.Gold:
                goldText.text = UIHelper.GetMoneyCntEx(1).ToString();
                break;
            case PlayerDataType.default33:
                sparText.text = UIHelper.GetMoneyCnt(42).ToString();
                break;
            case PlayerDataType.Face:
            case PlayerDataType.FacePic:
                avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
@@ -101,8 +93,6 @@
    private void UpdateCurrency()
    {
        hammerText.text = UIHelper.GetMoneyCnt(41).ToString();
        goldText.text = UIHelper.GetMoneyCntEx(1).ToString();
        sparText.text = UIHelper.ReplaceLargeNumEx(UIHelper.GetMoneyCnt(42));
    }
    
    /// <summary>
Main/System/Main/PlayerMainDate.cs
@@ -47,36 +47,21 @@
    }
    public void PowerAdd(ulong power)
    public void PowerAdd(long power)
    {
        if (prowBool)
        {
            prowNum = (long)power;
            prowNum = power;
            prowBool = false;
        }
        else
        {
            if ((long)power > prowNum)
            if (power != prowNum)
            {
                prowNumChange = (long)power - prowNum;
                prowNum = (long)power;
                isAdd = true;
                if (customDisplayPower != null && customDisplayPower())
                {
                    return;
                }
                if (UIManager.Instance.IsOpened<PowerAddWin>())
                {
                    AddPowerEvent?.Invoke();
                    return;
                }
                UIManager.Instance.OpenWindow<PowerAddWin>();
            }
            else if ((long)power < prowNum)
            {
                prowNumChange = prowNum - (long)power;
                prowNum = (long)power;
                isAdd = false;
                prowNumChange = power - prowNum;
                prowNum = power;
                isAdd = prowNumChange > 0;
                prowNumChange = Math.Abs(prowNumChange);
                if (customDisplayPower != null && customDisplayPower())
                {
                    return;
@@ -90,7 +75,7 @@
            }
            else
            {
                prowNum = (long)power;
                prowNum = power;
            }
        }
    }
@@ -108,7 +93,34 @@
    //     UIManager.Instance.OpenWindow<PowerAddWin>();
    // }
    /// <summary>
    /// 武将自身的战力变化
    /// </summary>
    /// <param name="hero"></param>
    public void AddPowerNotOnTeam(HeroInfo hero)
    {
        if (HeroUIManager.Instance.lastFightPower.Key != hero.itemHero.guid)
        {
            return;
        }
        if (hero.IsInTeamByTeamType(TeamType.Story))
        {
            return;
        }
        prowNumChange = hero.CalculatePower() - HeroUIManager.Instance.lastFightPower.Value;
        HeroUIManager.Instance.lastFightPower = new KeyValuePair<string, long>();
        isAdd = prowNumChange > 0;
        prowNumChange = Math.Abs(prowNumChange);
        prowNum = hero.CalculatePower();
        if (UIManager.Instance.IsOpened<PowerAddWin>())
        {
            AddPowerEvent?.Invoke();
            return;
        }
        UIManager.Instance.OpenWindow<PowerAddWin>();
    }
}
Main/System/Message/ColorAnalysis.cs
@@ -39,7 +39,7 @@
        }
        // switch (_value.ToLower())
        // {
        //     case "109d06":
        //     case "248B12":
        //         return "35e122";
        //     case "ff6701":
        //         return "f8983b";
Main/System/PhantasmPavilion/PhantasmPavilionModel.cs
@@ -430,7 +430,7 @@
                return 0;
            //激活物品数量不足
            var hasCnt = PackManager.Instance.GetItemCountByID(PackType.Item, itemId);
            if (hasCnt < (ulong)count)
            if (hasCnt < count)
                return 0;
            return 1;
        }
Main/System/Recharge/DailySpecialsModel.cs
@@ -55,7 +55,7 @@
            List<Item> itemList = new List<Item>();
            for (int j = 0; j < giftInfoDict[giftInfokeyList[i]].Count; j++)
            {
                Item item = new Item(giftInfoDict[giftInfokeyList[i]][j][0], (ulong)giftInfoDict[giftInfokeyList[i]][j][1]);
                Item item = new Item(giftInfoDict[giftInfokeyList[i]][j][0], giftInfoDict[giftInfokeyList[i]][j][1]);
                itemList.Add(item);
            }
            itemAllList.Add(itemList);
Main/System/Recharge/GotoChargeWin.cs
New file
@@ -0,0 +1,69 @@
//--------------------------------------------------------
//    [Author]:           第二世界
//    [  Date ]:           Wednesday, May 09, 2018
//--------------------------------------------------------
using System;
using UnityEngine;
using UnityEngine.UI;
public class GotoChargeWin : UIBase
{
    [SerializeField] Text m_CTGStageDisplay;
    public long startTime = DateTime.Now.Ticks;
    private void Update() {
#if !UNITY_EDITOR
        if (SDKUtils.Instance.FreePlatformInfo == null || string.IsNullOrEmpty(SDKUtils.Instance.FreePlatformInfo.account)){
            return;
        }
        if (DateTime.Now.Ticks - startTime > 50000000)
        {
            CloseWindow();
        }
#endif
        if (DateTime.Now.Ticks - startTime > 10000000)
        {
            CloseWindow();
        }
    }
    protected override void OnPreOpen()
    {
        SDKUtils.Instance.onFreePlatformPayCancel += OnChargeComplete;
        SDKUtils.Instance.onFreePlatformPayFail += OnChargeComplete;
        SDKUtils.Instance.onFreePlatformPayOk += OnChargeComplete;
        m_CTGStageDisplay.text = Language.Get("GotoCharging");
        RechargeManager.Instance.OnCTGStageChange += OnCTGStageChange;
        startTime = DateTime.Now.Ticks;
    }
    protected override void OnPreClose()
    {
        SDKUtils.Instance.onFreePlatformPayCancel -= OnChargeComplete;
        SDKUtils.Instance.onFreePlatformPayFail -= OnChargeComplete;
        SDKUtils.Instance.onFreePlatformPayOk -= OnChargeComplete;
        RechargeManager.Instance.OnCTGStageChange -= OnCTGStageChange;
    }
    private void OnCTGStageChange(string _display)
    {
        m_CTGStageDisplay.text = _display;
    }
    private void OnChargeComplete()
    {
        CloseWindow();
    }
}
Main/System/Recharge/GotoChargeWin.cs.meta
copy from Main/System/Hero/HeroConfigUtility.cs.meta copy to Main/System/Recharge/GotoChargeWin.cs.meta
File was copied from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: de7b6ab55e42a8349b47e45201f894d9
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Recharge/RechargeManager.cs
@@ -204,7 +204,7 @@
                        m_RechargeGainItemDict.Add(configs[i].CTGID, _itemList);
                        for (int k = 0; k < _itemArray.Length; k++)
                        {
                            Item _item = new Item(_itemArray[k][0], (ulong)_itemArray[k][1]);
                            Item _item = new Item(_itemArray[k][0], _itemArray[k][1]);
                            _itemList.Add(_item);
                        }
                    }
@@ -262,7 +262,7 @@
                for (int i = 0; i < _itemJson[jobstr].Count; i++)
                {
                    m_FirstChargeItemDict[day][job].Add(new Item(int.Parse(_itemJson[jobstr][i][0].ToString()),
                        ulong.Parse(_itemJson[jobstr][i][1].ToString())));
                        long.Parse(_itemJson[jobstr][i][1].ToString())));
                }
            }
@@ -274,7 +274,7 @@
            var _itemCommon = JsonMapper.ToObject<int[][]>(config.CommItemList);
            for (int i = 0; i < _itemCommon.Length; i++)
            {
                m_FirstChargeCommonItemDict[day].Add(new Item(_itemCommon[i][0], (ulong)_itemCommon[i][1]));
                m_FirstChargeCommonItemDict[day].Add(new Item(_itemCommon[i][0], _itemCommon[i][1]));
            }
Main/System/RoleParticulars/RoleParticularModel.cs
@@ -34,7 +34,7 @@
    public int viewPlayerType { get; private set; }  
    private Dictionary<int, ViewPlayerData> viewPlayerDataDic = new Dictionary<int, ViewPlayerData>();
    private Dictionary<int, ulong> funcFightPowerDict = new Dictionary<int, ulong>();
    private Dictionary<int, long> funcFightPowerDict = new Dictionary<int, long>();
    public event Action PowerUpdate;
    public static Action<int, int, ViewPlayerData> OnRevPackage; //尽量不要用第一个参数viewtype做判断,容易出错
@@ -212,7 +212,7 @@
        }
    }
    public ulong GetFuncFightPower(int type)
    public long GetFuncFightPower(int type)
    {
        if (funcFightPowerDict.ContainsKey(type))
        {
Main/System/Store/StoreModel.cs
@@ -922,11 +922,11 @@
    #endregion
    private ulong _price;
    private long _price;
    public void SendBuyShopItem(StoreConfig model, int count)
    {
        _price = (ulong)(model.MoneyNumber * count);
        _price = model.MoneyNumber * count;
        if (MoneyIsEnough(model.MoneyType, _price))
        {
@@ -968,9 +968,9 @@
    }
    //仙玉购买物品的二次确认框,一级货币只有仙玉 默认为仙玉即可
    Dictionary<int, bool> buyItemCheckDict = new Dictionary<int, bool>();
    //type 对应枚举 BuyStoreItemCheckType 方便记忆
    public void SendBuyShopItemWithPopCheck(StoreConfig model, int count, int type = 0)
    Dictionary<int, bool> buyItemCheckDict = new Dictionary<int, bool>();   //记录勾选信息
    //eventType 二次确认框类型,对应枚举 BuyStoreItemCheckType
    public void SendBuyShopItemWithPopCheck(StoreConfig model, int count, int eventType = 0)
    {
        if (model.MoneyNumber == 0)
        {
@@ -979,7 +979,7 @@
            return;
        }
        if (buyItemCheckDict.ContainsKey(type) && buyItemCheckDict[type])
        if (buyItemCheckDict.ContainsKey(eventType) && buyItemCheckDict[eventType])
        {
            SendBuyShopItem(model, count);
            return;
@@ -991,15 +991,15 @@
            if (isOk)
            {
                SendBuyShopItem(model, count);
                buyItemCheckDict[type] = isToggle;
                buyItemCheckDict[eventType] = isToggle;
            }
            
        }));
    }
    //花仙玉购买的二次确认框(本次登录) 默认提示 MysticalQG104    是否花费<color=#109d06>{0}</color>仙玉进行购买?
    //type 对应枚举 BuyStoreItemCheckType 方便记忆
    public void UseMoneyCheck(int money, Action func, int type = 0, string tip = "MysticalQG104", string fullTip = "")
    //花仙玉购买的二次确认框(本次登录)
    //eventType 二次确认框类型,对应枚举 BuyStoreItemCheckType
    public void UseMoneyCheck(int money, int moneyType, Action func, int eventType = 0, string tip = "CostMoney", string fullTip = "")
    {
        if (money == 0)
        {
@@ -1008,19 +1008,19 @@
            return;
        }
        if (buyItemCheckDict.ContainsKey(type) && buyItemCheckDict[type])
        if (buyItemCheckDict.ContainsKey(eventType) && buyItemCheckDict[eventType])
        {
            func?.Invoke();
            return;
        }
        ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), fullTip == "" ? Language.Get(tip, money) : fullTip,
        ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), fullTip == "" ? Language.Get(tip, money, moneyType) : fullTip,
            Language.Get("ConfirmCancel102"), (bool isOk, bool isToggle) =>
            {
                if (isOk)
                {
                    func?.Invoke();
                    buyItemCheckDict[type] = isToggle;
                    buyItemCheckDict[eventType] = isToggle;
                }
            });
@@ -1052,7 +1052,7 @@
    }
    public bool MoneyIsEnough(int moneyType, ulong money)
    public bool MoneyIsEnough(int moneyType, long money)
    {
        if (UIHelper.GetMoneyCnt(moneyType) < money)
        {
@@ -1409,7 +1409,7 @@
                    {
                        if (!TryGetIsSellOut(storeConfig, out remainNum))
                        {
                            if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= (ulong)storeConfig.MoneyNumber)
                            if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= storeConfig.MoneyNumber)
                            {
                                shopRedDict[storeConfig.ID].state = RedPointState.Simple;
                            }
@@ -1496,7 +1496,7 @@
                        {
                            break;
                        }
                        if (!MoneyIsEnough(config.MoneyType, (ulong)config.MoneyNumber))
                        if (!MoneyIsEnough(config.MoneyType, config.MoneyNumber))
                        {
                            break;
                        }
Main/System/Team/TeamType.cs
@@ -4,7 +4,9 @@
{
    None = 0,
    Story = 1, //主线
    Arena = 2,    //竞技场进攻
    ArenaDefense = 3,    //竞技场防守
    Arena = 2,  //竞技场进攻
    ArenaDefense = 3,   //竞技场防守
    Max,    //最大值放最后,用于for循环,故阵容枚举按顺序+1定义,如果不按此规则请修改Max相关逻辑
}
Main/System/Tip/ConfirmCancel.cs
@@ -261,7 +261,17 @@
    public static string generalItemTip2;
    public static List<Item> getItems { get; private set; }
    //多物品确认框
    /// <summary>
    /// 多物品确认框
    /// </summary>
    /// <param name="items"></param>
    /// <param name="tiltle"></param>
    /// <param name="info"></param>
    /// <param name="func"></param>
    /// <param name="info2"></param>
    /// <param name="btnText">为空时默认显示确定文字</param>
    /// <param name="moneyCnt"></param>
    /// <param name="type"></param>
    public static void ShowItemsConfirm(List<Item> items, string tiltle, string info, Action<bool> func,
        string info2 = "", string btnText = "", int moneyCnt = 0, int type = 0)
    {
Main/System/Tip/FuncRuleWin.cs
@@ -7,8 +7,8 @@
{
    [SerializeField] Text m_Title;
    [SerializeField] Text m_RuleTxt;
    [SerializeField] RectTransform scrollRect;
    [SerializeField] float maxHeight = 800f; // 设置最大高度限制
    // [SerializeField] RectTransform scrollRect;
    // [SerializeField] float maxHeight = 800f; // 设置最大高度限制
    #region Built-in
@@ -25,12 +25,12 @@
    }
    //打开后固定文本,不会动态变化
    protected override void NextFrameAfterOpen()
    {
        Vector2 newSizeDelta = scrollRect.sizeDelta;
        newSizeDelta.y = Mathf.Min(newSizeDelta.y, maxHeight); // 限制最大高度
        scrollRect.sizeDelta = newSizeDelta;
    }
    // protected override void NextFrameAfterOpen()
    // {
    //     Vector2 newSizeDelta = scrollRect.sizeDelta;
    //     newSizeDelta.y = Mathf.Min(newSizeDelta.y, maxHeight); // 限制最大高度
    //     scrollRect.sizeDelta = newSizeDelta;
    // }
    #endregion
Main/System/Tip/ItemsConfirmCell.cs
@@ -9,7 +9,7 @@
    public void Display(int index)
    {
        int itemID = ConfirmCancel.getItems[index].id;
        itemCell.Init(new ItemCellModel(itemID, false, (ulong)ConfirmCancel.getItems[index].countEx));
        itemCell.Init(new ItemCellModel(itemID, false, ConfirmCancel.getItems[index].countEx));
        itemCell.button.SetListener(() =>
        {
            ItemTipUtility.Show(itemID);
Main/System/Tip/ItemsConfirmWin.cs
@@ -33,7 +33,15 @@
    {
        m_Title.text = ConfirmCancel.generalTitle;
        m_Info.text = ConfirmCancel.generalItemTip;
        m_Info2.text = ConfirmCancel.generalItemTip2;
        if (string.IsNullOrEmpty(ConfirmCancel.generalItemTip2))
        {
            m_Info2.SetActive(false);
        }
        else
        {
            m_Info2.SetActive(true);
            m_Info2.text = ConfirmCancel.generalItemTip2;
        }
        m_Scroller.OnRefreshCell += OnRefreshCell;
        CreateScroller();
        m_BtnText.text = string.IsNullOrEmpty(ConfirmCancel.OKName) ? Language.Get("L1001") : ConfirmCancel.OKName;
@@ -44,7 +52,7 @@
        else
        {
            moneyObj.SetActive(true);
            moneyText.text = UIHelper.ShowUseMoney(ConfirmCancel.moneyType, (ulong)ConfirmCancel.moneyNeedCount);
            moneyText.text = UIHelper.ShowUseMoney(ConfirmCancel.moneyType, ConfirmCancel.moneyNeedCount);
            moneyIcon.SetIconWithMoneyType(ConfirmCancel.moneyType);
        }
    }
@@ -61,6 +69,7 @@
    private void ConfirmBtn()
    {
        ConfirmCancel.OnPopConfirmClickEvent?.Invoke(true);
        CloseWindow();
    }
Main/System/Tip/ScrollTip.cs
@@ -2,114 +2,130 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
    public class ScrollTip
public class ScrollTip
{
    public static List<SystemHintData> m_Hints = new List<SystemHintData>();
    public static List<ScrollTipDetail> m_ActiveTips = new List<ScrollTipDetail>();
    private static GameObjectPoolManager.GameObjectPool pool = null;
    private static bool inited = false;
    public static float tipMoveTime = 0.2f;
    public static event Action OnTipReceiveEvent;
    public static void ShowTip(string tip, ArrayList infoList = null, int _order = 0)
    {
        public static List<SystemHintData> m_Hints = new List<SystemHintData>();
        public static List<ScrollTipDetail> m_ActiveTips = new List<ScrollTipDetail>();
        private static GameObjectPoolManager.GameObjectPool pool = null;
        private static bool inited = false;
        public static float tipMoveTime = 0.2f;
        public static event Action OnTipReceiveEvent;
        public static void ShowTip(string tip, ArrayList infoList = null, int _order = 0)
        int range = Math.Min(m_Hints.Count, 10);
        int findCnt = 0;
        for (int i = 1; i <= range; i++)
        {
            int range = Math.Min(m_Hints.Count, 10);
            int findCnt = 0;
            for (int i = 1; i <= range; i++)
            if (m_Hints[m_Hints.Count - i].message == tip)
            {
                if (m_Hints[m_Hints.Count - i].message == tip)
                findCnt++;
                if (findCnt == 3)
                {
                    findCnt++;
                    if (findCnt == 3)
                    {
                        //列表内重复提示最多3次
                        return;
                    }
                    //列表内重复提示最多3次
                    return;
                }
            }
            m_Hints.Add(new SystemHintData()
            {
                message = tip,
                extentionData = infoList == null ? infoList : new ArrayList(infoList),
                appendTime = DateTime.Now,
                order = _order
            });
            //m_Hints.Sort(SysNotifyMgr.Instance.Compare);
            if (OnTipReceiveEvent != null)
            {
                OnTipReceiveEvent();
            }
            if (!UIManager.Instance.IsOpened<ScrollTipWin>())
            {
                UIManager.Instance.OpenWindow<ScrollTipWin>();
            }
        }
        public static ScrollTipDetail Request()
        m_Hints.Add(new SystemHintData()
        {
            ScrollTipDetail tip = null;
            if (pool == null)
            {
                var _prefab = UILoader.LoadPrefab("Tip");
                pool = GameObjectPoolManager.Instance.RequestPool(_prefab);
            }
            if (pool != null)
            {
                tip = pool.Request().AddMissingComponent<ScrollTipDetail>();
            }
            return tip;
            message = tip,
            extentionData = infoList == null ? infoList : new ArrayList(infoList),
            appendTime = DateTime.Now,
            order = _order
        });
        //m_Hints.Sort(SysNotifyMgr.Instance.Compare);
        if (OnTipReceiveEvent != null)
        {
            OnTipReceiveEvent();
        }
        //过滤不播放的情况
        if (!CanOpen())
        {
            return;
        }
        public static void Release(ScrollTipDetail tip, bool next = true)
        if (!UIManager.Instance.IsOpened<ScrollTipWin>())
        {
            if (m_ActiveTips.Contains(tip))
            {
                tip.presentState = ScrollTipState.None;
                m_ActiveTips.Remove(tip);
            }
            if (tip.gameObject != null && pool != null)
            {
                pool.Release(tip.gameObject);
            }
            if (m_ActiveTips.Count > 0 && next)
            {
                m_ActiveTips[0].Play(ScrollTipState.Hide);
            }
        }
        public static void ReleaseAll()
        {
            for (int i = 0; i < m_ActiveTips.Count; i++)
            {
                Release(m_ActiveTips[i]);
                i--;
            }
        }
        public static void OnTipComplete()
        {
            if (OnTipReceiveEvent != null) OnTipReceiveEvent();
        }
        public static void Close()
        {
            m_Hints.Clear();
        }
        public enum ScrollTipState
        {
            None,
            Idle,
            Move,
            Hide
            UIManager.Instance.OpenWindow<ScrollTipWin>();
        }
    }
    static bool CanOpen()
    {
        // if (UIManager.Instance.IsOpened<HeroCallResultWin>())
        // {
        //     return false;
        // }
        if (HappyXBModel.Instance.isXBCoolTime)
            return false;
        return true;
    }
    public static ScrollTipDetail Request()
    {
        ScrollTipDetail tip = null;
        if (pool == null)
        {
            var _prefab = UILoader.LoadPrefab("Tip");
            pool = GameObjectPoolManager.Instance.RequestPool(_prefab);
        }
        if (pool != null)
        {
            tip = pool.Request().AddMissingComponent<ScrollTipDetail>();
        }
        return tip;
    }
    public static void Release(ScrollTipDetail tip, bool next = true)
    {
        if (m_ActiveTips.Contains(tip))
        {
            tip.presentState = ScrollTipState.None;
            m_ActiveTips.Remove(tip);
        }
        if (tip.gameObject != null && pool != null)
        {
            pool.Release(tip.gameObject);
        }
        if (m_ActiveTips.Count > 0 && next)
        {
            m_ActiveTips[0].Play(ScrollTipState.Hide);
        }
    }
    public static void ReleaseAll()
    {
        for (int i = 0; i < m_ActiveTips.Count; i++)
        {
            Release(m_ActiveTips[i]);
            i--;
        }
    }
    public static void OnTipComplete()
    {
        if (OnTipReceiveEvent != null) OnTipReceiveEvent();
    }
    public static void Close()
    {
        m_Hints.Clear();
    }
    public enum ScrollTipState
    {
        None,
        Idle,
        Move,
        Hide
    }
}
Main/Utility/CommonFunc.cs
@@ -4,9 +4,9 @@
public class CommonFunc
{
    public static Dictionary<int, ulong> AddDict(Dictionary<int, ulong> dic1, Dictionary<int, ulong> dic2)
    public static Dictionary<int, long> AddDict(Dictionary<int, long> dic1, Dictionary<int, long> dic2)
    {
        var resultDic = new Dictionary<int, ulong>(dic1);
        var resultDic = new Dictionary<int, long>(dic1);
        foreach (var data in dic2)
        {
            if (resultDic.ContainsKey(data.Key))
@@ -21,7 +21,7 @@
    public static List<Item> ChangeToItemList(Dictionary<int, ulong> dict)
    public static List<Item> ChangeToItemList(Dictionary<int, long> dict)
    {
        List<Item> itemlist = new List<Item>();
        if (dict == null)
Main/Utility/Constants.cs
@@ -38,7 +38,7 @@
    public const float F_EPSILON = 0.00001f;
    //服务端的大数值通过两个字段表示,大数字位单位为亿
    public const ulong ExpPointValue = 100000000;
    public const long ExpPointValue = 100000000;
    public static readonly Vector3 Special_Hide_Position = new Vector3(10000, -10000, 10000);
    public readonly static Vector2 DESIGN_RESOLUTION = new Vector2(750, 1334);
Main/Utility/EnumHelper.cs
@@ -697,7 +697,7 @@
    default30,
    default31,
    default32,
    default33,  // 261 结晶
    default33,  // 261 玉髓
    default34,  // 262 凭证积分
    default35,  // 263 聚魂精华
    default36,  // 264 Boss最终伤害加成
@@ -862,7 +862,7 @@
    SkillTreasure = 95,//技能法宝
    WingCompose = 97,//翅膀合成
    Demon = 98,//混乱妖域
    HappyFindTreasure = 99,//欢乐寻宝
    HappyFindTreasure = 99,// 英雄招募
    FightPromote = 100,//战力提升
    AncientBattleGround = 101,//上古战场
    Chat = 102,//聊天
@@ -1084,7 +1084,7 @@
    Green = 9,//绿色
    Black = 10,
    /// <summary>
    /// 深绿色 109d06 (16, 157, 6, 255)
    /// 深绿色 248B12 (36, 187, 18, 255)
    /// </summary>
    DarkGreen = 12,
    NavyYellow = 13,
@@ -1924,8 +1924,7 @@
    MJXB = 2,   //秘境寻宝
    GatherSoulXB = 3,   //聚魂寻宝
    TreasurePavilion = 4,   //古宝寻宝
    BestXB = 5,   //极品寻宝
    RuneXB = 6,   //符文寻宝
    HeroCall = 5,   //英雄招募
}
//查询其他玩家数据 用途类型
Main/Utility/TimeUtility.cs
@@ -172,62 +172,62 @@
    //     Debug.LogFormat("CreateRoleTime {0}  CreateDays {1}", createRoleTimeTail, CreateDays);
    // }
    public static event Action OnServerTimeRefresh;
    public static void OnRefreshServerTime(HA004_tagServerDateTime vNetData)
    {
        var dateTime = new DateTime(vNetData.Year, vNetData.Month, vNetData.Day, vNetData.Hour, vNetData.Minute, vNetData.Second);
        s_ServerTime = dateTime;
        _checkTime = Time.realtimeSinceStartup;
        if (OnServerTimeRefresh != null)
        {
            OnServerTimeRefresh();
        }
        s_CrossServerTime = Convert.ToDateTime(vNetData.CrossServerTime);
        _crossCheckTime = Time.realtimeSinceStartup;
        TimeDownMgr.Instance.Begin(TimeDownMgr.CoolTimeType.SyncServerTime, 60, (float tick) =>
        {
            SyncServerTime();
        }, 60);
    public static event Action OnServerTimeRefresh;
    public static void OnRefreshServerTime(HA004_tagServerDateTime vNetData)
    {
        var dateTime = new DateTime(vNetData.Year, vNetData.Month, vNetData.Day, vNetData.Hour, vNetData.Minute, vNetData.Second);
        s_ServerTime = dateTime;
        _checkTime = Time.realtimeSinceStartup;
        if (OnServerTimeRefresh != null)
        {
            OnServerTimeRefresh();
        }
        s_CrossServerTime = Convert.ToDateTime(vNetData.CrossServerTime);
        _crossCheckTime = Time.realtimeSinceStartup;
        TimeDownMgr.Instance.Begin(TimeDownMgr.CoolTimeType.SyncServerTime, 60, (float tick) =>
        {
            SyncServerTime();
        }, 60);
    }
    public static event Action OnServerOpenDayRefresh;
    public static void OnRefreshServerOpenDay(HA005_tagOpenServerDay package)
    {
        {
            OpenDay = package.Day;
            IsMixServer = package.IsMixServer == 1;
            MixOpenDay = package.MixDay;
            openServerDayOfWeek = package.OpenWeekday == 7 ? DayOfWeek.Sunday : (DayOfWeek)package.OpenWeekday;
            WeekOfYear = package.WeekOfYear;
        }
        OnRefreshServerTime(new HA004_tagServerDateTime()
        {
            Year = package.NowYear,
            Month = package.NowMonth,
            Day = package.NowDay,
            Hour = package.NowHour,
            Minute = package.NowMinute,
            Second = package.NowSecond,
            MicSecond = package.NowMicSecond,
            socketType = package.socketType,
        });
        if (OnServerOpenDayRefresh != null)
        {
            OnServerOpenDayRefresh();
        }
    }
    public static void SyncServerTime()
    {
        CA002_tagClientRequestServerTime pak = new CA002_tagClientRequestServerTime();
        GameNetSystem.Instance.SendInfo(pak);
    public static event Action OnServerOpenDayRefresh;
    public static void OnRefreshServerOpenDay(HA005_tagOpenServerDay package)
    {
        {
            OpenDay = package.Day;
            IsMixServer = package.IsMixServer == 1;
            MixOpenDay = package.MixDay;
            openServerDayOfWeek = package.OpenWeekday == 7 ? DayOfWeek.Sunday : (DayOfWeek)package.OpenWeekday;
            WeekOfYear = package.WeekOfYear;
        }
        OnRefreshServerTime(new HA004_tagServerDateTime()
        {
            Year = package.NowYear,
            Month = package.NowMonth,
            Day = package.NowDay,
            Hour = package.NowHour,
            Minute = package.NowMinute,
            Second = package.NowSecond,
            MicSecond = package.NowMicSecond,
            socketType = package.socketType,
        });
        if (OnServerOpenDayRefresh != null)
        {
            OnServerOpenDayRefresh();
        }
    }
    public static void SyncServerTime()
    {
        CA002_tagClientRequestServerTime pak = new CA002_tagClientRequestServerTime();
        GameNetSystem.Instance.SendInfo(pak);
    }
    /// <summary>
@@ -394,6 +394,16 @@
    }
    /// <summary>
    /// 获取当天的24点时间
    /// </summary>
    /// <returns></returns>
    public static DateTime GetTodayEndTime()
    {
        var now = ServerNow.AddDays(1);
        return new DateTime(now.Year, now.Month, now.Day);
    }
    /// <summary>
    /// 获取下一个凌晨5点的时间
    /// </summary>
    /// <returns></returns>
@@ -427,4 +437,10 @@
        return (ServerNow - startTime).Days;
    }
    //今日剩余秒数
    public static int GetTodayRemainSeconds()
    {
        return (int)(GetTodayEndTime() - ServerNow).TotalSeconds;
    }
}
Main/Utility/UIHelper.cs
@@ -178,166 +178,7 @@
        else if (span.TotalMinutes > 1) return Math.Floor(span.TotalMinutes) + Language.Get("L1073");
        else return 1 + Language.Get("L1073");
    }
    /// <summary>
    /// 根据属性获取玩家数据
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static ulong GetPropertyValue(PropertyType type)
    {
        switch (type)
        {
            case PropertyType.LV:
                return PlayerDatas.Instance.baseData.LV;
            case PropertyType.POWER:
                return (ulong)PlayerDatas.Instance.baseData.STR;
            case PropertyType.AGILITY:
                return (ulong)PlayerDatas.Instance.baseData.PHY;
            case PropertyType.PHYSIQUE:
                return (ulong)PlayerDatas.Instance.baseData.CON;
            case PropertyType.MENTALITY:
                return (ulong)PlayerDatas.Instance.baseData.PNE;
            case PropertyType.HP:
                return PlayerDatas.Instance.extersion.MaxHP;
            case PropertyType.ATK:
                return (ulong)PlayerDatas.Instance.extersion.MAXATK;
            case PropertyType.DEF:
                return (ulong)PlayerDatas.Instance.extersion.DEF;
            case PropertyType.HIT:
                return (ulong)PlayerDatas.Instance.extersion.HIT;
            case PropertyType.MISS:
                return (ulong)PlayerDatas.Instance.extersion.Miss;
            case PropertyType.ATKSPEED:
                return (ulong)PlayerDatas.Instance.extersion.battleValEx1;
            case PropertyType.CritChance:
                return (ulong)PlayerDatas.Instance.extersion.SuperHitRate;
            case PropertyType.CritHurt:
                return (ulong)PlayerDatas.Instance.extersion.SuperHit;
            case PropertyType.CritResis:
                return (ulong)PlayerDatas.Instance.extersion.SuperHitReduce;
            case PropertyType.HeartHit:
                return (ulong)PlayerDatas.Instance.extersion.luckHitRate;
            case PropertyType.HeartHurt:
                return (ulong)PlayerDatas.Instance.extersion.luckHitVal;
            case PropertyType.HeartResis:
                return (ulong)PlayerDatas.Instance.extersion.LuckyHitRateReduce;
            case PropertyType.SkillHurt:
                return (ulong)PlayerDatas.Instance.extersion.SkillAtkRate;
            case PropertyType.PVPAddHurt:
                return (ulong)PlayerDatas.Instance.extersion.DamagePVP;
            case PropertyType.PVPReduceHurt:
                return PlayerDatas.Instance.GetPlayerDataByType((PlayerDataType)191);
            case PropertyType.LifeReply:
                return (ulong)PlayerDatas.Instance.extersion.HPRestorePer;
            case PropertyType.HurtReflect:
                return (ulong)PlayerDatas.Instance.extersion.DamageBackRate;
            case PropertyType.MoveSpeed:
                return (ulong)PlayerDatas.Instance.extersion.SpeedValue;
            case PropertyType.PetAddHurt:
                return (ulong)PlayerDatas.Instance.extersion.PetDamPer;
            case PropertyType.RealHurt:
                return (ulong)PlayerDatas.Instance.extersion.realATK;
            case PropertyType.RealResis:
                return (ulong)PlayerDatas.Instance.extersion.realDEF;
            case PropertyType.DefyDef:
                return (ulong)PlayerDatas.Instance.extersion.IgnoreDefRate;
            case PropertyType.DefyDefResis:
                return (ulong)PlayerDatas.Instance.extersion.IgnoreDefRateReduce;
            case PropertyType.DefChance:
                return (ulong)PlayerDatas.Instance.extersion.DamChanceDef;
            case PropertyType.BloodHurt:
                return (ulong)PlayerDatas.Instance.extersion.BleedDamage;
            case PropertyType.AktReplyBlood:
                return (ulong)PlayerDatas.Instance.extersion.BattleValEx2;
            case PropertyType.Stun:
                return (ulong)PlayerDatas.Instance.extersion.FaintRate;
            case PropertyType.CtrlResis:
                return (ulong)PlayerDatas.Instance.extersion.FaintDefRate;
            case PropertyType.AddFinalHurt:
                return (ulong)PlayerDatas.Instance.extersion.FinalHurt;
            case PropertyType.ReduceFinalHurt:
                return (ulong)PlayerDatas.Instance.extersion.FinalHurtReduce;
            case PropertyType.PVPAddHurtPer:
                return (ulong)PlayerDatas.Instance.extersion.DamagePerPVP;
            case PropertyType.PVPReduceHurtPer:
                return (ulong)PlayerDatas.Instance.extersion.DamagePerPVPReduce;
            case PropertyType.DleHitChance:
                return (ulong)PlayerDatas.Instance.extersion.ComboDamPerRate;
            case PropertyType.DleHurt:
                return (ulong)PlayerDatas.Instance.extersion.ComboDamPer;
            case PropertyType.ReduceSkillHurtPercent:
                return (ulong)PlayerDatas.Instance.extersion.skillAtkRateReduce;
            case PropertyType.NpcHurtAddPer:
                return (ulong)PlayerDatas.Instance.extersion.NpcHurtAddPer;
            case PropertyType.Luck:
                return (ulong)PlayerDatas.Instance.extersion.luckValue;
            case PropertyType.Mater:
                return (ulong)PlayerDatas.Instance.baseData.mater;
            case PropertyType.Wood:
                return (ulong)PlayerDatas.Instance.baseData.wood;
            case PropertyType.Water:
                return (ulong)PlayerDatas.Instance.baseData.water;
            case PropertyType.Fire:
                return (ulong)PlayerDatas.Instance.baseData.fire;
            case PropertyType.Earth:
                return (ulong)PlayerDatas.Instance.baseData.earth;
            case PropertyType.ReduceCrit:
                return (ulong)PlayerDatas.Instance.baseData.reduceCrit;
            case PropertyType.ReduceHeartHurtPer:
                return (ulong)PlayerDatas.Instance.baseData.reduceHeartHurt;
            case PropertyType.ReduceFinalHurtPer:
                return (ulong)PlayerDatas.Instance.baseData.reduceFinalHurt;
            case PropertyType.AtkPercent:
            case PropertyType.CritHurtPercent:
            case PropertyType.DodgePercent:
                // return (ulong)ModelCenter.Instance.GetModel<ReikiRootModel>().GetReikiPropertyValue((int)type);
                // TODO YYL
                return 0ul;
            case PropertyType.SkillAddPerA:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerA;
            case PropertyType.SkillAddPerB:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerB;
            case PropertyType.SkillAddPerC:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerC;
            case PropertyType.SkillAddPerD:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerD;
            case PropertyType.SkillAddPerE:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerE;
            case PropertyType.SkillAddPerF:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerF;
            case PropertyType.SkillAddPerG:
                return (ulong)PlayerDatas.Instance.baseData.skillAddPerG;
            case PropertyType.SkillReducePerA:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerA;
            case PropertyType.SkillReducePerB:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerB;
            case PropertyType.SkillReducePerC:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerC;
            case PropertyType.SkillReducePerD:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerD;
            case PropertyType.SkillReducePerE:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerE;
            case PropertyType.SkillReducePerF:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerF;
            case PropertyType.SkillReducePerG:
                return (ulong)PlayerDatas.Instance.baseData.skillReducePerG;
            case PropertyType.ReduceSkillCDPer:
                return (ulong)PlayerDatas.Instance.extersion.battleValEx3;
            case PropertyType.AddFinalHurtPer:
                return (ulong)PlayerDatas.Instance.extersion.FunalHurtPer;
            case PropertyType.AddNormalHurt:
                return (ulong)PlayerDatas.Instance.baseData.NormalHurt;
            case PropertyType.AddNormalHurtPer:
                return (ulong)PlayerDatas.Instance.baseData.NormalHurtPer;
            case PropertyType.AddSkillHurt:
                return (ulong)PlayerDatas.Instance.baseData.FabaoHurt;
            case PropertyType.AddSkillHurtPer:
                return (ulong)PlayerDatas.Instance.baseData.FabaoHurtPer;
            case PropertyType.AddPVEHurt:
                return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.DamagePVE);
        }
        return 0;
    }
    /// <summary>
@@ -854,11 +695,11 @@
            case TextColType.Pink:
                return StringUtility.Contact("<color=#", bright ? "f6408d" : "ff7c7c", ">", msg, "</color>");
            case TextColType.Green:
                return StringUtility.Contact("<color=#", bright ? "109d06" : "2ae337", ">", msg, "</color>");
                return StringUtility.Contact("<color=#", bright ? "248B12" : "2ae337", ">", msg, "</color>");
            case TextColType.NavyBrown:
                return StringUtility.Contact("<color=#6e4c31>", msg, "</color>");
            case TextColType.DarkGreen:
                return StringUtility.Contact("<color=#109d06>", msg, "</color>");
                return StringUtility.Contact("<color=#248B12>", msg, "</color>");
            case TextColType.Black:
                return StringUtility.Contact("<color=#000000>", msg, "</color>");
            case TextColType.LightWhite:
@@ -1083,8 +924,18 @@
        return 0;
    }
    //货币对应0418类型
    public static Dictionary<int, PlayerDataType> moneyTypeToPlayerDataType = new Dictionary<int, PlayerDataType>()
    {
        {1, PlayerDataType.Gold},
        {2, PlayerDataType.GoldPaper},
        {3, PlayerDataType.Silver},
        {41, PlayerDataType.default26},
        {42, PlayerDataType.default33},
    public static ulong GetMoneyCnt(int moneyType)
    };
    public static long GetMoneyCnt(int moneyType)
    {
        switch (moneyType)
        {
@@ -1102,7 +953,7 @@
                }
            case 18:
                {
                    return (ulong)PlayerDatas.Instance.extersion.honorValue;
                    return PlayerDatas.Instance.extersion.honorValue;
                }
            case 25:
                {
@@ -1111,7 +962,7 @@
                }
            case 24:
                {
                    return (ulong)PlayerDatas.Instance.extersion.runeChip;
                    return PlayerDatas.Instance.extersion.runeChip;
                }
            case 15:
                {
@@ -1232,21 +1083,22 @@
        return 0;
    }
    public static int GetAllVourcher()
    {
        return (int)GetMoneyCnt(98) + (int)GetMoneyCnt(99);
    }
    //显示数量, 格式n/m, 足够绿色不足红色
    public static string ShowUseMoney(int moneyType, ulong useCnt, TextColType engoughColor = TextColType.Green)
    public static string ShowUseMoney(int moneyType, long useCnt, TextColType engoughColor = TextColType.Green)
    {
        ulong cnt = GetMoneyCnt(moneyType);
        long cnt = GetMoneyCnt(moneyType);
        return AppendColor(useCnt <= cnt ? engoughColor : TextColType.Red, $"{ReplaceLargeNum(useCnt)}/{ReplaceLargeNum(cnt)}");
    }
    public static string ShowUseItem(PackType type, int itemId, ulong useCnt, TextColType engoughColor = TextColType.Green)
    public static string ShowUseItem(PackType type, int itemId, long useCnt, TextColType engoughColor = TextColType.Green)
    {
        ulong cnt = PackManager.Instance.GetItemCountByID(type, itemId);
        long cnt = PackManager.Instance.GetItemCountByID(type, itemId);
        return AppendColor(useCnt <= cnt ? engoughColor : TextColType.Red, $"{ReplaceLargeNum(useCnt)}/{ReplaceLargeNum(cnt)}");
    }