hch
6 天以前 ee3196b5a04c15d025d1a9eab825d5d14987758d
286 【常规】坊市系统; 调整布阵界面对应引导
25个文件已修改
16个文件已删除
10 文件已复制
12个文件已添加
2 文件已重命名
3206 ■■■■■ 已修改文件
Main/Component/UI/Common/GroupButtonEx.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/SliderPanel.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/StoreConfig.cs 102 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA201_tagCMQueryNPCShopItem.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA201_tagCMQueryNPCShopItem.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCMRefreshMysticalShop.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCMRefreshMysticalShop.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCSRefreshShop.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCSRefreshShop.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCMBuyItem.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCMBuyItem.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCSBuyItem.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCSBuyItem.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagMCShopItemDayBuyCntInfo.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagMCShopItemDayBuyCntInfo.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagSCShopItemBuyCntInfo.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagSCShopItemBuyCntInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA803_tagSCShopRefreshItemInfo.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA803_tagSCShopRefreshItemInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA811_tagMCShoppingResult.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA811_tagMCShoppingResult.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/H01_System/H0102_tagCDBPlayer.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagSCShopItemBuyCntInfo.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagSCShopItemBuyCntInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA803_tagSCShopRefreshItemInfo.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA803_tagSCShopRefreshItemInfo.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA811_tagMCShoppingResult.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA811_tagMCShoppingResult.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Manager/UIManager.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaAwardWin.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/BuyItemWin.cs 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/FirstCharge/FirstChargeWin.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildBaseWin.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildHawkerWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Guild/GuildManager.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBaseWin.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ItemTipUtility.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Mail/MailWin.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FuncsBaseWin.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HomeWin.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/RightFuncInHome.cs 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/RightFuncInHome.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/MainRedDot.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/Redpoint.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/RedpointCenter.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/BuyItemController.cs 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/BuyItemController.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/BuyItemWin.cs 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/BuyItemWin.cs.meta 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreBaseWin.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreBaseWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreCell.cs 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreLineCell.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreLineCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreModel.cs 1485 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreWin.cs 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Store/StoreWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/UIBase/OneLevelWin.cs 191 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/ComponentExtersion.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/EnumHelper.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/GroupButtonEx.cs
@@ -78,6 +78,8 @@
        set { m_SelectEffect = value; }
    }
    [SerializeField] public RedpointBehaviour redpoint;   //外部自己用
    public bool isLock = false;
    protected override void Awake()
@@ -124,12 +126,19 @@
    // 更新按钮状态
    public void UpdateButtonState()
    {
        if (m_SelectIcon != null && m_UnSelectIcon != null && m_SelectIcon.sprite == m_UnSelectIcon.sprite)
        {
            m_SelectIcon.SetActive(true);
        }
        else
        {
        // 更新图标显示
        if (m_SelectIcon != null)
            m_SelectIcon.SetActive(m_State == TitleBtnState.Click);
        if (m_UnSelectIcon != null)
            m_UnSelectIcon.SetActive(m_State != TitleBtnState.Click);
        }
        // 更新文字颜色
        if (m_Title != null && m_Manager != null)
Main/Component/UI/Common/SliderPanel.cs
@@ -54,9 +54,9 @@
    {
        count = _count;
        maxCount = _maxCount;
        slider.minValue = 1;
        slider.maxValue = _maxCount;
        slider.value = count;
        slider.minValue = 0;
        slider.maxValue = _maxCount;
        Refresh();
        OnChangeEvent = _OnChangeEvent;
@@ -82,7 +82,7 @@
            maxBtn.SetColorful(null, true);
        }
        if (count <= 0)
        if (count <= 1)
        {
            decBtn.interactable = false;
            decBtn.SetColorful(null, false);
Main/Config/Configs/StoreConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年8月5日
//    [  Date ]:           2025年10月28日
//--------------------------------------------------------
using System.Collections.Generic;
@@ -18,27 +18,17 @@
    public int ID;
    public int ShopType;
    public int[] SecondType;
    public int ShopSort;
    public int ItemID;
    public int ItemCnt;
    public int IsBind;
    public string ItemListEx;
    public int MainItemID;
    public string JobItem;
    public int RefreshType;
    public int[] VIPLV;
    public int LV;
    public int LVSee;
    public int[] GoumaiNumber;
    public int[][] ItemListEx;
    public int ResetType;
    public int LimitCnt;
    public int MoneyType;
    public int MoneyNumber;
    public int MoneyNum;
    public int MoneyOriginal;
    public int LimitValue;
    public string SalesStatus;
    public int TheOnlyShop;
    public int RemindSuccess;
    public int IsHideSellOut;
    public int UnlockType;
    public int UnlockValue;
    public override int LoadKey(string _key)
    {
@@ -54,83 +44,27 @@
            int.TryParse(tables[1],out ShopType); 
            if (tables[2].Contains("["))
            {
                SecondType = JsonMapper.ToObject<int[]>(tables[2]);
            }
            else
            {
                string[] SecondTypeStringArray = tables[2].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                SecondType = new int[SecondTypeStringArray.Length];
                for (int i=0;i<SecondTypeStringArray.Length;i++)
                {
                     int.TryParse(SecondTypeStringArray[i],out SecondType[i]);
                }
            }
            int.TryParse(tables[2],out ShopSort);
            int.TryParse(tables[3],out ShopSort);
            int.TryParse(tables[3],out ItemID);
            int.TryParse(tables[4],out ItemID);
            int.TryParse(tables[4],out ItemCnt);
            int.TryParse(tables[5],out ItemCnt);
            ItemListEx = JsonMapper.ToObject<int[][]>(tables[5].Replace("(", "[").Replace(")", "]"));
            int.TryParse(tables[6],out IsBind);
            int.TryParse(tables[6],out ResetType);
            ItemListEx = tables[7];
            int.TryParse(tables[7],out LimitCnt);
            int.TryParse(tables[8],out MainItemID);
            int.TryParse(tables[8],out MoneyType);
            JobItem = tables[9];
            int.TryParse(tables[9],out MoneyNum);
            int.TryParse(tables[10],out RefreshType);
            int.TryParse(tables[10],out MoneyOriginal);
            if (tables[11].Contains("["))
            {
                VIPLV = JsonMapper.ToObject<int[]>(tables[11]);
            }
            else
            {
                string[] VIPLVStringArray = tables[11].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                VIPLV = new int[VIPLVStringArray.Length];
                for (int i=0;i<VIPLVStringArray.Length;i++)
                {
                     int.TryParse(VIPLVStringArray[i],out VIPLV[i]);
                }
            }
            int.TryParse(tables[11],out UnlockType);
            int.TryParse(tables[12],out LV);
            int.TryParse(tables[13],out LVSee);
            if (tables[14].Contains("["))
            {
                GoumaiNumber = JsonMapper.ToObject<int[]>(tables[14]);
            }
            else
            {
                string[] GoumaiNumberStringArray = tables[14].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                GoumaiNumber = new int[GoumaiNumberStringArray.Length];
                for (int i=0;i<GoumaiNumberStringArray.Length;i++)
                {
                     int.TryParse(GoumaiNumberStringArray[i],out GoumaiNumber[i]);
                }
            }
            int.TryParse(tables[15],out MoneyType);
            int.TryParse(tables[16],out MoneyNumber);
            int.TryParse(tables[17],out MoneyOriginal);
            int.TryParse(tables[18],out LimitValue);
            SalesStatus = tables[19];
            int.TryParse(tables[20],out TheOnlyShop);
            int.TryParse(tables[21],out RemindSuccess);
            int.TryParse(tables[22],out IsHideSellOut);
            int.TryParse(tables[12],out UnlockValue);
        }
        catch (Exception exception)
        {
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA201_tagCMQueryNPCShopItem.cs
File was deleted
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA201_tagCMQueryNPCShopItem.cs.meta
File was deleted
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCMRefreshMysticalShop.cs
File was deleted
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCMRefreshMysticalShop.cs.meta
File was deleted
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCSRefreshShop.cs
New file
@@ -0,0 +1,18 @@
using UnityEngine;
using System.Collections;
// A2 32 刷新商店 #tagCSRefreshShop
public class CA232_tagCSRefreshShop : GameNetPackBasic {
    public ushort ShopType;
    public CA232_tagCSRefreshShop () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xA232;
    }
    public override void WriteToBytes () {
        WriteBytes (ShopType, NetDataType.WORD);
    }
}
Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCSRefreshShop.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/Core/NetworkPackage/ClientPack/CA2_Interaction/CA232_tagCSRefreshShop.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 29b7288a0ca13a0459cee54ee3946f00
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCMBuyItem.cs
File was deleted
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCMBuyItem.cs.meta
File was deleted
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCSBuyItem.cs
New file
@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
// A3 10 购买商城物品 #tagCSBuyItem
public class CA310_tagCSBuyItem : GameNetPackBasic {
    public uint ShopID;    //商品ID
    public uint BuyCount;    //购买数量
    public CA310_tagCSBuyItem () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xA310;
    }
    public override void WriteToBytes () {
        WriteBytes (ShopID, NetDataType.DWORD);
        WriteBytes (BuyCount, NetDataType.DWORD);
    }
}
Main/Core/NetworkPackage/ClientPack/CA3_Item/CA310_tagCSBuyItem.cs.meta
File was renamed from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 2c10800b4df582940bcd553f7ce5d5e7
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagMCShopItemDayBuyCntInfo.cs
File was deleted
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagMCShopItemDayBuyCntInfo.cs.meta
File was deleted
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagSCShopItemBuyCntInfo.cs
New file
@@ -0,0 +1,12 @@
using UnityEngine;
using System.Collections;
// A8 02 商店物品已购买次数 #tagSCShopItemBuyCntInfo
public class DTCA802_tagSCShopItemBuyCntInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HA802_tagSCShopItemBuyCntInfo vNetData = vNetPack as HA802_tagSCShopItemBuyCntInfo;
        StoreModel.Instance.RefreshBuyShopLimitModel(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagSCShopItemBuyCntInfo.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA802_tagSCShopItemBuyCntInfo.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 6562275467e1a804fba2bf87c1dfc299
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA803_tagSCShopRefreshItemInfo.cs
New file
@@ -0,0 +1,12 @@
using UnityEngine;
using System.Collections;
// A8 03 商店刷新解锁的商品信息 #tagSCShopRefreshItemInfo
public class DTCA803_tagSCShopRefreshItemInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HA803_tagSCShopRefreshItemInfo vNetData = vNetPack as HA803_tagSCShopRefreshItemInfo;
        StoreModel.Instance.UpdateRefreshItemInfo(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA803_tagSCShopRefreshItemInfo.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA803_tagSCShopRefreshItemInfo.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 3448d17fb6821f145a4011196fbe337f
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA811_tagMCShoppingResult.cs
File was deleted
Main/Core/NetworkPackage/DTCFile/ServerPack/HA8_Item/DTCA811_tagMCShoppingResult.cs.meta
File was deleted
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -67,9 +67,9 @@
        Register(typeof(HA501_tagMCNotifyRequestJoinFamilyInfo), typeof(DTCA501_tagMCNotifyRequestJoinFamilyInfo));
        Register(typeof(HA705_tagSCQueryPlayerCacheResult), typeof(DTCA705_tagSCQueryPlayerCacheResult));
        Register(typeof(HA801_tagMCGiveAwardInfo), typeof(DTCA801_tagMCGiveAwardInfo));
        Register(typeof(HA802_tagMCShopItemDayBuyCntInfo), typeof(DTCA802_tagMCShopItemDayBuyCntInfo));
        Register(typeof(HA802_tagSCShopItemBuyCntInfo), typeof(DTCA802_tagSCShopItemBuyCntInfo));
        Register(typeof(HA803_tagSCShopRefreshItemInfo), typeof(DTCA803_tagSCShopRefreshItemInfo));
        Register(typeof(HA809_tagMCItemDayUseCntInfo), typeof(DTCA809_tagMCItemDayUseCntInfo));
        Register(typeof(HA811_tagMCShoppingResult), typeof(DTCA811_tagMCShoppingResult));
        Register(typeof(HA721_tagMCEmojiPackInfo), typeof(DTCA721_tagMCEmojiPackInfo));
        Register(typeof(HB117_tagMCFaceInfo), typeof(DTCB117_tagMCFaceInfo));
        Register(typeof(HB118_tagMCFacePicInfo), typeof(DTCB118_tagMCFacePicInfo));
Main/Core/NetworkPackage/ServerPack/H01_System/H0102_tagCDBPlayer.cs
@@ -103,7 +103,7 @@
    public uint HPEx;    //当前血量 超过E的记录
    public uint Face;    //头像
    public uint FacePic;    //头像外框
    public uint RoleType;    //角色类型(各项目可自定义含义,如种族,与职业区分)
    public uint RoleType;    //角色外观
    public H0102_tagCDBPlayer () {
        _cmd = (ushort)0x0102;
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs
File was deleted
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagSCShopItemBuyCntInfo.cs
New file
@@ -0,0 +1,29 @@
using UnityEngine;
using System.Collections;
// A8 02 商店物品已购买次数 #tagSCShopItemBuyCntInfo
public class HA802_tagSCShopItemBuyCntInfo : GameNetPackBasic {
    public ushort Count;
    public  tagSCShopItemBuyCnt[] BuyCntList;    //仅通知有限购次数的商品
    public HA802_tagSCShopItemBuyCntInfo () {
        _cmd = (ushort)0xA802;
    }
    public override void ReadFromBytes (byte[] vBytes) {
        TransBytes (out Count, vBytes, NetDataType.WORD);
        BuyCntList = new tagSCShopItemBuyCnt[Count];
        for (int i = 0; i < Count; i ++) {
            BuyCntList[i] = new tagSCShopItemBuyCnt();
            TransBytes (out BuyCntList[i].ShopID, vBytes, NetDataType.DWORD);
            TransBytes (out BuyCntList[i].BuyCnt, vBytes, NetDataType.DWORD);
        }
    }
    public class tagSCShopItemBuyCnt {
        public uint ShopID;        // 商品ID
        public uint BuyCnt;        // 已购买次数
    }
}
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagSCShopItemBuyCntInfo.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagSCShopItemBuyCntInfo.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 550e038f35a05504e907bb17dc280742
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA803_tagSCShopRefreshItemInfo.cs
New file
@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
// A8 03 商店刷新解锁的商品信息 #tagSCShopRefreshItemInfo
public class HA803_tagSCShopRefreshItemInfo : GameNetPackBasic {
    public ushort ShopType;    // 商店类型
    public byte RefreshCnt;    // 今日已刷新次数
    public byte Count;
    public  uint[] ShopIDList;    // 对应刷新出来的商店表商品ID列表
    public HA803_tagSCShopRefreshItemInfo () {
        _cmd = (ushort)0xA803;
    }
    public override void ReadFromBytes (byte[] vBytes) {
        TransBytes (out ShopType, vBytes, NetDataType.WORD);
        TransBytes (out RefreshCnt, vBytes, NetDataType.BYTE);
        TransBytes (out Count, vBytes, NetDataType.BYTE);
        TransBytes (out ShopIDList, vBytes, NetDataType.DWORD, Count);
    }
}
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA803_tagSCShopRefreshItemInfo.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/Core/NetworkPackage/ServerPack/HA8_Item/HA803_tagSCShopRefreshItemInfo.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: ed9f0959991e18a428f4cb38e6e31163
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA811_tagMCShoppingResult.cs
File was deleted
Main/Core/NetworkPackage/ServerPack/HA8_Item/HA811_tagMCShoppingResult.cs.meta
File was deleted
Main/Manager/UIManager.cs
@@ -326,7 +326,7 @@
        return false;
    }
    // 检查是否存在任何全屏或遮罩窗口, 暂未定义全屏可以统一勾选openMask
    // 检查是否存在任何全屏或遮罩窗口, 有screenMask 即可代表全屏
    public bool ExistAnyFullScreenOrMaskWin(string excludeUIName)
    {
        var exist = false;
@@ -338,7 +338,7 @@
                // 刷新UI
                if (ui.IsActive() && ui.name != excludeUIName)
                {
                    if (ui.openMask)
                    if (ui.screenMask != null)
                    {
                        exist = true;
                        break;
@@ -370,7 +370,7 @@
            {
                break;
            }
            if (uiBase.IsActive() && uiBase.openMask)
            if (uiBase.IsActive() && uiBase.screenMask != null)
            {
                return true;
            }
Main/System/Arena/ArenaAwardWin.cs
@@ -19,7 +19,6 @@
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        tabButtons[functionOrder].SelectBtn(true);
        ArenaManager.Instance.OnArenaMatchListEvent += OnArenaMatchListEvent;
        ArenaManager.Instance.OnUpdateArenaPlayerInfo += OnUpdateArenaPlayerInfo;
        ArenaManager.Instance.OnUpdateGameRecInfo += OnUpdateGameRecInfo;
Main/System/Arena/BuyItemWin.cs
File was deleted
Main/System/FirstCharge/FirstChargeWin.cs
@@ -47,11 +47,9 @@
    protected override void OnPreOpen()
    {
        functionOrder = GetDefaultTabIndex();
        base.OnPreOpen();
        InitRedPoint();
        functionOrder = GetDefaultTabIndex();
        tabButtons[functionOrder].SelectBtn(true);
        int firstId = model.GetFirstIDByTabIndex(functionOrder);
        model.SetClickTabState(firstId);
Main/System/Guild/GuildBaseWin.cs
@@ -16,7 +16,7 @@
    [SerializeField] Text guildNameText;
    [SerializeField] Text guildMemberCountText;
    [SerializeField] Button rankBtn;
    [SerializeField] Button storeBtn;
    [SerializeField] Button requestBtn;
@@ -34,6 +34,11 @@
        });
        
        guildHawkerBtn.AddListener(OpenHawker);
        storeBtn.AddListener(() =>
        {
            StoreModel.Instance.selectStoreFuncType = StoreFunc.Guild;
            UIManager.Instance.OpenWindow<StoreBaseWin>();
        });
    }
Main/System/Guild/GuildHawkerWin.cs
@@ -227,7 +227,7 @@
            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"),
            Language.Get("L1135", GuildManager.Instance.zbgPriceType, cutPrice)+ Language.Get("Guild_71"), (bool isOK) =>
            Language.Get("L1135", UIHelper.GetIconNameWithMoneyType(GuildManager.Instance.zbgPriceType), cutPrice)+ Language.Get("Guild_71"), (bool isOK) =>
                {
                    if (isOK)
                    {
Main/System/Guild/GuildManager.cs
@@ -58,7 +58,7 @@
    void OnPlayerLoginOk()
    {
        UpdateDonateRedPoint();
        QueryZBGFamilyInfo();
    }
    
    void PlayerDataRefreshEvent(PlayerDataType type)
@@ -104,6 +104,7 @@
        await UniTask.Delay(100);
        UpdateDonateRedPoint();
        UpdateZBGRedpoint();
        QueryZBGFamilyInfo();
        EnterOrQuitGuildEvent?.Invoke(true);
    }
@@ -784,7 +785,7 @@
        if (isQueryZBGYet)
            return;
        QueryFamilyAction((int)PlayerDatas.Instance.baseData.FamilyId, 16);
        QueryFamilyAction((int)PlayerDatas.Instance.baseData.FamilyId, ZBGFamilyActionType);
        isQueryZBGYet = true;
    }
@@ -896,7 +897,7 @@
    #region 红点
    Redpoint hallRedpoint = new Redpoint(MainRedDot.MainGuildRedpoint, MainRedDot.guildHallRedpointID);
    Redpoint donateRedpoint = new Redpoint(MainRedDot.guildHallRedpointID, MainRedDot.guildHallRedpointID * 10);
    //珍宝阁(行商)
    Redpoint zbgRedpoint = new Redpoint(MainRedDot.MainGuildRedpoint, MainRedDot.MainGuildRedpoint * 100 + 1);
Main/System/HeroUI/HeroBaseWin.cs
@@ -24,12 +24,6 @@
    }
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        tabButtons[functionOrder].SelectBtn(true);
    }
    protected override void OnPreClose()
    {
        base.OnPreClose();
Main/System/HeroUI/HeroDeleteWin.cs
@@ -21,7 +21,8 @@
    {
        storeBtn.AddListener(() =>
        {
            // UIManager.Instance.OpenWindow<StoreWin>();
            StoreModel.Instance.selectStoreFuncType = StoreFunc.Hero;
            UIManager.Instance.OpenWindow<StoreBaseWin>();
        });
        quickSelectBtn.AddListener(QuickSelect);
        deleteBtn.AddListener(DeleteHero);
Main/System/ItemTip/ItemTipUtility.cs
@@ -682,7 +682,7 @@
            //suitInfo = GetSuitInfo(itemId),
            //gemInfo = GetGemInfo(itemId),
            //starInfo = GetStarInfo(itemId),
            operates = GetGoodOperates(goodId),
            // operates = GetGoodOperates(goodId),
            //shenProperty = GetShenProperty(itemId)
        };
    }
@@ -771,7 +771,7 @@
            // legendProperty = GetLegendProperty(itemId),
            // spiritWeaponProperty = GetSpiritWeaponProperty(itemId),
            // petMountBaseProperty = GetPetMountBaseProperty(itemId),
            operates = GetGoodOperates(goodId),
            // operates = GetGoodOperates(goodId),
            // shenProperty = GetShenProperty(itemId)
        };
    }
