hch
6 天以前 303f5970d2bef26905c9d6d471cd13f41bc722a7
155 子 【武将】招募系统 - 高级招募
27个文件已修改
1个文件已删除
5 文件已复制
6个文件已添加
1 文件已重命名
2884 ■■■■ 已修改文件
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/Configs/EffectConfig.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/FightPowerRatioConfig.cs 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/FuncOpenLVConfig.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/SkillConfig.cs 367 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/XBGetItemConfig.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HappyXBModel.cs 861 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultCell.cs 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallWin.cs 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroConfigUtility.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Awake.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Break.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroManager.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/UIHeroController.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBaseWin.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroScenePosCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnItemCell.cs 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnItemCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnMoneyCell.cs 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/OwnMoneyCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FightPowerManager.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/MainWin.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Message/ColorAnalysis.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreModel.cs 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ScrollTip.cs 208 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/EnumHelper.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/TimeUtility.cs 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/BattleEffectPlayer.cs
@@ -231,7 +231,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)
        {
            PlayAsync(false).Forget();
        }
        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 = 1f;
            // 检查动画是否有相加模式
            // 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
File was renamed from Main/System/Hero/HeroConfigUtility.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0e5888e0c25bbc48bbf6aa354fad7b2
guid: fdbe400d15c065042a16a05cd09dd322
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
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/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/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -108,6 +108,7 @@
        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));
    }
    //主工程注册封包
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,40 @@
            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 = XBCostTypeDict[xbType];
            int xbOneMoney = funcSet.xbPrices[0];
            //货币寻宝
            int moneyType = funcSet.CostMoneyType;
            int xbOneMoney = funcSet.CostMoneyList[0];
            if (UIHelper.GetMoneyCnt(moneyType) >= (ulong)xbOneMoney)
            {
                StoreModel.Instance.UseMoneyCheck(xbOneMoney, () =>
                StoreModel.Instance.UseMoneyCheck(xbOneMoney, moneyType, () =>
                {
                    SendXBQuest(xbType, 0, 0);
                }, xbType == 1 ? 5 : 6, fullTip: Language.Get("TreasurePavilion08", xbOneMoney, moneyType, funcSet.costToolIds[0], 1));
                }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, xbOneMoney,
                UIHelper.GetIconNameWithMoneyType(moneyType), funcSet.CostItemCountList[0]));
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
                ItemTipUtility.Show(GeneralDefine.MoneyDisplayModel[moneyType], true);
            }
        }
    }
    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 +335,61 @@
            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) >= (ulong)needMoney)
            {
                StoreModel.Instance.UseMoneyCheck(xbManyMoney, () =>
                StoreModel.Instance.UseMoneyCheck(needMoney, moneyType, () =>
                {
                    //只要有道具就是道具寻宝,不足部分服务端扣货币
                    SendXBQuest(xbType, 1, toolCnt > 0 ? 2 : 0);
                }, xbType == 1 ? 5 : 6, fullTip: Language.Get("TreasurePavilion08", xbManyMoney, moneyType, funcSet.costToolIds[1], needToolCnt - toolCnt));
                }, (int)BuyStoreItemCheckType.HeroCall, fullTip: Language.Get("CostMoneyForItem", funcSet.CostItemID, needMoney,
                UIHelper.GetIconNameWithMoneyType(moneyType), needToolCnt - toolCnt));
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("LackMoney", moneyType);
                ItemTipUtility.Show(GeneralDefine.MoneyDisplayModel[moneyType], true);
            }
        }
    }
    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 +397,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 +409,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,238 +417,105 @@
        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)
    {
        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++)
        {
            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;
                }
            }
        }
        xbStoreRed.state = RedPointState.None;
    }
    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
}
@@ -1026,17 +530,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 +538,6 @@
    public int itemId;
    public int count;
    public DateTime createTime;
    public string createTimeStr;
    public void SetModel(int index, int id, int count)
    {
@@ -1052,7 +545,6 @@
        this.itemId = id;
        this.count = count;
        createTime = TimeUtility.ServerNow;
        createTimeStr = TimeUtility.ServerNow.ToString("yyyy-MM-dd HH:mm:ss");
    }
}
@@ -1067,6 +559,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) ? 0 : 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,266 @@
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();
        Display();
    }
    protected override void OnPreClose()
    {
        HappyXBModel.Instance.RefreshXBResultAct -= UpdateState;
        HappyXBModel.Instance.RefreshXBTypeInfoAct -= RefreshBtn;
    }
    void Display()
    {
        // RefreshState();
        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(true);
            call10Btn.SetActive(false);
            result1Obj.SetActive(true);
            result10Obj.SetActive(false);
            result10LihuiObj.SetActive(false);
            moneyObj.SetActive(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);
            moneyObj.SetActive(true);
            heroInfoObj.SetActive(false);
            if (isSkip)
                Refresh10Result();
        }
        else if (resultState == 2)
        {
            btnsObj.SetActive(false);
            result1Obj.SetActive(false);
            result10Obj.SetActive(true);
            result10LihuiObj.SetActive(false);
            moneyObj.SetActive(false);
            heroInfoObj.SetActive(false);
            Refresh10Result();
        }
        else if (resultState == 3)
        {
            btnsObj.SetActive(false);
            result1Obj.SetActive(false);
            result10Obj.SetActive(false);
            result10LihuiObj.SetActive(true);
            moneyObj.SetActive(false);
            heroInfoObj.SetActive(true);
            RefreshLihui();
        }
    }
    public void RefreshBtn()
    {
        var funcSet = TreasureSetConfig.Get((int)HeroUIManager.Instance.selectCallType);
        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 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()
    {
        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/HeroCallWin.cs
New file
@@ -0,0 +1,118 @@
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);
        });
    }
    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]);
        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/Hero/HeroConfigUtility.cs