@@ -1605,28 +1605,6 @@
    // }
    private static List<ItemOperateType> GetGoodOperates(int goodId)
    {
        var operates = new List<ItemOperateType>();
        var countLimit = BuyItemController.Instance.GetBuyCountLimit(goodId, PlayerDatas.Instance.baseData.VIPLv);
        if (countLimit == -1 || countLimit > 0)
        {
            var config = StoreConfig.Get(goodId);
            int curVipIndex = -1;
            int nextVipIndex = -1;
            bool isVipBuy = BuyItemController.Instance.CheckIsVipBuy(config, out curVipIndex, out nextVipIndex);
            if ((isVipBuy && curVipIndex == -1) || PlayerDatas.Instance.baseData.LV < config.LV)
            {
                return operates;
            }
            operates.Add(ItemOperateType.buy);
        }
        return operates;
    }
    // private static bool IsEquipGemHoleOpen(Int2 equipPosition, int maxStar, int hole)
    // {
Main/System/Mail/MailWin.cs
@@ -21,7 +21,6 @@
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        tabButtons[functionOrder].SelectBtn(true);
        model.nowMailCategory = MailCategory.Personal;
        rpTab0.redpointId = model.GetTabRedpointId(MailCategory.Personal);
        rpTab1.redpointId = model.GetTabRedpointId(MailCategory.Global);
Main/System/Main/FuncsBaseWin.cs
@@ -24,6 +24,7 @@
    }
    protected override void OnPreOpen()
    {
        tabButtons[functionOrder].SelectBtn();
        // 默认选中第一个标签
        SelectBottomTab(functionOrder);
Main/System/Main/HomeWin.cs
@@ -52,8 +52,10 @@
    [SerializeField] Text blessLVText;
    [SerializeField] Button mailBtn;
    //其他功能入口
    [SerializeField] Button monthCardBtn;
    //右侧功能
    [SerializeField] Button funcColBtn;
    [SerializeField] RightFuncInHome rightFuncInHome;
    [SerializeField] Button FirstChargeBtn;
    /// <summary>
@@ -80,10 +82,7 @@
        });
        monthCardBtn.AddListener(() =>
        {
            InvestModel.Instance.BuyInvest(InvestModel.monthCardType);
        });
        FirstChargeBtn.AddListener(() =>
        {
@@ -112,6 +111,10 @@
        });
        restBtn.AddListener(GotoRest);
        funcColBtn.AddListener(()=>
        {
            rightFuncInHome.ShowFuncCol(true);
        });
    }
Main/System/Main/RightFuncInHome.cs
New file
@@ -0,0 +1,75 @@
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
//主界面的右边栏缩进功能
public class RightFuncInHome : MonoBehaviour
{
    [SerializeField] ClickScreenOtherSpaceEvent clickScreenOtherSpaceEvent;
    [SerializeField] RectTransform funcCol;
    [SerializeField] RectTransform showPoint;
    [SerializeField] RectTransform hidePoint;
    [SerializeField] Button closeBtn;
    [SerializeField] Button storeBtn;
    [SerializeField] Button monthCardBtn;
    string listenWindowName = "";   //监听关闭时再显示
    bool isShow = false;
    void Awake()
    {
        monthCardBtn.AddListener(() =>
        {
            ListenWindow("");
            InvestModel.Instance.BuyInvest(InvestModel.monthCardType);
        });
        storeBtn.AddListener(() =>
        {
            ListenWindow("StoreBaseWin");
            UIManager.Instance.OpenWindow<StoreBaseWin>();
        });
        clickScreenOtherSpaceEvent.AddListener(() =>
        {
            if (isShow)
            {
                isShow = !isShow;
                ShowFuncCol(isShow);
            }
        });
        closeBtn.AddListener(() =>
        {
            ShowFuncCol(false);
        });
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
    }
    //显隐功能栏
    public void ShowFuncCol(bool _isShow)
    {
        isShow = _isShow;
        funcCol.DOLocalMove(isShow ? showPoint.localPosition : hidePoint.localPosition, 0.3f);
    }
    void OnCloseWindow(UIBase win)
    {
        if (win.name == listenWindowName)
        {
            ShowFuncCol(true);
            listenWindowName = "";
        }
    }
    void ListenWindow(string _listenWindowName)
    {
        ShowFuncCol(false);
        listenWindowName = _listenWindowName;
    }
}
Main/System/Main/RightFuncInHome.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/System/Main/RightFuncInHome.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 74e5ae08181442a4f8900388b534c310
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Redpoint/MainRedDot.cs
@@ -16,6 +16,8 @@
    public Redpoint redpointChallenge = new Redpoint(MainChallengeRedpoint);
    public const int MainGuildRedpoint = 4;     //公会
    public Redpoint redpointGuild = new Redpoint(MainGuildRedpoint);
    public const int RightFuncRedpoint = 5;     //右侧功能红点
    public Redpoint redpointRightFunc = new Redpoint(RightFuncRedpoint);
    //以下红点规则:功能基础红点3位数,子红点至少大于1000,
@@ -55,13 +57,17 @@
    #region 仙盟红点
    //大厅
    public const int guildHallRedpointID = MainGuildRedpoint * 10;
    Redpoint hallRedpoint = new Redpoint(MainGuildRedpoint, guildHallRedpointID);
    #endregion
    #region 仙盟商店红点
    public const int FAIRYStore_REDPOINT_KEY3 = 1070106;
    #region 商店入口红点
    public const int Store_REDPOINT = 103;
    #endregion
Main/System/Redpoint/Redpoint.cs
@@ -12,11 +12,15 @@
        }
        int m_Parent = 0;
        public int parent {
    public int parent
    {
            get { return m_Parent; }
            private set { m_Parent = value; }
        }
    public int otherParent;
        RedPointState m_State = RedPointState.None;
        public RedPointState state {
            get { return m_State; }
Main/System/Redpoint/RedpointCenter.cs
@@ -50,19 +50,46 @@
        }
    }
    //额外添加父红点用
    public void AddParent(int _parentId, int _childId)
    {
        Redpoint child = null;
        if (!redpoints.TryGetValue(_childId, out child))
        {
            Debug.LogErrorFormat("添加父子关系失败,子节点不存在:id->{0}", _childId);
            return;
        }
        child.otherParent = _parentId;
        List<int> children = null;
        if (!parentChildren.TryGetValue(_parentId, out children))
        {
            parentChildren[_parentId] = children = new List<int>();
        }
        if (!children.Contains(_childId))
        {
            children.Add(_childId);
        }
    }
    public void Report(Redpoint _redpoint)
    {
        var parentId = _redpoint.parent;
        if (redpointValueChangeEvent != null)
        {
            redpointValueChangeEvent(_redpoint.id);
        }
        if (parentId > 0)
        if (_redpoint.parent > 0)
        {
            TestParentValue(_redpoint.parent);
        }
        if (_redpoint.otherParent > 0)
        {
            TestParentValue(_redpoint.otherParent);
        }
    }
    public void ReportWithoutParent(Redpoint _redpoint)