File was deleted
Main/System/Hero/HeroInfo.Awake.cs
@@ -52,7 +52,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] = tmpAwakeConfig.SkillID;
Main/System/Hero/HeroInfo.Break.cs
@@ -52,7 +52,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/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,12 @@
        { 
            skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
        }
        if (skeletonGraphic.skeletonDataAsset == null)
        {
            this.SetActive(false);
            Debug.LogError("未配置spine");
            return;
        }
        skeletonGraphic.Initialize(true);
        this.transform.localScale = Vector3.one * scale;
        spineAnimationState = skeletonGraphic.AnimationState;
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/HeroScenePosCell.cs
@@ -29,7 +29,7 @@
        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);
Main/System/HeroUI/HeroTrainWin.cs
@@ -135,7 +135,7 @@
    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);
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.cs
@@ -16,6 +16,9 @@
    public WaitHeroFuncResponse waitResponse;    //请求武将功能,与服务端交互
    public const float lihuiScale = 0.6f;   //立绘缩放大小
    public override void Init()
    {
@@ -203,10 +206,42 @@
    }
    #region 招募
    public HappXBTitle selectCallType;  //寻宝枚举类型
    public int selectCallIndex;//0:1抽 1:10抽 对应配置顺序
    public const string skipKey = "SkipHeroCall";
    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;
    }
    #endregion
}
public struct WaitHeroFuncResponse
Main/System/ItemTip/OwnItemCell.cs
New file
@@ -0,0 +1,57 @@
using UnityEngine;
using UnityEngine.UI;
//拥有的物品:数量显示,点击按钮显示途径tip
public class OwnItemCell : MonoBehaviour
{
    [SerializeField] Image itemIcon;
    [SerializeField] Text numText;
    [SerializeField] Button wayBtn;
    public int itemID;
    void Start()
    {
        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,75 @@
using UnityEngine;
using UnityEngine.UI;
//拥有的货币:数量显示,点击按钮打开对应获取界面
public class OwnMoneyCell : MonoBehaviour
{
    [SerializeField] Image moneyIcon;
    [SerializeField] Text numText;
    [SerializeField] Button wayBtn;
    public int moneyType;
    void Start()
    {
        moneyIcon.SetIconWithMoneyType(moneyType);
        if (wayBtn != null)
        {
            wayBtn.AddListener(()=>
            {
                switch (moneyType)
                {
                    // case 1:
                    //     {
                    //         //UIManager.Instance.OpenWindow<RechargeWin>();
                    //     }
                    //     break;
                    default:
                        {
                            if (GeneralDefine.MoneyDisplayModel.ContainsKey(moneyType))
                            {
                                ItemTipUtility.Show(GeneralDefine.MoneyDisplayModel[moneyType], true);
                            }
                        }
                        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/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);
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/Message/ColorAnalysis.cs
@@ -39,7 +39,7 @@
        }
        // switch (_value.ToLower())
        // {
        //     case "109d06":
        //     case "248B12":
        //         return "35e122";
        //     case "ff6701":
        //         return "f8983b";
Main/System/Store/StoreModel.cs
@@ -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;
                }
            });
Main/System/Tip/ScrollTip.cs
@@ -2,114 +2,128 @@
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;
        }
        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/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
@@ -854,11 +854,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,6 +1083,16 @@
        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)
    {
@@ -1232,6 +1242,7 @@
        return 0;
    }
    public static int GetAllVourcher()
    {
        return (int)GetMoneyCnt(98) + (int)GetMoneyCnt(99);