Main/System/Store/BuyItemController.cs
File was deleted
Main/System/Store/BuyItemController.cs.meta
File was deleted
Main/System/Store/BuyItemWin.cs
New file
@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//使用货币购买坊市表商品
public class BuyItemWin : UIBase
{
    [SerializeField] ItemCell itemCell;
    [SerializeField] Text nameText;
    [SerializeField] Text countText;
    [SerializeField] Text descText;
    [SerializeField] SliderPanel sliderPanel;
    [SerializeField] Text limitText;
    [SerializeField] Image moneyIcon;
    [SerializeField] Text moneyText;
    [SerializeField] Button buyButton;
    int itemCount;
    int useCnt;
    int maxCnt;
    protected override void InitComponent()
    {
        buyButton.AddListener(BuyGoods);
    }
    protected override void OnPreOpen()
    {
        useCnt = 1;
        Display();
    }
    void Display()
    {
        var shopConfig = StoreConfig.Get(StoreModel.Instance.buyShopID);
        var itemID = shopConfig.ItemID;
        var itemCount = shopConfig.ItemCnt;
        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
        var itemConfig = ItemConfig.Get(itemID);
        nameText.text = itemConfig.ItemName;
        countText.text = Language.Get("storename12", PackManager.Instance.GetItemCountByID(PackType.Item, itemID));
        descText.text = itemConfig.Description;
        var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(StoreModel.Instance.buyShopID);
        maxCnt = shopConfig.LimitCnt - buyCnt;
        if (maxCnt == 0)
        {
            //没有限购,用货币可购买数量
            maxCnt = Math.Max(1, (int)(UIHelper.GetMoneyCnt(shopConfig.MoneyType)/shopConfig.MoneyNum));
        }
        OnSliderChange(useCnt);
        sliderPanel.Init((value) => { OnSliderChange(value); }, maxCnt);
    }
    void OnSliderChange(int value)
    {
        var shopConfig = StoreConfig.Get(StoreModel.Instance.buyShopID);
        useCnt = value;
        itemCell.countText.text = value.ToString();
        string limitStr = "";
        if (shopConfig.LimitCnt == 0)
        {
            limitStr = "";
        }
        else if (shopConfig.ResetType == 0)
        {
            //限购
            limitStr = Language.Get("storename8", useCnt, maxCnt);
        }
        else if (shopConfig.ResetType == 1)
        {
            //每日限购
            limitStr = Language.Get("storename6", useCnt, maxCnt);
        }
        else if (shopConfig.ResetType == 2)
        {
            //每周限购
            limitStr = Language.Get("storename7", useCnt, maxCnt);
        }
        limitText.text = limitStr;
        moneyIcon.SetIconWithMoneyType(shopConfig.MoneyType);
        moneyText.text = UIHelper.ShowUseMoney(shopConfig.MoneyType, shopConfig.MoneyNum * useCnt);
    }
    void BuyGoods()
    {
        CloseWindow();
        StoreModel.Instance.SendBuyShopItem(StoreConfig.Get(StoreModel.Instance.buyShopID), useCnt);
    }
}
Main/System/Store/BuyItemWin.cs.meta
Main/System/Store/StoreBaseWin.cs
New file
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StoreBaseWin : OneLevelWin
{
    protected override void OpenSubUIByTabIndex()
    {
        switch (functionOrder)
        {
            case 0:
                currentSubUI = UIManager.Instance.OpenWindow<StoreWin>();
                break;
            case 1:
                // 充值界面
                currentSubUI = UIManager.Instance.OpenWindow<StoreWin>();
                break;
            default:
                Debug.LogWarning("未知的标签索引: " + functionOrder);
                break;
        }
    }
}
Main/System/Store/StoreBaseWin.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/System/Store/StoreBaseWin.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: ec02a33fe66b23e4da4bfcb33ca49c4e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Store/StoreCell.cs
New file
@@ -0,0 +1,143 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StoreCell : MonoBehaviour
{
    [SerializeField] Transform saleRect;
    [SerializeField] Text saleText;
    [SerializeField] Text itemName;
    [SerializeField] ItemCell itemCell;
    [SerializeField] Text limitText;
    [SerializeField] Text lockTip;
    [SerializeField] Image priceIcon;
    [SerializeField] Text priceText;
    [SerializeField] Text salePriceText;
    [SerializeField] Button buyButton;
    //免费 和 已售罄的显示 同一个按钮
    [SerializeField] Button freeButton;
    [SerializeField] Image freeRedPoint;
    [SerializeField] Text freeText;
    public void Display(int index)
    {
        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
        {
            return;
        }
        var list = StoreModel.Instance.storeTypeDict[(int)StoreModel.Instance.selectStoreFuncType];
        var storeData = list[index];
        int shopID = storeData.shopId;
        var itemID = storeData.storeConfig.ItemID;
        var itemCount = storeData.storeConfig.ItemCnt;
        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
        itemCell.button.AddListener(() =>
        {
            ItemTipUtility.Show(itemID);
        });
        var config = ItemConfig.Get(itemID);
        itemName.text = config.ItemName;
        //折扣
        if (storeData.storeConfig.MoneyOriginal != 0)
        {
            saleRect.SetActive(true);
            saleText.text = Language.Get("storename5", (storeData.storeConfig.MoneyNum*10 / (float)storeData.storeConfig.MoneyOriginal).ToString("0.#"));
        }
        else
        {
            saleRect.SetActive(false);
        }
        var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(shopID);
        string limitStr = "";
        if (storeData.storeConfig.MoneyNum == 0)
        {
            //免费
            limitStr = "";
        }
        else if (storeData.storeConfig.ResetType == 0)
        {
            //限购
            limitStr = storeData.storeConfig.LimitCnt > 0 ? Language.Get("storename8", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt) : "";
        }
        else if (storeData.storeConfig.ResetType == 1)
        {
            //每日限购
            limitStr = Language.Get("storename6", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt);
        }
        else if (storeData.storeConfig.ResetType == 2)
        {
            //每周限购
            limitStr = Language.Get("storename7", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt);
        }
        limitText.text = buyCnt >= storeData.storeConfig.LimitCnt ? UIHelper.AppendColor(TextColType.Gray, limitStr) : limitStr;
        //0可购买 1已售罄 2免费 3未解锁
        var state = StoreModel.Instance.GetShopIDState(shopID);
        if (state == 0)
        {
            buyButton.SetActive(true);
            freeButton.SetActive(false);
            lockTip.text = "";
            priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
            priceText.text = storeData.storeConfig.MoneyNum.ToString();
            if (storeData.storeConfig.MoneyOriginal == 0)
            {
                salePriceText.SetActive(false);
            }
            else
            {
                salePriceText.SetActive(true);
                salePriceText.text = storeData.storeConfig.MoneyOriginal.ToString();
            }
            buyButton.AddListener(()=> { BuyGoods(shopID); });
        }
        else if (state == 1)
        {
            buyButton.SetActive(false);
            freeButton.SetActive(true);
            freeText.text = Language.Get("storename11");
            freeButton.SetInteractable(false);
            lockTip.text = "";
            freeRedPoint.SetActive(false);
        }
        else if (state == 2)
        {
            buyButton.SetActive(false);
            freeButton.SetActive(true);
            freeText.text = Language.Get("L1127");
            freeButton.SetInteractable(true);
            lockTip.text = "";
            freeRedPoint.SetActive(true);
            freeButton.AddListener(()=> { BuyGoods(shopID); });
        }
        else if (state == 3)
        {
            buyButton.SetActive(false);
            freeButton.SetActive(false);
            lockTip.text = Language.Get("storename10", storeData.storeConfig.UnlockValue);
        }
    }
    void BuyGoods(int shopID)
    {
        var state = StoreModel.Instance.GetShopIDState(shopID);
        if (state == 2)
        {
            StoreModel.Instance.SendBuyShopItem(StoreConfig.Get(shopID), 1);
        }
        else
        {
            StoreModel.Instance.buyShopID = shopID;
            UIManager.Instance.OpenWindow<BuyItemWin>();
        }
    }
}
Main/System/Store/StoreCell.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/System/Store/StoreCell.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 6ef33ea31e746294a9b5d401fe64b21f
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Store/StoreLineCell.cs
New file
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StoreLineCell : CellView
{
    [SerializeField] StoreCell[] storeCells;
    public void Display(int index)
    {
        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
        {
            return;
        }
        var list = StoreModel.Instance.storeTypeDict[(int)StoreModel.Instance.selectStoreFuncType];
        for (int i = 0; i < storeCells.Length; i++)
        {
            if (index + i < list.Count)
            {
                storeCells[i].SetActive(true);
                storeCells[i].Display(index + i);
            }
            else
            {
                storeCells[i].SetActive(false);
            }
        }
    }
}
Main/System/Store/StoreLineCell.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/System/Store/StoreLineCell.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: c61cd40bb2d026a4bbdb9b9e2c07ca70
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Store/StoreModel.cs
@@ -6,14 +6,9 @@
using LitJson;
using System.Collections;
public class BuyShopItemLimit
{
    public uint ItemIndex;
    public int BuyCnt;        // 今日已购买次数
    public int isReset;         //是否属于每月重置  0 不重置 1重置
}
public struct ShopItemInfo
public class ShopItemInfo
{
    public int itemId;
    public int count;
@@ -27,149 +22,87 @@
public class StoreModel : GameSystemManager<StoreModel>
{
    public Dictionary<int, List<StoreData>> storeTypeDict { get; private set; } //所有显示商品
    public Dictionary<int, int> shopRefreshCntDict = new Dictionary<int, int>();    //刷新次数
    private Dictionary<int, int> shopItemlimitDict = new Dictionary<int, int>();    //已购买次数
    public event Action RefreshBuyShopLimitEvent;
    public event Action RefreshShopEvent;
    public string UNIONSTORESAVE_KEY { get; private set; }
    public string MUSTBUYSAVE_KEY { get; private set; }
    public string StoreEffectRecord_Key { get; private set; }
    public Dictionary<int, Dictionary<int, int>> JobReplaceIdDict = new Dictionary<int, Dictionary<int, int>>();
    public Dictionary<int, int> showCoinUIDict { get; private set; }
    public int storeTrailerLv { get; private set; }
    public StoreFunc selectStoreFuncType = StoreFunc.Normal;
    public int fairyStoreJumpShopId = 0;
    public int buyShopID;
    int m_SelectClassifyId = 0;
    public int selectSecondType
    {
        get { return m_SelectClassifyId; }
        set
        {
            if (m_SelectClassifyId != value)
            {
                m_SelectClassifyId = value;
                if (selectClassifyRefresh != null)
                {
                    selectClassifyRefresh();
                }
            }
        }
    }
    //配置
    public int heroSoulRefreshMoneyType;
    public int heroSoulRefreshMoney;
    public int heroSoulRefreshFreeCount;
    public event Action selectClassifyRefresh;
    private bool isUpdatePlayerLv;
    //排行榜活动的商店
    public int rankActStore_MoneyType;
    public int rankActStore_StoreType;
    public OperationType rankActStore_ActType;
    Dictionary<int, List<int>> freeShopDict = new Dictionary<int, List<int>>();
    public Dictionary<int, int> shopMoneyTypeDict = new Dictionary<int, int>();
    public override void Init()
    {
        RedpointCenter.Instance.AddParent(MainRedDot.MainGuildRedpoint, MainRedDot.Store_REDPOINT);
        FuncOpen.Instance.OnFuncStateChangeEvent += FuncStateChange;
        TimeMgr.Instance.OnDayEvent += RefreshDay;
        GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeRelogin;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        ParseFuncConfig();
        ParseStoreConfig();
        SetShopRedpoint();
    }
    public void OnBeforePlayerDataInitialize()
    public override void Release()
    {
        isUpdatePlayerLv = false;
        IsMustBuyDay = false;
        sortStoreSecondType = true;
        ClearJump();
        FuncOpen.Instance.OnFuncStateChangeEvent -= FuncStateChange;
        PlayerDatas.Instance.fairyData.OnRefreshFairyMine -= RefreshServerHour;
        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= RefreshFamilyLv;
        PlayerDatas.Instance.playerDataRefreshEvent -= RefreshPlayerData;
        TimeMgr.Instance.OnHourEvent -= RefreshServerHour;
        GlobalTimeEvent.Instance.secondEvent -= UpdateSecond;
        TimeMgr.Instance.OnDayEvent -= RefreshDay;
        GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeRelogin;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
    }
    void OnBeforePlayerDataInitialize()
    {
        shopItemlimitDict.Clear();
        storeFuncType = StoreFunc.DayStore;
        storeTypeDict.Remove((int)StoreFunc.Hero);  //由服务器通知
        selectStoreFuncType = StoreFunc.Normal;
    }
    public void OnAfterPlayerDataInitialize()
    void OnBeforePlayerDataInitializeRelogin()
    {
        UNIONSTORESAVE_KEY = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, LocalSaveStoreType.UnionStore);
        StoreEffectRecord_Key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "StoreEffectRecord");
        MUSTBUYSAVE_KEY = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "MustBuy");
        buyItemCheckDict.Clear();
    }
    public void OnPlayerLoginOk()
    {
        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += RefreshFamilyLv;
        PlayerDatas.Instance.fairyData.OnRefreshFairyMine += RefreshServerHour;
        FuncOpen.Instance.OnFuncStateChangeEvent += FuncStateChange;
        PlayerDatas.Instance.playerDataRefreshEvent += RefreshPlayerData;
        TimeMgr.Instance.OnHourEvent += RefreshServerHour;
        GlobalTimeEvent.Instance.secondEvent += UpdateSecond;
        UpdateShowStore();
        SetIsMustBuyDay();
        ControllerRedPoint();
        UpdateFreeShopRedpoint();
        UpdateCanBuyRedpoint();
        UpdateMustBuyRedpoint();
        UpdateDailyRedpoinit();
    }
    #region 解析本地数据
    public Dictionary<int, List<int>> storeRedRuleDict { get; private set; } //红点类型 1,免费商品  2,必买商品  3,坐骑灵宠 4,可购买物品(积分兑换)
    private void ParseFuncConfig()
    {
        storeRedRuleDict = new Dictionary<int, List<int>>();
        FuncConfigConfig storeRedRules = FuncConfigConfig.Get("StoreRedRules");
        if (storeRedRules != null)
        {
            JsonData redRules = JsonMapper.ToObject(storeRedRules.Numerical1);
            foreach (var type in redRules.Keys)
            {
                int redType = 0;
                int.TryParse(type, out redType);
                JsonData shops = redRules[type];
                if (!storeRedRuleDict.ContainsKey(redType))
                {
                    List<int> shopIdlist = new List<int>();
                    if (shops.IsArray)
                    {
                        for (int i = 0; i < shops.Count; i++)
                        {
                            int shopId = 0;
                            int.TryParse(shops[i].ToString(), out shopId);
                            shopIdlist.Add(shopId);
                        }
                    }
                    storeRedRuleDict.Add(redType, shopIdlist);
                }
        var config = FuncConfigConfig.Get("StoreHeroSoul");
        var tmpArr = ConfigParse.GetMultipleStr<int>(config.Numerical2);
        heroSoulRefreshMoneyType = tmpArr[0];
        heroSoulRefreshMoney = tmpArr[1];
        heroSoulRefreshFreeCount = int.Parse(config.Numerical3);
            }
            
        }
    }
    public Dictionary<int, List<StoreData>> storeTypeDict { get; private set; }
    public Dictionary<int, List<StoreData>> theOnlyShopDict { get; private set; } //key 物品id
    public Dictionary<string, List<StoreData>> limitValueShopDict { get; private set; } //key 商品类型和限制条件
    private void ParseStoreConfig()
    {
        freeShopDict.Clear();
        storeTypeDict = new Dictionary<int, List<StoreData>>();
        theOnlyShopDict = new Dictionary<int, List<StoreData>>();
        limitValueShopDict = new Dictionary<string, List<StoreData>>();
        List<StoreConfig> storeConfigs = StoreConfig.GetValues();
        for (int i = 0; i < storeConfigs.Count; i++)
        {
            var config = storeConfigs[i];
            if (config.ShopType != 0)
            //UnlockType 2 由服务端通知
            if (config.ShopType != 0 && config.UnlockType != 2)
            {
                //构建商品数据
                StoreData storeData = new StoreData();
                storeData.shopId = config.ID;
                storeData.storeConfig = config;
                storeData.jobReplaceDict = AnalysisJobReplace(config);
                if (!storeTypeDict.ContainsKey(config.ShopType))
                {
                    List<StoreData> storeDatas = new List<StoreData>();
@@ -181,31 +114,21 @@
                    storeTypeDict[config.ShopType].Add(storeData);
                }
                if (config.TheOnlyShop == 1)
                //构建免费商品数据
                if (config.MoneyNum == 0)
                {
                    if (!theOnlyShopDict.ContainsKey(config.ItemID))
                    if (!freeShopDict.ContainsKey(config.ShopType))
                    {
                        List<StoreData> storeDatas = new List<StoreData>();
                        storeDatas.Add(storeData);
                        theOnlyShopDict.Add(config.ItemID, storeDatas);
                        freeShopDict.Add(config.ShopType, new List<int>());
                    }
                    else
                    {
                        theOnlyShopDict[config.ItemID].Add(storeData);
                    freeShopDict[config.ShopType].Add(config.ID);
                    }
                }
                string key = StringUtility.Contact(config.ShopType, config.LimitValue);
                if (!limitValueShopDict.ContainsKey(key))
            //构建商品价格类型
            if (!shopMoneyTypeDict.ContainsKey(config.ShopType))
                {
                    List<StoreData> storeDatas = new List<StoreData>();
                    storeDatas.Add(storeData);
                    limitValueShopDict.Add(key, storeDatas);
                }
                else
                {
                    limitValueShopDict[key].Add(storeData);
                }
                shopMoneyTypeDict[config.ShopType] = config.MoneyType;
            }
        }
@@ -216,30 +139,7 @@
        }
    }
    private Dictionary<int, List<int>> AnalysisJobReplace(StoreConfig storeConfig)
    {
        if (storeConfig == null || string.IsNullOrEmpty(storeConfig.JobItem)) return null;
        Dictionary<int, List<int>> replaceDict = new Dictionary<int, List<int>>();
        JsonData jsonData = JsonMapper.ToObject(storeConfig.JobItem);
        if (jsonData.IsArray)
        {
            for (int i = 0; i < jsonData.Count; i++)
            {
                List<int> idlist = new List<int>();
                replaceDict.Add(i, idlist);
                if (jsonData[i].IsArray)
                {
                    for (int j = 0; j < jsonData[i].Count; j++)
                    {
                        int itemId = int.Parse(jsonData[i][j].ToString());
                        idlist.Add(itemId);
                    }
                }
            }
        }
        return replaceDict;
    }
    public int CompareByShopSort(StoreData start, StoreData end)
    {
@@ -253,114 +153,11 @@
    {
        public int shopId;
        public StoreConfig storeConfig;
        public Dictionary<int, List<int>> jobReplaceDict;
    }
    #endregion
    #region 获取数据
    private Dictionary<int, List<StoreData>> showStoreTypeDict = new Dictionary<int, List<StoreData>>();
    private Dictionary<int, Dictionary<int, List<StoreData>>> showStoreSecondTypeDict = new Dictionary<int, Dictionary<int, List<StoreData>>>();
    // 新规则分二级标签,此函数保留,另增加UpdateShowStoreEx函数
    public void UpdateShowStore()
    {
        showStoreTypeDict.Clear();
        int playeLv = PlayerDatas.Instance.baseData.LV;
        //int vipLevel = PlayerDatas.Instance.baseData.VIPLv;
        foreach (var type in storeTypeDict.Keys)
        {
            var storeDatas = storeTypeDict[type];
            List<StoreData> showStoreDatas = new List<StoreData>();
            if (!showStoreTypeDict.ContainsKey(type))
            {
                for (int i = 0; i < storeDatas.Count; i++)
                {
                    var storeData = storeDatas[i];
                    bool isReachLv = playeLv >= storeData.storeConfig.LVSee ? true : false;
                    bool isReach = isReachLv;
                    if (isReach)
                    {
                        int remainNum = 0;
                        bool isSellOut = TryGetIsSellOut(storeData.storeConfig, out remainNum);
                        if (storeData.storeConfig.IsHideSellOut != 1)
                        {
                            showStoreDatas.Add(storeData);
                        }
                        else
                        {
                            if (storeData.storeConfig.TheOnlyShop == 1)
                            {
                                if (!CheckTheOnlyShopSellOut(storeData.shopId))
                                {
                                    showStoreDatas.Add(storeData);
                                }
                            }
                            else
                            {
                                if (!isSellOut)
                                {
                                    showStoreDatas.Add(storeData);
                                }
                            }
                        }
                    }
                }
                showStoreTypeDict.Add(type, showStoreDatas);
            }
        }
        UpdateShowStoreEx();
    }
    // 商城分二级标签
    public void UpdateShowStoreEx()
    {
        sortStoreSecondType = true;
        showStoreSecondTypeDict.Clear();
        foreach (var type in showStoreTypeDict.Keys)
        {
            if (!showStoreSecondTypeDict.ContainsKey(type))
                showStoreSecondTypeDict[type] = new Dictionary<int, List<StoreData>>();
            foreach (var storeData in showStoreTypeDict[type])
            {
                foreach (var secondType in storeData.storeConfig.SecondType)
                {
                    if (!showStoreSecondTypeDict[type].ContainsKey(secondType))
                        showStoreSecondTypeDict[type][secondType] = new List<StoreData>();
                    showStoreSecondTypeDict[type][secondType].Add(storeData);
                }
            }
        }
    }
    bool sortStoreSecondType = true;
    public void SortStoreSecondType()
    {
        //ArrayList lst = new ArrayList(showStoreSecondTypeDict.Keys);
        if (!sortStoreSecondType)
            return;
        foreach (var type in showStoreSecondTypeDict.Keys)
        {
            foreach (var secondType in showStoreSecondTypeDict[type].Keys)
            {
                var storeList = showStoreSecondTypeDict[type][secondType];
                storeList.Sort(CompareSecondShop);
            }
        }
        sortStoreSecondType = false;
    }
    private bool IsSellOut(StoreData storeData)
    {
@@ -368,121 +165,23 @@
        if (TryGetIsSellOut(storeData.storeConfig, out remainNum))
            return true;
        if (storeData.storeConfig.TheOnlyShop == 1 && CheckTheOnlyShopSellOut(storeData.shopId))
            return true;
        return false;
    }
    private int CompareSecondShop(StoreData start, StoreData end)
    {
        bool isSellOut1 = IsSellOut(start);
        bool isSellOut2 = IsSellOut(end);
        if (isSellOut1 != isSellOut2)
            return isSellOut1.CompareTo(isSellOut2);
        int sort1 = start.storeConfig.ShopSort;
        int sort2 = end.storeConfig.ShopSort;
        return sort1.CompareTo(sort2);
    }
    /// <summary>
    /// 检测唯一商品是否已售罄
    /// </summary>
    /// <param name="shopIndex"></param>
    /// <param name="isTheOnlyShop"></param>
    /// <returns></returns>
    public bool CheckTheOnlyShopSellOut(int shopIndex)
    {
        StoreConfig storeConfig = StoreConfig.Get(shopIndex);
        if (storeConfig == null || storeConfig.TheOnlyShop != 1) return false;
        if (theOnlyShopDict.ContainsKey(storeConfig.ItemID))
        {
            List<StoreData> datas = theOnlyShopDict[storeConfig.ItemID];
            for (int i = 0; i < datas.Count; i++)
            {
                var data = datas[i];
                int remainNum = 0;
                if (TryGetIsSellOut(data.storeConfig, out remainNum))
                {
                    return true;
                }
            }
        }
        return false;
    }
    public List<StoreData> TryGetStoreDatas(StoreFunc type)
    {
        var results = new List<StoreData>();
        List<StoreData> datas = null;
        if (showStoreTypeDict.TryGetValue((int)type, out datas))
        if (storeTypeDict.TryGetValue((int)type, out datas))
        {
            results.AddRange(datas);
            //switch (type)
            //{
            //    case StoreFunc.MysteryStore:
            //        foreach (var item in datas)
            //        {
            //            if (mysteryCommondities.Contains(item.storeConfig.ID))
            //            {
            //                results.Add(item);
            //            }
            //        }
            //        results.Sort((StoreData x, StoreData y) => { return x.storeConfig.MoneyType < y.storeConfig.MoneyType ? -1 : 1; });
            //        break;
            //    default:
            //        results.AddRange(datas);
            //        break;
            //}
            return datas;
        }
        return results;
        return datas;
    }
    // 获取二级标签商品
    public List<StoreData> TryGetStoreDatasBySecondType(int type, int secondType)
    {
        if (!showStoreSecondTypeDict.ContainsKey(type))
            return null;
        if (!showStoreSecondTypeDict[type].ContainsKey(secondType))
            return null;
        SortStoreSecondType();
        return showStoreSecondTypeDict[type][secondType];
    }
    // 获得二级标签的第一个标签类型
    public int GetFirstStoreSecondType(int type, bool jump = true)
    {
        if (jump && jumpToItemId != 0)
        {
            if (selectSecondType == 0) selectSecondType = 1;
            return selectSecondType;
        }
        if (!showStoreSecondTypeDict.ContainsKey(type))
            return 1;
        ArrayList sortList = new ArrayList(showStoreSecondTypeDict[type].Keys);
        sortList.Sort();
        return (int)sortList[0];
    }
    // 获得二级标签的第一个标签类型
    public ArrayList GetStoreSecondTypeList(int type)
    {
        if (!showStoreSecondTypeDict.ContainsKey(type))
            return null;
        ArrayList sortList = new ArrayList(showStoreSecondTypeDict[type].Keys);
        sortList.Sort();
        return sortList;
    }
    public StoreData GetStoreData(int shopId)
    {
@@ -505,61 +204,21 @@
        return null;
    }
    // 不同职业显示不同物品的情况
    public int GetReplaceId(int shopId, int itemId)
    {
        var storeData = GetStoreData(shopId);
        if (storeData == null) return 0;
        int job = PlayerDatas.Instance.baseData.Job;
        var replaceDict = storeData.jobReplaceDict;
        if (replaceDict != null)
        {
            foreach (var index in replaceDict.Keys)
            {
                var idlist = replaceDict[index];
                if (idlist.Contains(itemId))
                {
                    int replaceIndex = job - 1;
                    return idlist[replaceIndex];
                }
            }
        }
        return itemId;
    }
    public bool TryGetRedTypeByShopId(int shopId, out int type)
    {
        type = 0;
        foreach (var key in storeRedRuleDict.Keys)
        {
            List<int> idlist = storeRedRuleDict[key];
            if (idlist.Contains(shopId))
            {
                type = key;
                return true;
            }
        }
        return false;
    }
    public bool TryGetIsSellOut(StoreConfig storeConfig, out int remainCnt)
    {
        int canBuyCnt = 0;
        int addBuyCnt = 0;
        int canBuyCnt = storeConfig.LimitCnt;
        remainCnt = 0;
        bool isLimitBuy = TryGetLimitBuy(storeConfig, out canBuyCnt, out addBuyCnt);
        if (!isLimitBuy) return false;
        //不限购
        if (canBuyCnt == 0) return false;
        remainCnt = canBuyCnt;
        BuyShopItemLimit shopItemLimit = GetBuyShopLimit((uint)storeConfig.ID);
        if (shopItemLimit != null)
        {
            remainCnt -= shopItemLimit.BuyCnt;
        }
        var buyCnt = GetShopLimitBuyCount(storeConfig.ID);
        remainCnt -= buyCnt;
        if (remainCnt <= 0)
        {
@@ -568,304 +227,105 @@
        return false;
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="config"></param>
    /// <param name="canBuyCnt"> 可购买上限</param>
    /// <param name="addBuyCnt"> 下一级VIP增加的可购买次数</param>
    /// <returns></returns>
    public bool TryGetLimitBuy(StoreConfig config, out int canBuyCnt, out int addBuyCnt)
    {
        canBuyCnt = 0;
        addBuyCnt = 0;
        if (config == null) return false;
        int[] canBuyNums = config.GoumaiNumber;
        if (canBuyNums == null || canBuyNums.Length < 1) return false;
        int curVipIndex = -1;
        int nexVipIndex = -1;
        bool isVipBuy = TryGetVipBuy(config, out curVipIndex, out nexVipIndex);
        if (isVipBuy)
        {
            if (curVipIndex != -1)
            {
                canBuyCnt = canBuyNums[curVipIndex];
            }
            if (nexVipIndex != -1)
            {
                addBuyCnt = canBuyNums[nexVipIndex] - canBuyCnt;
            }
            return true;
        }
        else
        {
            if (canBuyNums[0] != 0)
            {
                canBuyCnt = canBuyNums[0];
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    public bool TryGetVipBuy(StoreConfig config, out int curVipIndex, out int nextVipIndex)
    {
        curVipIndex = -1;
        nextVipIndex = -1;
        bool isVipBuy = false;
        if (config == null) return false;
        var vipLvs = config.VIPLV;
        if (vipLvs == null || vipLvs.Length < 1) return false;
        for (int i = 0; i < vipLvs.Length; i++)
        {
            var vipLv = vipLvs[i];
            if (vipLv != 0)
            {
                isVipBuy = true;
            }
        }
        if (isVipBuy)
        {
            int playerVip = PlayerDatas.Instance.baseData.VIPLv;
            for (int i = vipLvs.Length - 1; i > -1; i--)
            {
                var vipLv = vipLvs[i];
                if (vipLv > playerVip)
                {
                    nextVipIndex = i;
                }
                else if (vipLv <= playerVip)
                {
                    curVipIndex = i;
                    break;
                }
            }
        }
        return isVipBuy;
    }
    public List<StoreData> TryGetStoreDatasByLimit(int type, int limitValue)
    {
        string key = StringUtility.Contact(type, limitValue);
        List<StoreData> datas = null;
        limitValueShopDict.TryGetValue(key, out datas);
        return datas;
    }
    #endregion
    public string GetMysteryStoreRefreshTime()
    private void RefreshDay()
    {
        if (GeneralDefine.mysteryShopRefreshInterval == 0)
        {
            return "";
        }
        var seconds = GeneralDefine.mysteryShopRefreshInterval -
             (int)((TimeUtility.ServerNow - TimeUtility.createRoleTime).TotalSeconds) % GeneralDefine.mysteryShopRefreshInterval;
        return Language.Get("StoreWin200", TimeUtility.SecondsToHMS(seconds));
    }
    private int GetWillRefreshTime()
    {
        int willRefresh = (3 - TimeUtility.OpenDay % 3);
        if (willRefresh == 3)
        {
            if (TimeUtility.ServerNow.Hour < 5)
            {
                willRefresh = 0;
            }
        }
        int remainHour = 5 - TimeUtility.ServerNow.Hour;
        int remainMinute = 0 - TimeUtility.ServerNow.Minute;
        int remainSecond = willRefresh * 24 * 60 * 60 + remainHour * 60 * 60 + remainMinute * 60 - TimeUtility.ServerNow.Second;
        return remainSecond;
    }
    int refreshTime = 0;
    private void UpdateSecond()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return;
        if (isUpdatePlayerLv)
        {
            UpdatePlayerLv();
            isUpdatePlayerLv = false;
        }
    }
    private void UpdatePlayerLv()
    {
        UpdateShowStore();
        UpdateFreeShopRedpoint();
        UpdateCanBuyRedpoint();
        UpdateMustBuyRedpoint();
    }
    private void RefreshPlayerData(PlayerDataType type)
    void EnterOrQuitGuildEvent(bool isEnter)
    {
        if (type == PlayerDataType.VIPLv)
        {
            UpdateShowStore();
        }
        switch (type)
        {
            case PlayerDataType.LV:
                isUpdatePlayerLv = true;
                break;
            case PlayerDataType.VIPLv:
            case PlayerDataType.Gold:
            case PlayerDataType.GoldPaper:
                UpdateFreeShopRedpoint();
                UpdateCanBuyRedpoint();
                UpdateDailyRedpoinit();
                break;
            case PlayerDataType.UnionLiven:
                UpdateDailyRedpoinit();
                break;
            case PlayerDataType.FBHelpPoint:
                UpdateFreeShopRedpoint();
                UpdateCanBuyRedpoint();
                break;
        }
    }
    private void RefreshFamilyLv()
    {
        int familyLv = PlayerDatas.Instance.fairyData.fairy.FamilyLV;
        if (familyLv > GetSaveFairyLV())
        {
            ControllerRedPoint();
        }
        UpdateDailyRedpoinit();
    }
    private void RefreshServerHour()
    {
        ControllerRedPoint();
        if (PlayerPrefs.HasKey(MUSTBUYSAVE_KEY))
        {
            int[] records = LocalSave.GetIntArray(MUSTBUYSAVE_KEY);
            if (TimeUtility.ServerNow.Hour >= 5
                && ((TimeUtility.ServerNow.Day == records[0] && records[1] < 5)
                || TimeUtility.ServerNow.Day != records[0]))
            {
                saveTimes[0] = TimeUtility.ServerNow.Day;
                saveTimes[1] = TimeUtility.ServerNow.Hour;
                IsMustBuyDay = true;
                LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes);
                UpdateMustBuyRedpoint();
            }
        }
        if (!PlayerDatas.Instance.fairyData.HasFairy)
        {
            PlayerPrefs.DeleteKey(UNIONSTORESAVE_KEY);
        }
        UpdateDailyRedpoinit();
    }
    public event Action RefreshBuyShopLimitEvent;
    public StoreFunc storeFuncType = StoreFunc.DayStore;
    public int jumpStoreFuncType { get; set; }
    private Dictionary<uint, BuyShopItemLimit> shopItemlimitDict = new Dictionary<uint, BuyShopItemLimit>();
    /// <summary>
    /// 得到物品购买次数
    /// </summary>
    /// <param name="buylimit"></param>
    public void RefreshBuyShopLimitModel(HA802_tagMCShopItemDayBuyCntInfo buylimit)
    {
        Debug.Log("RefreshBuyShopLimitModel" + buylimit.Count);
        if (buylimit.Count > 0)
    public void RefreshBuyShopLimitModel(HA802_tagSCShopItemBuyCntInfo buylimit)
        {
            int i = 0;
            for (i = 0; i < buylimit.Count; i++)
            {
                if (!shopItemlimitDict.ContainsKey(buylimit.DayBuyCntList[i].ItemIndex))
                {
                    BuyShopItemLimit shopItemLimit = new BuyShopItemLimit();
                    shopItemLimit.ItemIndex = buylimit.DayBuyCntList[i].ItemIndex;
                    shopItemLimit.BuyCnt = (int)buylimit.DayBuyCntList[i].BuyCnt;
                    shopItemLimit.isReset = buylimit.DayBuyCntList[i].IsReset;
                    shopItemlimitDict.Add(shopItemLimit.ItemIndex, shopItemLimit);
                }
                else
                {
                    shopItemlimitDict[buylimit.DayBuyCntList[i].ItemIndex].BuyCnt = (int)buylimit.DayBuyCntList[i].BuyCnt;
                    shopItemlimitDict[buylimit.DayBuyCntList[i].ItemIndex].isReset = buylimit.DayBuyCntList[i].IsReset;
                }
            shopItemlimitDict[(int)buylimit.BuyCntList[i].ShopID] = (int)buylimit.BuyCntList[i].BuyCnt;
            }
        }
        sortStoreSecondType = true;
        UpdateShowStore();
        UpdateFreeShopRedpoint();
        UpdateCanBuyRedpoint();
        UpdateMustBuyRedpoint();
        UpdateDailyRedpoinit();
        if (RefreshBuyShopLimitEvent != null)
            RefreshBuyShopLimitEvent();
    }
    public BuyShopItemLimit GetBuyShopLimit(uint itemIndex)
    // 限购商品已购买次数
    public int GetShopLimitBuyCount(int shopID)
    {
        if (shopItemlimitDict.ContainsKey(itemIndex))
        if (shopItemlimitDict.ContainsKey(shopID))
        {
            return shopItemlimitDict[itemIndex];
            return shopItemlimitDict[shopID];
        }
        return null;
        return 0;
    }
    public void UpdateRefreshItemInfo(HA803_tagSCShopRefreshItemInfo netPack)
    {
        storeTypeDict.Remove(netPack.ShopType);
        shopRefreshCntDict[netPack.ShopType] = netPack.RefreshCnt;
        List<int> resortList = new List<int>();
        for (int i = 0; i < netPack.ShopIDList.Length; i++)
        {
            var config = StoreConfig.Get((int)netPack.ShopIDList[i]);
            //UnlockType 2 由服务端通知
            StoreData storeData = new StoreData();
            storeData.shopId = config.ID;
            storeData.storeConfig = config;
            if (!storeTypeDict.ContainsKey(config.ShopType))
            {
                List<StoreData> storeDatas = new List<StoreData>();
                storeDatas.Add(storeData);
                storeTypeDict.Add(config.ShopType, storeDatas);
            }
            else
            {
                storeTypeDict[config.ShopType].Add(storeData);
            }
        }
        if (storeTypeDict.ContainsKey(netPack.ShopType))
        {
            var configs = storeTypeDict[netPack.ShopType];
            configs.Sort(CompareByShopSort);
        }
        RefreshShopEvent?.Invoke();
    }
    //和GetShopItemlistEx 一样 获取商店物品列表,只是返回类型不同
    List<ShopItemInfo> shopItemlist = new List<ShopItemInfo>();
    public List<ShopItemInfo> GetShopItemlistByIndex(StoreConfig storeConfig)
    {
        if (storeConfig == null) return null;
        List<ShopItemInfo> shopItemlist = new List<ShopItemInfo>();
        shopItemlist.Clear();
        if (storeConfig.ItemID != 0)
        {
            int replaceId = GetReplaceId(storeConfig.ID, storeConfig.ItemID);
            ShopItemInfo shopItem = new ShopItemInfo(replaceId, storeConfig.ItemCnt);
            ShopItemInfo shopItem = new ShopItemInfo(storeConfig.ID, storeConfig.ItemCnt);
            shopItemlist.Add(shopItem);
        }
        JsonData extraItem = JsonMapper.ToObject(storeConfig.ItemListEx);
        if (extraItem.IsArray)
        var extraItem = storeConfig.ItemListEx;
        if (extraItem != null)
        {
            for (int i = 0; i < extraItem.Count; i++)
            for (int i = 0; i < extraItem.Length; i++)
            {
                if (extraItem[i].IsArray)
                {
                    if (extraItem[i].Count > 0)
                    {
                        int itemId = int.Parse(extraItem[i][0].ToString());
                        int itemCount = int.Parse(extraItem[i][1].ToString());
                        if (itemId != 0)
                        {
                            int extraReplaceId = GetReplaceId(storeConfig.ID, itemId);
                            ShopItemInfo shop = new ShopItemInfo(extraReplaceId, itemCount);
                ShopItemInfo shop = new ShopItemInfo(extraItem[i][0], extraItem[i][1]);
                            shopItemlist.Add(shop);
                        }
                    }
                }
            }
        }
        return shopItemlist;
@@ -879,10 +339,9 @@
        List<int[]> shopItemlist = new List<int[]>();
        if (storeConfig.ItemID != 0)
        {
            int replaceId = GetReplaceId(storeConfig.ID, storeConfig.ItemID);
            shopItemlist.Add(new int[] { replaceId, storeConfig.ItemCnt, 0 });
            shopItemlist.Add(new int[] { storeConfig.ID, storeConfig.ItemCnt});
        }
        var extraItem = JsonMapper.ToObject<int[][]>(storeConfig.ItemListEx);
        var extraItem = storeConfig.ItemListEx;
        for (int i = 0; i < extraItem.Length; i++)
        {
            shopItemlist.Add(extraItem[i]);
@@ -890,79 +349,21 @@
        return shopItemlist;
    }
    public bool TryGetShopItemInfo(StoreFunc _type, int _id, out List<ShopItemInfo> _shopItems)
    public bool TryGetShopItemInfo(int _id, out List<ShopItemInfo> _shopItems)
    {
        _shopItems = null;
        var _list = TryGetStoreDatas(_type);
        var _index = _list.FindIndex((x) =>
        {
            return x.shopId == _id;
        });
        if (_index == -1)
        {
            return false;
        }
        _shopItems = GetShopItemlistByIndex(_list[_index].storeConfig);
        _shopItems = GetShopItemlistByIndex(StoreConfig.Get(_id));
        return _shopItems != null;
    }
    #region 点击商店物品逻辑
    public void OnClickShopCell(StoreConfig shopInfo)
    {
        int itemId = GetReplaceId(shopInfo.ID, shopInfo.ItemID);
        ItemTipUtility.Show(itemId);
    }
    public int BuyCnt { get; private set; }
    public void SetBuyCnt(int buyCnt)
    {
        BuyCnt = buyCnt;
    }
    #endregion
    private long _price;
    public void SendBuyShopItem(StoreConfig model, int count)
    {
        _price = model.MoneyNumber * count;
        if (MoneyIsEnough(model.MoneyType, _price))
        if (UIHelper.CheckMoneyCount(model.MoneyType, model.MoneyNum * count, 2))
        {
            var vipLv = PlayerDatas.Instance.baseData.VIPLv;
            var itemMinLv = model.VIPLV[0];
            if (vipLv < itemMinLv)
            {
                SysNotifyMgr.Instance.ShowTip("VIPNotEnough", itemMinLv);
            }
            else
            {
                CA310_tagCMBuyItem buyShop = new CA310_tagCMBuyItem();
                buyShop.BuyItemIndex = (ushort)model.ID;
            CA310_tagCSBuyItem buyShop = new CA310_tagCSBuyItem();
            buyShop.ShopID = (ushort)model.ID;
                buyShop.BuyCount = (uint)count;
                GameNetSystem.Instance.SendInfo(buyShop);
            }
        }
        else
        {
            switch (model.MoneyType)
            {
                case 1:
                    if (VersionConfig.Get().isBanShu)
                    {
                        SysNotifyMgr.Instance.ShowTip("GoldErr");
                        return;
                    }
                    // WindowCenter.Instance.Open<RechargeTipWin>();
                    break;
                case 25:
                    SysNotifyMgr.Instance.ShowTip("LackXBMoney", model.MoneyType);
                    break;
                default:
                    SysNotifyMgr.Instance.ShowTip("LackMoney", model.MoneyType);
                    break;
            }
        }
    }
@@ -972,7 +373,7 @@
    //eventType 二次确认框类型,对应枚举 BuyStoreItemCheckType
    public void SendBuyShopItemWithPopCheck(StoreConfig model, int count, int eventType = 0)
    {
        if (model.MoneyNumber == 0)
        if (model.MoneyNum == 0)
        {
            //免费的
            SendBuyShopItem(model, count);
@@ -985,8 +386,8 @@
            return;
        }
        ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("OSTimeLimitGiftConfirm", model.MoneyNumber),
        Language.Get("ConfirmCancel102"), (Action<bool, bool>)((bool isOk, bool isToggle) =>
        ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("CostMoney", model.MoneyNum, model.MoneyType),
        Language.Get("ConfirmCancel102"), (bool isOk, bool isToggle) =>
        {
            if (isOk)
            {
@@ -994,7 +395,7 @@
                buyItemCheckDict[eventType] = isToggle;
            }
            
        }));
        });
    }
    //花仙玉购买的二次确认框(本次登录)
@@ -1028,640 +429,126 @@
    public event Action<int> RefreshBuyResultEvent;
    public void GetBuyResult(HA811_tagMCShoppingResult result)
    {
        //Debug.Log("GetBuyResult");
        StoreConfig tagStore = StoreConfig.Get((int)result.ItemIndex);
        if (tagStore != null)
        {
            ItemConfig chinModel = ItemConfig.Get(GetReplaceId(tagStore.ID, tagStore.ItemID));
            if (tagStore.RemindSuccess == 0)
            {
                return;
            }
            if (RefreshBuyResultEvent != null)
            {
                RefreshBuyResultEvent(chinModel.ID);
            }
        }
    }
    public bool MoneyIsEnough(int moneyType, long money)
    {
        if (UIHelper.GetMoneyCnt(moneyType) < money)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    public int funcOrder { get; private set; }
    public int jumpToItemId { get; set; }
    /// <summary>
    /// 会先清之前的跳转,调用者要注意 ClearJump
    /// </summary>
    /// <param name="itemId"></param>
    public void SetJumpToModel(int itemId)
    {
        ClearJump();
        jumpToItemId = itemId;
    }
    public void ClearJump()
    {
        funcOrder = -1;
        jumpToItemId = 0;
    }
    public void SetWinOrder(int order)
    {
        funcOrder = order;
    }
    public void OpenStoreWin(bool forceSync = false, int functionOrder = 0, bool useJump = false)
    {
        if (useJump && funcOrder != -1)
        {
            // WindowCenter.Instance.Open<StoreWin>(forceSync, funcOrder);
        }
        else
        {
            ClearJump();
            // WindowCenter.Instance.Open<StoreWin>(forceSync, functionOrder);
        }
    }
    public event Action StoreFuncOpenAct;
    private void FuncStateChange(int funcId)
    {
        switch ((FuncOpenEnum)funcId)
        {
            case FuncOpenEnum.Store:
                if (StoreFuncOpenAct != null)
                {
                    StoreFuncOpenAct();
                }
                UpdateFreeShopRedpoint();
                UpdateCanBuyRedpoint();
                UpdateMustBuyRedpoint();
                UpdateDailyRedpoinit();
                break;
            // case FuncOpenEnum.BlastFurnace:
            //     ControllerRedPoint();
            //     break;
        }
    }
    public bool IsNewDay(string recordKey)
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return false;
        if (PlayerPrefs.HasKey(recordKey))
        {
            int day = LocalSave.GetInt(recordKey);
            if (day != TimeUtility.ServerNow.Day)
            {
                LocalSave.SetInt(recordKey, TimeUtility.ServerNow.Day);
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            LocalSave.SetInt(recordKey, TimeUtility.ServerNow.Day);
            return true;
        }
    }
    public bool IsRequireDailyRedRemind(int shopId)
    {
        var config = StoreConfig.Get(shopId);
        if (config == null)
        {
            return false;
        }
        var key = StringUtility.Contact("Store_", config.ShopType, "_", "Daily", shopId);
        var array = LocalSave.GetIntArray(key);
        if (array != null && array.Length == 2)
        {
            if (array[0] < TimeUtility.Day - 1)
            {
                return true;
            }
            else if (array[0] == TimeUtility.Day - 1)
            {
                return array[1] < 5 || TimeUtility.Hour >= 5;
            }
            else if (array[0] == TimeUtility.Day)
            {
                return array[1] < 5 && TimeUtility.Hour >= 5;
            }
        }
        return true;
    }
    public void SetDailyRedRedmind(int shopId)
    {
        var config = StoreConfig.Get(shopId);
        if (config == null)
        {
            return;
        }
        var key = StringUtility.Contact("Store_", config.ShopType, "_", "Daily", shopId);
        LocalSave.SetIntArray(key, new int[2] { TimeUtility.Day, TimeUtility.Hour });
        UpdateDailyRedpoinit();
    }
    #region 商城红点
    #region 仙盟红点逻辑处理
    private bool CheckIsBuyNewItem(int fairyLv)
    {
        if (fairyLv > GetSaveFairyLV())
        {
            var toolStoreDatas = TryGetStoreDatasByLimit((int)StoreFunc.ToolStore, fairyLv);
            var mountStoreDatas = TryGetStoreDatasByLimit((int)StoreFunc.MountStoneStore, fairyLv);
            var skillBookStoreData = TryGetStoreDatasByLimit((int)StoreFunc.MountSkillBookStore, fairyLv);
            if ((toolStoreDatas != null && toolStoreDatas.Count > 0)
                || (mountStoreDatas != null && mountStoreDatas.Count > 0)
                || (skillBookStoreData != null && skillBookStoreData.Count > 0))
            {
                return true;
            }
        }
        return false;
    }
    private bool CheckIsNewMonth()
    {
        GetSaveDateTime();
        if (datelist.Count > 0)
        {
            if (TimeUtility.ServerNow.Month == datelist[0])
            {
                if (TimeUtility.ServerNow.Day >= 1
                    && TimeUtility.ServerNow.Hour >= 5
                    && datelist[1] <= 1 && datelist[2] < 5)
                {
                    return true;
                }
            }
            else
            {
                if (TimeUtility.ServerNow.Day >= 1
                    && TimeUtility.ServerNow.Hour >= 5)
                {
                    return true;
                }
            }
        }
        return false;
    }
    List<int> datelist = new List<int>();
    public List<int> GetSaveDateTime()
    {
        datelist.Clear();
        int[] unionArray = LocalSave.GetIntArray(UNIONSTORESAVE_KEY);
        if (unionArray != null && unionArray.Length >= 4)
        {
            datelist.Add(unionArray[1]);
            datelist.Add(unionArray[2]);
            datelist.Add(unionArray[3]);
        }
        return datelist;
    }
    public int GetSaveFairyLV()
    {
        int[] unionArray = LocalSave.GetIntArray(UNIONSTORESAVE_KEY);
        int fairyLv = 0;
        if (unionArray != null)
        {
            return unionArray[0];
        }
        return fairyLv;
    }
    //1仙盟等级 2 月份 3 号 4 几点
    public void SetStoreLocalSave(LocalSaveStoreType saveStoreType, params int[] infos)
    {
        string key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, saveStoreType);
        LocalSave.SetIntArray(key, infos);
    }
    public void ControllerRedPoint(bool isLook = false)
    {
        fairyStoreRemindRedpoint.state = RedPointState.None;
        // if (!FairyModel.Instance.fairyStoreOpen
        //     || !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.BlastFurnace))
        // {
        //     return;
        // }
        int familyLv = PlayerDatas.Instance.fairyData.fairy.FamilyLV;
        if (!isLook)
        {
            if (CheckIsBuyNewItem(familyLv))
            {
                fairyStoreRemindRedpoint.state = RedPointState.Simple;
                return;
            }
            if (CheckIsNewMonth())
            {
                fairyStoreRemindRedpoint.state = RedPointState.Simple;
                return;
            }
        }
        SetStoreLocalSave(LocalSaveStoreType.UnionStore, familyLv, TimeUtility.ServerNow.Month,
                TimeUtility.ServerNow.Day, TimeUtility.ServerNow.Hour);
    }
    #endregion
    public const int StoreFunc_RedKey = 22;
    public const int StoreFunc1_RedKey = 2201;
    public const int StoreFunc2_RedKey = 2202;
    public const int StoreFunc3_RedKey = 2203;
    public const int StoreFunc4_RedKey = 2204;
    public const int StoreFunc5_RedKey = 2205;
    public const int StoreFunc8_RedKey = 2208;
    public const int FairyStoreRemind_RedKey = 107010601;
    public Redpoint storeFuncPoint = new Redpoint(StoreFunc_RedKey);
    public Redpoint storeFunc1Point = new Redpoint(StoreFunc_RedKey, StoreFunc1_RedKey);
    public Redpoint storeFunc2Point = new Redpoint(StoreFunc_RedKey, StoreFunc2_RedKey);
    public Redpoint storeFunc3Point = new Redpoint(StoreFunc_RedKey, StoreFunc3_RedKey);
    public Redpoint storeFunc4Point = new Redpoint(StoreFunc_RedKey, StoreFunc4_RedKey);
    public Redpoint storeFunc5Point = new Redpoint(StoreFunc_RedKey, StoreFunc5_RedKey);
    public Redpoint storeFunc8Point = new Redpoint(MainRedDot.FAIRYStore_REDPOINT_KEY3, StoreFunc8_RedKey);
    public Redpoint fairyStoreRemindRedpoint = new Redpoint(MainRedDot.FAIRYStore_REDPOINT_KEY3, FairyStoreRemind_RedKey);
    public Dictionary<int, Redpoint> shopRedDict = new Dictionary<int, Redpoint>();
    public void SetShopRedpoint()
    {
        shopRedDict.Clear();
        List<StoreConfig> storelist = StoreConfig.GetValues();
        for (int i = 0; i < storelist.Count; i++)
        {
            StoreConfig storeConfig = storelist[i];
            int redKey = 0;
            Redpoint redpoint = null;
            switch (storeConfig.ShopType)
            {
                //case 1:
                //    redKey = StoreFunc1_RedKey * 10000 + storeConfig.ID;
                //    redpoint = new Redpoint(StoreFunc1_RedKey, redKey);
                //    shopRedDict.Add(storeConfig.ID, redpoint);
                //    break;
                //case 2:
                //    redKey = StoreFunc2_RedKey * 10000 + storeConfig.ID;
                //    redpoint = new Redpoint(StoreFunc2_RedKey, redKey);
                //    shopRedDict.Add(storeConfig.ID, redpoint);
                //    break;
                //case 3:
                //    redKey = StoreFunc3_RedKey * 10000 + storeConfig.ID;
                //    redpoint = new Redpoint(StoreFunc3_RedKey, redKey);
                //    shopRedDict.Add(storeConfig.ID, redpoint);
                //    break;
                //case 4:
                //    redKey = StoreFunc4_RedKey * 10000 + storeConfig.ID;
                //    redpoint = new Redpoint(StoreFunc4_RedKey, redKey);
                //    shopRedDict.Add(storeConfig.ID, redpoint);
                //    break;
                //case 5:
                //    redKey = StoreFunc5_RedKey * 10000 + storeConfig.ID;
                //    redpoint = new Redpoint(StoreFunc5_RedKey, redKey);
                //    shopRedDict.Add(storeConfig.ID, redpoint);
                //    break;
                case 8:
                    redKey = StoreFunc8_RedKey * 10000 + storeConfig.ID;
                    redpoint = new Redpoint(StoreFunc8_RedKey, redKey);
                    shopRedDict.Add(storeConfig.ID, redpoint);
                    break;
            }
        }
    }
    Redpoint storeRedpoint = new Redpoint(MainRedDot.RightFuncRedpoint, MainRedDot.Store_REDPOINT);
    Redpoint normalRedpoint = new Redpoint(MainRedDot.Store_REDPOINT, MainRedDot.Store_REDPOINT * 10 + 1);
    Redpoint guildRedpoint = new Redpoint(MainRedDot.Store_REDPOINT, MainRedDot.Store_REDPOINT * 10 + 2);
    public void UpdateFreeShopRedpoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return;
        foreach (var key in showStoreTypeDict.Keys)
        {
            var storeDatas = showStoreTypeDict[key];
            for (int i = 0; i < storeDatas.Count; i++)
            {
                var storeConfig = storeDatas[i].storeConfig;
                int type = 0;
                TryGetRedTypeByShopId(storeConfig.ID, out type);
                if (type == 1)
                {
                    int remainNum = 0;
                    if (shopRedDict.ContainsKey(storeConfig.ID))
                    {
                        if (!TryGetIsSellOut(storeConfig, out remainNum))
                        {
                            shopRedDict[storeConfig.ID].state = RedPointState.Simple;
                        }
                        else
                        {
                            shopRedDict[storeConfig.ID].state = RedPointState.None;
                        }
                    }
                }
            }
        normalRedpoint.state = RedPointState.None;
        guildRedpoint.state = RedPointState.None;
        }
    }
        if (freeShopDict.Count == 0) return;
    public void UpdateCanBuyRedpoint()
        if (freeShopDict.ContainsKey((int)StoreFunc.Normal))
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return;
            var shopList = freeShopDict[(int)StoreFunc.Normal];
        foreach (var key in showStoreTypeDict.Keys)
            for (int i = 0; i < shopList.Count; i++)
        {
            var storeDatas = showStoreTypeDict[key];
            for (int i = 0; i < storeDatas.Count; i++)
                var shopID = shopList[i];
                var config = StoreConfig.Get(shopID);
                if (shopItemlimitDict.ContainsKey(shopID))
            {
                var storeConfig = storeDatas[i].storeConfig;
                int type = 0;
                TryGetRedTypeByShopId(storeConfig.ID, out type);
                if (type == 4)
                    if (shopItemlimitDict[shopID] < config.LimitCnt)
                {
                    int remainNum = 0;
                    if (shopRedDict.ContainsKey(storeConfig.ID))
                    {
                        if (!TryGetIsSellOut(storeConfig, out remainNum))
                        {
                            if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= storeConfig.MoneyNumber)
                            {
                                shopRedDict[storeConfig.ID].state = RedPointState.Simple;
                            }
                            else
                            {
                                shopRedDict[storeConfig.ID].state = RedPointState.None;
                        normalRedpoint.state = RedPointState.Simple;
                        break;
                            }
                        }
                        else
                        {
                            shopRedDict[storeConfig.ID].state = RedPointState.None;
                        }
                    }
                }
            }
        }
    }
    public void UpdateMustBuyRedpoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return;
        foreach (var key in showStoreTypeDict.Keys)
        {
            var storeDatas = showStoreTypeDict[key];
            for (int i = 0; i < storeDatas.Count; i++)
            {
                var storeConfig = storeDatas[i].storeConfig;
                int type = 0;
                TryGetRedTypeByShopId(storeConfig.ID, out type);
                if (type == 2)
                {
                    if (shopRedDict.ContainsKey(storeConfig.ID))
                    {
                        if (CheckIsMustBuy(storeConfig))
                        {
                            shopRedDict[storeConfig.ID].state = RedPointState.Simple;
                        }
                        else
                        {
                            shopRedDict[storeConfig.ID].state = RedPointState.None;
                        }
                    }
                }
            }
        }
    }
    public void UpdateDailyRedpoinit()
    {
        if (storeRedRuleDict.ContainsKey(6))
        {
            var shopIds = storeRedRuleDict[6];
            var count = 0;
            foreach (var shopId in shopIds)
            {
                var redable = false;
                var config = StoreConfig.Get(shopId);
                if (config == null)
                {
                    Debug.LogError($"StoreConfig {shopId} is null");
                    continue;
                }
                switch (config.ShopType)
                {
                    case 8:
                        if (TryGetIsSellOut(config, out count))
                        {
                    normalRedpoint.state = RedPointState.Simple;
                            break;
                        }
                        if (PlayerDatas.Instance.fairyData.fairy == null)
            }
        }
        if (PlayerDatas.Instance.fairyData.HasFairy && freeShopDict.ContainsKey((int)StoreFunc.Guild))
                        {
            var shopList = freeShopDict[(int)StoreFunc.Guild];
            for (int i = 0; i < shopList.Count; i++)
            {
                var shopID = shopList[i];
                var config = StoreConfig.Get(shopID);
                if (shopItemlimitDict.ContainsKey(shopID))
                {
                    if (shopItemlimitDict[shopID] < config.LimitCnt)
                    {
                        guildRedpoint.state = RedPointState.Simple;
                            break;
                        }
                        if (config.VIPLV.Length > 0
                            && PlayerDatas.Instance.baseData.VIPLv < config.VIPLV[0])
                        {
                            break;
                        }
                        if (PlayerDatas.Instance.fairyData.fairy.FamilyLV < config.LimitValue)
                        {
                            break;
                        }
                        if (!MoneyIsEnough(config.MoneyType, config.MoneyNumber))
                        {
                            break;
                        }
                        redable = IsRequireDailyRedRemind(shopId);
                        break;
                }
                if (shopRedDict.ContainsKey(shopId))
                {
                    shopRedDict[shopId].state = redable ? RedPointState.Simple : RedPointState.None;
                }
            }
        }
    }
    public void ClearMustBuyRedpoint(StoreConfig storeConfig)
    {
        if (!shopRedDict.ContainsKey(storeConfig.ID))
            return;
        int type = 0;
        TryGetRedTypeByShopId(storeConfig.ID, out type);
        if (type == 2)
        {
            shopRedDict[storeConfig.ID].state = RedPointState.None;
            IsMustBuyDay = false;
        }
        else if (type == 1)
        {
            shopRedDict[storeConfig.ID].state = RedPointState.None;
        }
    }
    public bool IsMustBuyDay { get; private set; }
    int[] saveTimes = new int[2];
    public void SetIsMustBuyDay()
    {
        if (IsMustBuyDay) return;
        saveTimes[0] = TimeUtility.ServerNow.Day;
        saveTimes[1] = TimeUtility.ServerNow.Hour;
        if (PlayerPrefs.HasKey(MUSTBUYSAVE_KEY))
        {
            int[] records = LocalSave.GetIntArray(MUSTBUYSAVE_KEY);
            if (TimeUtility.ServerNow.Hour >= 5
                && ((TimeUtility.ServerNow.Day == records[0] && records[1] < 5)
                || TimeUtility.ServerNow.Day != records[0]))
            {
                IsMustBuyDay = true;
                LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes);
            }
            else
            {
                IsMustBuyDay = false;
            }
        }
        else
        {
            IsMustBuyDay = true;
            LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes);
        }
    }
    public bool CheckIsMustBuy(StoreConfig config)
    {
        int remainNum = 0;
        if (!TryGetIsSellOut(config, out remainNum) && IsMustBuyDay)
        {
            return true;
        }
        return false;
    }
    public void ClearPetAndMountRedpoint(StoreConfig storeConfig)
    {
        ItemConfig itemConfig = ItemConfig.Get(storeConfig.ItemID);
        switch (itemConfig.Type)
        {
            case 26:
            case 41:
                string key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", storeConfig.ID);
                if (shopRedDict.ContainsKey(storeConfig.ID) && shopRedDict[storeConfig.ID].state == RedPointState.Simple)
                {
                    shopRedDict[storeConfig.ID].state = RedPointState.None;
                    LocalSave.SetBool(key, false);
                }
                    guildRedpoint.state = RedPointState.Simple;
                break;
        }
    }
    public void ClearAllPetAndMountRedpoint(StoreFunc storeFunc)
    {
        if (storeFuncType == StoreFunc.BindStore && storeFunc != StoreFunc.BindStore)
        {
            foreach (var key in shopRedDict.Keys)
            {
                StoreConfig storeConfig = StoreConfig.Get(key);
                ItemConfig itemConfig = ItemConfig.Get(storeConfig.ItemID);
                switch (itemConfig.Type)
                {
                    case 26:
                    case 41:
                        if (shopRedDict.ContainsKey(key) && shopRedDict[key].state != RedPointState.None)
                        {
                            string record = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", key);
                            shopRedDict[key].state = RedPointState.None;
                            LocalSave.SetBool(record, false);
                        }
                        break;
                }
            }
        }
    }
    public void CloseRedPoint(StoreConfig storeConfig)
    {
        ClearMustBuyRedpoint(storeConfig);
        ClearPetAndMountRedpoint(storeConfig);
    }
    public void CloseAllRedpoint(StoreFunc storeFunc)
    {
        ClearAllPetAndMountRedpoint(storeFunc);
    }
    #endregion
    public void RefreshStore(int shopType)
    {
        var pack = new CA232_tagCSRefreshShop();
        pack.ShopType = (ushort)shopType;
        GameNetSystem.Instance.SendInfo(pack);
    }
    
    //获取商品状态  0可购买 1已售罄 2免费 3未解锁
    public int GetShopIDState(int shopID)
    {
        var config = StoreConfig.Get(shopID);
        if (config.UnlockType == 1)
        {
            if (!PlayerDatas.Instance.fairyData.HasFairy ||
            PlayerDatas.Instance.fairyData.fairy.FamilyLV < config.UnlockValue)
            {
                return 3;
            }
        }
        if (config.LimitCnt != 0 && GetShopLimitBuyCount(shopID) >= config.LimitCnt)
        {
            return 1;
        }
        if (config.MoneyNum == 0)
        {
            return 2;
        }
        return 0;
    }
}
public enum StoreFunc
{
    DayStore = 1, //1:每天限购
    CommonStore = 2, //2:幻境阁商店
    GrowStrongerStore = 3, //3:成长变强
    BindStore = 4,  //4:绑玉商城
    IntegralStore = 5,  //5:积分商城
    BagStore = 6,  //6:随身商店
    RuneStore = 7,  //7:符印商店
    ToolStore = 8, // 道具商店
    MountStoneStore = 9, //坐骑魂石商店
    MountSkillBookStore = 10,//坐骑技能书商店
    XBEquipStore = 11, //寻宝装备商店
    XBRuneStore = 12, //寻宝符印商店
    XBToolStore = 13, //寻宝道具商店
    OSGift = 14,//开服礼包
    OSTimeLimitGift = 15,//限时特惠
    CrossOneVsOneHonor = 17,//荣誉商店
    MysteryStore = 18, //1:神秘商店
    default1,
    default2, //时间类活动 - 如boss凭证的商店 20
    default3,
    QCTrainActStore = 306, //骑宠养成活动商店
    CelestialPalaceStore = 308, //仙宫商店(天道阁)
}
public enum LocalSaveStoreType
{
    UnionStore, //仙盟商店
    Normal = 1, //1:坊市
    Guild = 2, //2:公会
    Hero = 3, //3:将魂
}
Main/System/Store/StoreWin.cs
New file
@@ -0,0 +1,179 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StoreWin : UIBase
{
    [SerializeField] OwnMoneyCell ownMoneyCellWithShop;
    //有刷新功能的商店
    [SerializeField] GameObject refreshGo;
    [SerializeField] Image refreshMoneyIcon;
    [SerializeField] Text refreshMoneyText;
    [SerializeField] Button refreshButton;
    [SerializeField] GroupButtonEx normalShopBtn;
    [SerializeField] GroupButtonEx guildShopBtn;
    [SerializeField] GroupButtonEx heroShopBtn;
    [SerializeField] ScrollerController scroller;
    protected override void InitComponent()
    {
        refreshButton.AddListener(RefreshStore);
        normalShopBtn.AddListener(() => { OnSelectStoreFuncType(1); });
        guildShopBtn.AddListener(() => { OnSelectStoreFuncType(2); });
        heroShopBtn.AddListener(() => { OnSelectStoreFuncType(3); });
    }
    protected override void OnPreOpen()
    {
        scroller.OnRefreshCell += OnRefreshCell;
        StoreModel.Instance.RefreshShopEvent += Display;
        StoreModel.Instance.RefreshBuyShopLimitEvent += Display;
        GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
        Display();
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        StoreModel.Instance.RefreshShopEvent -= Display;
        StoreModel.Instance.RefreshBuyShopLimitEvent -= Display;
        GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
        StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
    }
    void Display()
    {
        if (StoreModel.Instance.selectStoreFuncType == StoreFunc.Normal)
        {
            normalShopBtn.SelectBtn();
        }
        else if (StoreModel.Instance.selectStoreFuncType == StoreFunc.Guild)
        {
            guildShopBtn.SelectBtn();
        }
        else if (StoreModel.Instance.selectStoreFuncType == StoreFunc.Hero)
        {
            heroShopBtn.SelectBtn();
        }
        guildShopBtn.SetColorful(null, PlayerDatas.Instance.fairyData.HasFairy);
        ShowMoney();
        CreateScroller();
    }
    void EnterOrQuitGuildEvent(bool isEnter)
    {
        if (!isEnter && StoreModel.Instance.selectStoreFuncType == StoreFunc.Guild)
        {
            StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
        }
        Display();
    }
    void CreateScroller()
    {
        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
        {
            return;
        }
        scroller.Refresh();
        var list = StoreModel.Instance.storeTypeDict[(int)StoreModel.Instance.selectStoreFuncType];
        for (int i = 0; i < list.Count; i++)
        {
            if (i % 3 == 0)
            {
                scroller.AddCell(ScrollerDataType.Header, i);
            }
        }
        scroller.Restart();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as StoreLineCell;
        _cell.Display(cell.index);
    }
    void ShowMoney()
    {
        if (!StoreModel.Instance.shopMoneyTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
        {
            return;
        }
        var moneyType = StoreModel.Instance.shopMoneyTypeDict[(int)StoreModel.Instance.selectStoreFuncType];
        ownMoneyCellWithShop.moneyType = moneyType;
        ownMoneyCellWithShop.Display(true);
        if (StoreModel.Instance.selectStoreFuncType == StoreFunc.Hero)
        {
            refreshGo.SetActive(true);
            refreshMoneyIcon.SetIconWithMoneyType(StoreModel.Instance.heroSoulRefreshMoneyType);
            if (StoreModel.Instance.shopRefreshCntDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
            {
                if (StoreModel.Instance.shopRefreshCntDict[(int)StoreModel.Instance.selectStoreFuncType] >=
                StoreModel.Instance.heroSoulRefreshFreeCount)
                {
                    refreshMoneyText.text = StoreModel.Instance.heroSoulRefreshMoney.ToString();
                }
                else
                {
                    refreshMoneyText.text = Language.Get("L1127");
                }
            }
            else
            {
                refreshMoneyText.text = Language.Get("L1127");
            }
        }
        else
        {
            refreshGo.SetActive(false);
        }
    }
    void RefreshStore()
    {
        if (StoreModel.Instance.selectStoreFuncType != StoreFunc.Hero)
        {
            return;
        }
        var useCnt = 0;
        if (StoreModel.Instance.shopRefreshCntDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
        {
            if (StoreModel.Instance.shopRefreshCntDict[(int)StoreModel.Instance.selectStoreFuncType] >=
            StoreModel.Instance.heroSoulRefreshFreeCount)
            {
                useCnt = StoreModel.Instance.heroSoulRefreshMoney;
            }
        }
        if (UIHelper.CheckMoneyCount(StoreModel.Instance.heroSoulRefreshMoneyType, useCnt, 2))
        {
            StoreModel.Instance.RefreshStore((int)StoreFunc.Hero);
        }
    }
    void OnSelectStoreFuncType(int index)
    {
        if (index == 2)
        {
            if (!PlayerDatas.Instance.fairyData.HasFairy)
            {
                SysNotifyMgr.Instance.ShowTip("NoGuild");
                return;
            }
        }
        StoreModel.Instance.selectStoreFuncType = (StoreFunc)index;
        Display();
    }
}
Main/System/Store/StoreWin.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta copy to Main/System/Store/StoreWin.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA8_Item/HA802_tagMCShopItemDayBuyCntInfo.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cbdb66c5b2f98534ca9f73a2b9b281e0
guid: 0986c3d06dfd5bb47a959ec12212f01e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/UIBase/OneLevelWin.cs
@@ -1,164 +1,51 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI; // DOTween 插件引用
using Cysharp.Threading.Tasks;
using UnityEngine.UI;
using System;
public class OneLevelWin : UIBase
// 一级界面带预制体,底部功能按钮样式
public class OneLevelWin : FunctionsBaseWin
{
    protected Image m_TitleIcon;
    protected FunctionButtonGroup m_Group;
    protected Button m_Left;
    protected Button m_Right;
    protected Button m_Close;
    protected Text m_Copper;
    protected Text m_Diamond;
    protected Text m_BindDiamond;
    protected RectTransform m_SubWindowContainer;
    public RectTransform subWindowContainer { get { return m_SubWindowContainer; } }
    private UIBase subWindow = null;
    //  init once
    [NonSerialized] GroupButtonEx tabBtn;
    public FuncBtnData[] funcBtnDatas;
    [NonSerialized] Button closeBtn;
    protected override void InitComponent()
    {
        // 创建
        var instance = UIUtility.CreateWidget("OneLevelWin", "BottomTabs");
        instance.transform.SetParentEx(_rectTransform, Vector3.zero, Quaternion.identity, Vector3.one);
        closeBtn = _rectTransform.GetComponent<Button>("BottomTabs/bg/backbtn");
        tabBtn = _rectTransform.GetComponent<GroupButtonEx>("BottomTabs/bg/btns/funcbtn");
        var btnParent = _rectTransform.GetComponent<RectTransform>("BottomTabs/bg/btns");
        tabButtons = new GroupButtonEx[funcBtnDatas.Length];
        for (int i = 0; i < tabButtons.Length; i++)
        {
            GameObject go = Instantiate(tabBtn.gameObject, btnParent);
            var data = funcBtnDatas[i];
            tabButtons[i] = go.GetComponent<GroupButtonEx>();
            tabButtons[i].selectIcon.SetSprite(data.iconName);
            tabButtons[i].selectIcon.SetNativeSize();
            tabButtons[i].title.text = Language.Get(data.name);
            tabButtons[i].redpoint.redpointId = data.redpointID;
            tabButtons[i].SetActive(true);
        }
        base.InitComponent();
        closeBtn.AddListener(CloseWindow);
    }
        // //  跟原版的差别
        Transform trans = transform;
        // if (_rectTransform != null)
        // {
        //     trans = _rectTransform;
        // }
        m_TitleIcon = trans.GetComponent<Image>("Pivot/Container_BackGround/Img_Title");
        m_Group = trans.GetComponent<FunctionButtonGroup>("Pivot/Container_Functions");
        m_Left = trans.GetComponent<Button>("Pivot/Container_Buttons/Btn_Left");
        m_Right = trans.GetComponent<Button>("Pivot/Container_Buttons/Btn_Right");
        m_Close = trans.GetComponent<Button>("Pivot/Container_Buttons/Btn_Close");
        m_Copper = trans.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/SilverCountBG/CountText");
        if (m_Copper != null)
            m_Diamond = trans.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/GoldCountBG/CountText");
            m_BindDiamond = trans.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/GoldPaperCountBG/CountText");
        m_SubWindowContainer = trans.GetComponent<RectTransform>("Pivot/Container_SubWindow");
        var name = gameObject.name;
        var infos = WindowConfig.GetWindowFunctionInfos(name);
        foreach (var info in infos)
    protected override void OpenSubUIByTabIndex()
        {
            var title = Language.Get(info.titleKey);
            if (title.Length == 2)
    }
}
[Serializable]
public struct FuncBtnData
            {
                title = title.Insert(1, " ");
            }
            m_Group.AddFunction("FunctionButton_Pattern_1", info.order, info.functionId, title, info.redPointId);
        }
        m_TitleIcon.SetSprite(WindowConfig.GetTitleIconKey(name));
        m_TitleIcon.SetNativeSize();
        m_Close.SetListener(CloseWindow);
        m_Left.SetListener(() => { m_Group.TriggerLast(); });
        m_Right.SetListener(() => { m_Group.TriggerNext(); });
    }
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        if (m_Copper == null)
            m_Copper = this.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/SilverCountBG/CountText");
            m_Diamond = this.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/GoldCountBG/CountText");
            m_BindDiamond = this.GetComponent<Text>("Pivot/Container_BackGround/FollowStoreBottom/GoldPaperCountBG/CountText");
        UpdateMoney();
    }
    protected override void OnPreClose()
    {
        base.OnPreClose();
        CloseSubWindows();
    }
    protected override void OnOpen()
    {
        base.OnOpen();
        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataUpdate;
        ExecuteNextFrame(() => {
            m_Group.TriggerByOrder(functionOrder);
            m_Group.GotoOrder(functionOrder);
        });
        m_Left.SetActive(m_Group.unLockedCount > 1);
        m_Right.SetActive(m_Group.unLockedCount > 1);
    }
    protected virtual void CloseSubWindows()
    {
        if (null != subWindow)
        {
            subWindow.CloseWindow();
        }
        subWindow = null;
    }
    public void SetFunctionListener(int order, Action callBack)
    {
        m_Group.SetFunctionListener(order, callBack);
    }
    public void SetFunctionButtonActive(int order, bool isShow)
    {
        m_Group.SetFunctionButtonActive(order, isShow);
    }
    public RedPointState GetFunctionButtonRedPointState(int order)
    {
        return m_Group.GetFunctionButtonRedPointState(order);
    }
    public void FunctionButtonInvoke(int order)
    {
        m_Group.TriggerByOrder(order);
        m_Group.GotoOrder(order);
    }
    private void OnPlayerDataUpdate(PlayerDataType type)
    {
        switch (type)
        {
            case PlayerDataType.Gold:
            case PlayerDataType.GoldPaper:
            case PlayerDataType.Silver:
            case PlayerDataType.ExAttr6:
            case PlayerDataType.default5:
            case PlayerDataType.default6:
                UpdateMoney();
                break;
        }
    }
    void UpdateMoney()
    {
        if (m_Copper == null)
            return;
        m_Copper.text = ItemLogicUtility.Instance.OnChangeCoinsUnit(PlayerDatas.Instance.baseData.allCopper);
        m_Diamond.text = UIHelper.GetMoneyCntEx(1).ToString();
        if (PlayerDatas.Instance.baseData.bindDiamond > 0)
            m_BindDiamond.text = ItemLogicUtility.Instance.OnChangeCoinsUnit(PlayerDatas.Instance.baseData.bindDiamond);
        else
            m_BindDiamond.text = UIHelper.GetMoneyCntEx(2).ToString();
    }
    public int redpointID;
    public string name;
    public string iconName; //默认显示的图标(选中)
}
Main/Utility/ComponentExtersion.cs
@@ -255,6 +255,39 @@
        }
    }
    public static void SetColorful(this GroupButtonEx _btn, Text _btnTxt, bool _colorful, int pattern = 0)
    {
        if (_btn != null)
        {
            if (_btn.selectIcon != null)
            {
                _btn.selectIcon.gray = !_colorful;
            }
            if (_btn.unSelectIcon != null)
            {
                _btn.unSelectIcon.gray = !_colorful;
            }
        }
        if (_btnTxt != null)
        {
            switch (pattern)
            {
                case 1:
                    _btnTxt.color = UIHelper.GetUIColor(_colorful ? TextColType.LightWhite : TextColType.White);
                    break;
                case 2:
                    _btnTxt.color = UIHelper.GetUIColor(_colorful ? TextColType.Green : TextColType.White);
                    break;
                default:
                    //false 灰色,true 原色
                    if (!_colorful)
                        _btnTxt.text = UIHelper.AppendColor(TextColType.NavyGray, _btnTxt.text);    //不改变组件颜色,只改变显示颜色
                    else
                        _btnTxt.text = UIHelper.AppendColor(_btnTxt.color, _btnTxt.text);
                    break;
            }
        }
    }
    // 设置按钮是否可点击,且取第一个文本组件置灰或置原色
    // 要先设置文本再调用该函数 因为没有改变文本组件的颜色避免颜色被还原,同理恢复可以不用改变颜色改文字即可
Main/Utility/EnumHelper.cs
@@ -698,7 +698,7 @@
    default31,
    default32,
    default33,  // 261 玉髓
    default34,  // 262 凭证积分
    default34,  // 262 将魂
    default35,  // 263 聚魂精华
    default36,  // 264 Boss最终伤害加成
    default37,  // 265 骑宠积分
@@ -820,7 +820,7 @@
    Realm = 10, //境界 官职
    Guild = 11,// 公会
    BlessLV = 12, //祝福等级
    Store = 16,//商城
    Store = 16,//坊市
    HappyFindTreasure = 18,// 英雄招募
    Chat = 19,//聊天
    AutoFight = 20,//自动战斗
Main/Utility/UIHelper.cs
@@ -75,6 +75,7 @@
        }
        else
        {
            // 暂不考虑富文本的情况
            // 不需要物品的情况补充
            // string iconKey = StringUtility.Contact("Money_Type_", moneyType);
            Debug.LogError("MoneyDisplayModel 未配置货币类型:" + moneyType);
@@ -85,6 +86,7 @@
    {
        if (IconConfig.HasKey("MoneyType_" + moneyType))
        {
            //富文本显示的情况
            return IconConfig.Get("MoneyType_" + moneyType).sprite;
        }
        else if (GeneralDefine.MoneyDisplayModel.ContainsKey(moneyType))
@@ -978,9 +980,12 @@
        {1, PlayerDataType.Gold},
        {2, PlayerDataType.GoldPaper},
        {3, PlayerDataType.Silver},
        {15, PlayerDataType.UnionLiven},
        {41, PlayerDataType.default26},
        {43, PlayerDataType.default34},
        {42, PlayerDataType.default33},
        {53, PlayerDataType.ChallengeVoucher},
        {99, PlayerDataType.ExAttr11},
    };
    public static long GetMoneyCnt(int moneyType)
@@ -1080,7 +1085,7 @@
                }
            case 43:
                {
                    //凭证积分
                    //将魂
                    return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.default34);
                }
            case 44: