yyl
2 天以前 9e89e605d5429babb4b33df2e47ea86dff9d2ba7
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
26个文件已修改
6个文件已添加
1212 ■■■■ 已修改文件
Main/Component/UI/Core/ButtonEx.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/ConfigManager.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/ConfigParse.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/ADAwardConfig.cs 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/ADAwardConfig.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/SDK/SDKUtils.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaManager.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/AdsCell.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/AdsCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/AdsManager.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/BoneFieldManager.cs 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/BoneFieldWin.cs 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/BoneFieldTabHandler.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/TianziBillboradTabHandler.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Dungeon/DungeonManager.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/BlessLVADWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/BlessLVManager.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Invest/InvestModel.cs 322 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/PackManager.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightModel.cs 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightWin.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/RightFuncInHome.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/PrivilegeActiveCardWin.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/PrivilegeActiveCardWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/PrivilegeCardCell.cs 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/PrivilegeCardCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/PrivilegeCardWin.cs 125 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Recharge/RechargeManager.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/MainRedDot.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TianziBillborad/TianziBillboradManager.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/TianziBillborad/TianziBillboradWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Core/ButtonEx.cs
@@ -9,7 +9,7 @@
    public event Action ableTimeChangeEvent;
    public float interval;
    public float interval = 0.5f;
    public bool customPositiveSound = false;
    public bool customNegativeSound = false;
    public int positiveSound = 0;
Main/Config/ConfigManager.cs
@@ -271,7 +271,6 @@
        ClearConfigDictionary<HorseClassConfig>();
        // 清空 HorseSkinConfig 字典
        ClearConfigDictionary<HorseSkinConfig>();
        // 清空 InvestConfig 字典
        // 清空 ItemCompoundConfig 字典
        ClearConfigDictionary<ItemCompoundConfig>();
        // 清空 ItemConfig 字典
Main/Config/ConfigParse.cs
@@ -320,13 +320,35 @@
        return result;
    }
    //json格式: {"1":{"1":1,"2":2},"2":{"3":3,"4":4}}
    public static Dictionary<int, Dictionary<int, int>> ParseDictInDict(string jsonStr)
    {
        if (jsonStr == "{}" || string.IsNullOrEmpty(jsonStr))
        {
            return new Dictionary<int, Dictionary<int, int>>();
        }
        var dict = JsonMapper.ToObject<Dictionary<string, Dictionary<string, int>>>(jsonStr);
        Dictionary<int, Dictionary<int, int>> result = new Dictionary<int, Dictionary<int, int>>();
        foreach (var item in dict)
        {
            Dictionary<int, int> subDict = new Dictionary<int, int>();
            foreach (var subItem in item.Value)
            {
                subDict[int.Parse(subItem.Key)] = subItem.Value;
            }
            result[int.Parse(item.Key)] = subDict;
        }
        return result;
    }
    //万分率转为每个id对应的概率 [[万分概率,id1],[万分概率,id2]]
    public static Dictionary<int, int> GetRateDict(int[][] rateArray)
    {
        Dictionary<int, int> dic = new Dictionary<int, int>();
        //概率为 减去上一个概率的值即为当前ID概率
        for (int i = 0;i< rateArray.Length; i++)
        for (int i = 0; i < rateArray.Length; i++)
        {
            if (i > 0)
            {
Main/Config/Configs/ADAwardConfig.cs
@@ -1,47 +1,50 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年10月9日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class ADAwardConfig : ConfigBase<int, ADAwardConfig>
{
    static ADAwardConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int ADID;
    public int ADCntMax;
    public int[][] ADAwardItemList;
    public int ADMapID;
    public override int LoadKey(string _key)
    {
        int key = GetKey(_key);
        return key;
    }
    public override void LoadConfig(string input)
    {
        try {
        string[] tables = input.Split('\t');
        int.TryParse(tables[0],out ADID);
            int.TryParse(tables[1],out ADCntMax);
            ADAwardItemList = JsonMapper.ToObject<int[][]>(tables[2].Replace("(", "[").Replace(")", "]"));
            int.TryParse(tables[3],out ADMapID);
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           Wednesday, November 19, 2025
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class ADAwardConfig : ConfigBase<int, ADAwardConfig>
{
    static ADAwardConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int ADID;
    public int ADCntMax;
    public int[][] ADAwardItemList;
    public int ADAwardType;
    public int ADAwardValue;
    public override int LoadKey(string _key)
    {
        int key = GetKey(_key);
        return key;
    }
    public override void LoadConfig(string input)
    {
        try {
        string[] tables = input.Split('\t');
        int.TryParse(tables[0],out ADID);
            int.TryParse(tables[1],out ADCntMax);
            ADAwardItemList = JsonMapper.ToObject<int[][]>(tables[2].Replace("(", "[").Replace(")", "]"));
            int.TryParse(tables[3],out ADAwardType);
            int.TryParse(tables[4],out ADAwardValue);
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/PartialConfigs/ADAwardConfig.cs
@@ -1,13 +1,19 @@
using System.Collections.Generic;
public partial class ADAwardConfig : ConfigBase<int, ADAwardConfig>
{
    private static Dictionary<int, int> idDict = new Dictionary<int, int>();
    private static Dictionary<Int2, ADAwardConfig> idDict = new Dictionary<Int2, ADAwardConfig>();
    protected override void OnConfigParseCompleted()
    {
        idDict[ADMapID] = ADID;
        idDict[new Int2(ADAwardType, ADAwardValue)] = this;
    }
    public static bool TryGetADIDByADMapID(int ADMapID, out int ADID)
    public static bool TryGetADIDByTypeValue(int type, int value, out ADAwardConfig config)
    {
        return idDict.TryGetValue(ADMapID, out ADID) && ADID > 0;
        if (idDict.TryGetValue(new Int2(type, value), out config))
        {
            return true;
        }
        return false;
    }
}
Main/SDK/SDKUtils.cs
@@ -966,7 +966,7 @@
            }
            else
            {
                ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("GameCashRule1", money), Language.Get("TodayNoNotify"), (bool isOk, bool isToggle) =>
                ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("GameCashRule1", money, title), Language.Get("TodayNoNotify"), (bool isOk, bool isToggle) =>
                {
                    if (isOk)
                    {
Main/System/Arena/ArenaManager.cs
@@ -121,7 +121,7 @@
    public int GetMaxChallengeCount()
    {
        return challengeTicketLimit;
        return challengeTicketLimit + InvestModel.Instance.GetArenaAddMaxCount();
    }
    public void OnArenaMatchList(HA922_tagSCArenaMatchList vNetData)
Main/System/BoneField/AdsCell.cs
New file
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
//广告小组件,可复制英雄招募里的
public class AdsCell : MonoBehaviour
{
    [SerializeField] Button adBtn;
    [SerializeField] Text cntText;
    public int adID;
    public int type;
    public int value;
    protected void OnEnable()
    {
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
        adBtn.AddListener(OnClickAds);
        OnAdsInfoListUpdateEvent(adID, type, value);
    }
    protected void OnDisable()
    {
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
    }
    private void OnAdsInfoListUpdateEvent(int _adID, int _type, int _value)
    {
        if (adID != _adID)
            return;
        int adsCnt = AdsManager.Instance.GetADCntByADID(adID);
        var aDAwardConfig = ADAwardConfig.Get(adID);
        bool isShowAds = adsCnt < aDAwardConfig.ADCntMax;
        int remainAdsCount = aDAwardConfig.ADCntMax - adsCnt;
        adBtn.SetActive(isShowAds);
        cntText.text = $"{remainAdsCount}/{aDAwardConfig.ADCntMax}";
    }
    // public void AddListener(UnityAction action)
    // {
    //     adBtn.AddListener(action);
    // }
    void OnClickAds()
    {
        AdsManager.Instance.PlayAds(adID);
    }
}
Main/System/BoneField/AdsCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20f5dfb2172d4004aa743824abe77f84
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BoneField/AdsManager.cs
@@ -4,7 +4,7 @@
{
    //<广告ID,今日已领取广告奖励次数>
    private Dictionary<int, int> adsInfoDict = new Dictionary<int, int>();
    public event Action<int, int> OnAdsInfoListUpdateEvent;//ADID ADMapID
    public event Action<int, int, int> OnAdsInfoListUpdateEvent;//ADID type value
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
@@ -20,7 +20,7 @@
        adsInfoDict.Clear();
    }
    public void SendGetReward(int ADID)
    void SendGetReward(int ADID)
    {
        var pack = new CA504_tagCMPlayerGetReward();
        pack.RewardType = 81;       //  广告奖励 81
@@ -28,6 +28,7 @@
        GameNetSystem.Instance.SendInfo(pack);
    }
    //如果有广告SDK接入,该函数改成回调触发
    public void PlayAds(int ADID)
    {
        switch (ADID)
@@ -39,15 +40,19 @@
                BoneFieldManager.Instance.SendBBeginFBWipeOut(BoneFieldManager.Instance.DataMapID, (int)fbInfo1.PassLineID);
                break;
            case 2:
                if (!DungeonManager.Instance.TryGetFBInfoByMapID(TianziBillboradManager.Instance.DataMapID, out var fbInfo2))
                    return;
                SendGetReward(ADID);
                BoneFieldManager.Instance.SendBBeginFBWipeOut(TianziBillboradManager.Instance.DataMapID, (int)fbInfo2.PassLineID);
                break;
            case 3:
            case 4:
                SendGetReward(ADID);
                break;
        }
    }
    //已获取广告奖励次数
    public int GetADCntByADID(int ADID)
    {
        if (adsInfoDict.IsNullOrEmpty() || !adsInfoDict.ContainsKey(ADID))
@@ -63,13 +68,14 @@
        {
            adsInfoDict[item.ADID] = item.ADCnt;
            int mapID = 0;
            if (ADAwardConfig.HasKey(item.ADID))
            if (!ADAwardConfig.HasKey(item.ADID))
            {
                ADAwardConfig aDAwardConfig = ADAwardConfig.Get(item.ADID);
                mapID = aDAwardConfig.ADMapID;
                continue;
            }
            OnAdsInfoListUpdateEvent?.Invoke(item.ADID, mapID);
            ADAwardConfig aDAwardConfig = ADAwardConfig.Get(item.ADID);
            var value = aDAwardConfig.ADAwardValue;
            var type = aDAwardConfig.ADAwardType;
            OnAdsInfoListUpdateEvent?.Invoke(item.ADID, type, value);
        }
    }
}
Main/System/BoneField/BoneFieldManager.cs
@@ -10,7 +10,7 @@
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
        TimeMgr.Instance.OnDayEvent += OnDayEvent;
@@ -19,7 +19,7 @@
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent -= OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
@@ -37,17 +37,16 @@
        UpdateRedPoint();
    }
    private void OnUpdateFBInfoChangeEvent(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    private void OnUpdateFBInfoChangeEvent(int mapID)
    {
        int dataMapID = DataMapID;
        if (mapID != dataMapID)
            return;
        if (isADAddCntChange)
            return;
        UpdateRedPoint();
    }
    private void OnAdsInfoListUpdateEvent(int id, int mapId)
    private void OnAdsInfoListUpdateEvent(int id, int type, int mapId)
    {
        if (mapId != DataMapID)
            return;
@@ -114,21 +113,9 @@
    public bool TryGetShowSweepCount(out int showSweepMaxCount, out int showrealRemainSweepCount)
    {
        showSweepMaxCount = 0;
        showrealRemainSweepCount = 0;
        int dataMapID = BoneFieldManager.Instance.DataMapID;
        if (!DungeonOpenTimeConfig.HasKey(dataMapID))
        if (!DungeonManager.Instance.TryGetDungeonCount(DataMapID, out showSweepMaxCount, out showrealRemainSweepCount))
            return false;
        if (!DungeonManager.Instance.TryGetFBInfoByMapID(dataMapID, out FBInfo fbInfo))
            return false;
        DungeonOpenTimeConfig dungeonOpenTimeConfig = DungeonOpenTimeConfig.Get(dataMapID);
        int baseCount = dungeonOpenTimeConfig.DayTimes + dungeonOpenTimeConfig.PayCntMax;
        int realMaxCount = baseCount + fbInfo.ADAddCnt + fbInfo.BuyAddCnt + fbInfo.ItemAddCnt;
        int realRemainSweepCount = realMaxCount - fbInfo.EnterCnt;
        showSweepMaxCount = realMaxCount - fbInfo.ADAddCnt - fbInfo.BuyAddCnt;
        showrealRemainSweepCount = realRemainSweepCount - fbInfo.BuyAddCnt;
        return true;
    }
Main/System/BoneField/BoneFieldWin.cs
@@ -43,7 +43,7 @@
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
        TimeMgr.Instance.OnDayEvent += OnDayEvent;
        Display();
@@ -52,36 +52,30 @@
    protected override void OnPreClose()
    {
        base.OnPreClose();
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent -= OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
    }
    private void OnUpdateFBInfoChangeEvent(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    private void OnUpdateFBInfoChangeEvent(int mapID)
    {
        int dataMapID = BoneFieldManager.Instance.DataMapID;
        if (mapID != dataMapID)
            return;
        if (!ADAwardConfig.TryGetADIDByADMapID(BoneFieldManager.Instance.DataMapID, out adID) || !ADAwardConfig.HasKey(adID))
        ADAwardConfig aDAwardConfig;
        if (!ADAwardConfig.TryGetADIDByTypeValue(2, BoneFieldManager.Instance.DataMapID, out aDAwardConfig))
            return;
        ADAwardConfig aDAwardConfig = ADAwardConfig.Get(adID);
        if (isADAddCntChange)
        {
            DisplayAdsButton(aDAwardConfig);
        }
        else
        {
            Display();
        }
        Display();
    }
    private void OnAdsInfoListUpdateEvent(int id, int mapId)
    private void OnAdsInfoListUpdateEvent(int id, int type, int mapId)
    {
        if (mapId != BoneFieldManager.Instance.DataMapID)
            return;
        if (!ADAwardConfig.TryGetADIDByADMapID(BoneFieldManager.Instance.DataMapID, out adID) || !ADAwardConfig.HasKey(adID))
        ADAwardConfig aDAwardConfig;
        if (!ADAwardConfig.TryGetADIDByTypeValue(2, BoneFieldManager.Instance.DataMapID, out aDAwardConfig))
            return;
        ADAwardConfig aDAwardConfig = ADAwardConfig.Get(adID);
        DisplayAdsButton(aDAwardConfig);
    }
@@ -107,6 +101,12 @@
        if (showrealRemainSweepCount == showSweepMaxCount)
        {
            BoneFieldManager.Instance.SendBBeginFBWipeOut(dataMapID, (int)fbInfo.PassLineID);
            return;
        }
        if (InvestModel.Instance.GetFBIsFree(dataMapID))
        {
            BoneFieldManager.Instance.SendBuyEnterCount(dataMapID);
            BoneFieldManager.Instance.SendBBeginFBWipeOut(dataMapID, (int)fbInfo.PassLineID);
            return;
        }
@@ -153,10 +153,10 @@
        if (bossId == 0 || !NPCConfig.HasKey(bossId))
            return;
        NPCConfig nPCConfig = NPCConfig.Get(bossId);
        if (!ADAwardConfig.TryGetADIDByADMapID(dataMapID, out adID) || !ADAwardConfig.HasKey(adID))
        ADAwardConfig aDAwardConfig;
        if (!ADAwardConfig.TryGetADIDByTypeValue(2, BoneFieldManager.Instance.DataMapID, out aDAwardConfig))
            return;
        ADAwardConfig aDAwardConfig = ADAwardConfig.Get(adID);
        adID = aDAwardConfig.ADID;
        DisplayFBInfo(nPCConfig, dungeonConfig, nowPassLineID);
        DisplayChallengeButton(dungeonConfig, fbInfo);
@@ -206,22 +206,32 @@
        imgSweep.gray = !isSweepCountOk;
        long myFightPower = PlayerDatas.Instance.baseData.FightPower;
        imgSweepRed.SetActive(isSweepCountOk && myFightPower < dungeonConfig.FightPower);
        txtFirstFree.SetActive(showSweepMaxCount == showrealRemainSweepCount);
        txtTodaySweepCount.SetActive(showSweepMaxCount > showrealRemainSweepCount);
        txtTodaySweepCount.text = UIHelper.AppendColor(isSweepCountOk ? TextColType.LightGreen : TextColType.Red, Language.Get("BoneField08", showrealRemainSweepCount, showSweepMaxCount));
        imgMoneyCount.SetActive(showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk);
        txtNeedMoneyCount.SetActive(showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk);
        if (showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk)
        if (InvestModel.Instance.GetFBIsFree(BoneFieldManager.Instance.DataMapID))
        {
            int dataMapID = BoneFieldManager.Instance.DataMapID;
            DungeonOpenTimeConfig config = DungeonOpenTimeConfig.Get(dataMapID);
            int index = Mathf.Min(Mathf.Max(0, showSweepMaxCount - showrealRemainSweepCount - 1), config.PayMoneyValues.Length - 1);
            int payMoneyValue = config.PayMoneyValues[index];
            int payMoneyType = config.PayMoneyType;
            imgMoneyCount.SetIconWithMoneyType(payMoneyType);
            txtNeedMoneyCount.text = payMoneyValue.ToString();
            txtFirstFree.text = Language.Get("PrivilegeCard1");
            imgMoneyCount.SetActive(false);
            txtNeedMoneyCount.SetActive(false);
        }
    }
        else
        {
            txtFirstFree.text = showSweepMaxCount == showrealRemainSweepCount ? Language.Get("BoneField10") : "";
            imgMoneyCount.SetActive(showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk);
            txtNeedMoneyCount.SetActive(showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk);
            if (showSweepMaxCount != showrealRemainSweepCount && isSweepCountOk)
            {
                int dataMapID = BoneFieldManager.Instance.DataMapID;
                DungeonOpenTimeConfig config = DungeonOpenTimeConfig.Get(dataMapID);
                int index = Mathf.Min(Mathf.Max(0, showSweepMaxCount - showrealRemainSweepCount - 1), config.PayMoneyValues.Length - 1);
                int payMoneyValue = config.PayMoneyValues[index];
                int payMoneyType = config.PayMoneyType;
                imgMoneyCount.SetIconWithMoneyType(payMoneyType);
                txtNeedMoneyCount.text = payMoneyValue.ToString();
            }
        }
    }
    public void DisplayAdsButton(ADAwardConfig aDAwardConfig)
    {
@@ -229,7 +239,7 @@
        bool isShowAds = adsCnt < aDAwardConfig.ADCntMax;
        int remainAdsCount = aDAwardConfig.ADCntMax - adsCnt;
        btnAds.SetActive(isShowAds);
        txtTodayAdsCount.text = UIHelper.AppendColor(isShowAds ? TextColType.LightGreen : TextColType.Red, Language.Get("BoneField09", remainAdsCount, aDAwardConfig.ADCntMax)); ;
        txtTodayAdsCount.text = Language.Get("BoneField09", remainAdsCount, aDAwardConfig.ADCntMax); ;
    }
    public void DisplayItemCellList(List<ItemCell> itemCells, int[][] items)
Main/System/ChallengeTab/BoneFieldTabHandler.cs
@@ -50,17 +50,17 @@
    protected override void SubscribeToSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChange;
        DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdate;
    }
    protected override void UnsubscribeFromSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChange;
        DungeonManager.Instance.UpdateFBInfoListEvent -= OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdate;
    }
    private void OnUpdateFBInfoChange(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    private void OnUpdateFBInfoChange(int mapID)
    {
        if (mapID == BoneFieldManager.Instance.DataMapID)
        {
@@ -68,7 +68,7 @@
        }
    }
    private void OnAdsInfoListUpdate(int adID, int mapID)
    private void OnAdsInfoListUpdate(int adID, int type, int mapID)
    {
        if (mapID == BoneFieldManager.Instance.DataMapID)
        {
Main/System/ChallengeTab/TianziBillboradTabHandler.cs
@@ -47,17 +47,17 @@
    protected override void SubscribeToSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChange;
        DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdate;
    }
    protected override void UnsubscribeFromSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChange;
        DungeonManager.Instance.UpdateFBInfoListEvent -= OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdate;
    }
    private void OnUpdateFBInfoChange(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    private void OnUpdateFBInfoChange(int mapID)
    {
        if (mapID == TianziBillboradManager.Instance.DataMapID)
        {
@@ -65,7 +65,7 @@
        }
    }
    private void OnAdsInfoListUpdate(int adID, int mapID)
    private void OnAdsInfoListUpdate(int adID, int type, int mapID)
    {
        if (mapID == TianziBillboradManager.Instance.DataMapID)
        {
Main/System/Dungeon/DungeonManager.cs
@@ -9,7 +9,6 @@
{
    private Dictionary<int, FBInfo> fbInfoDict = new Dictionary<int, FBInfo>();
    public event Action<int> UpdateFBInfoListEvent;//int mapID
    public event Action<int, bool, bool, bool> UpdateFBInfoChangeEvent;
    Dictionary<int, DungeonRecord> dungeonRecords = new Dictionary<int, DungeonRecord>();
    public event Action updateDungeonBuyCnt;
@@ -31,6 +30,33 @@
    public bool TryGetFBInfoByMapID(int mapID, out FBInfo info)
    {
        return fbInfoDict.TryGetValue(mapID, out info);
    }
    //获得副本的最大次数和剩余可用次数
    //maxCount 最大次数:可能会因各个副本展示规则不同而不同
    //            默认为从功能操作归属出发购买次数属于每日上限次数 每日次数 + 可最大购买次数 + 特权次数
    //useCount 剩余可用次数:今日总的可用次数 - 今日已进入次数
    //          今日总的可用次数:每日次数 + 可购总买次数 + 广告次数 + 道具次数 + 特权次数
    //          默认为从功能操作归属出发购买次数属于可用次数内
    public bool TryGetDungeonCount(int dataMapID, out int maxCount, out int useCount)
    {
        maxCount = 0;
        useCount = 0;
        if (!TryGetFBInfoByMapID(dataMapID, out FBInfo fbInfo))
            return false;
        DungeonOpenTimeConfig dungeonOpenTimeConfig = DungeonOpenTimeConfig.Get(dataMapID);
        if (dungeonOpenTimeConfig == null)
        {
            return false;
        }
        //总的可用次数:每日次数 + 可购总买次数 + 广告次数 + 道具次数 + 特权次数
        int totalCount = dungeonOpenTimeConfig.DayTimes + dungeonOpenTimeConfig.PayCntMax + InvestModel.Instance.GetAddFBBuyCount(dataMapID) + fbInfo.ADAddCnt + fbInfo.ItemAddCnt;
        maxCount = dungeonOpenTimeConfig.DayTimes + dungeonOpenTimeConfig.PayCntMax + InvestModel.Instance.GetAddFBBuyCount(dataMapID);
        useCount = totalCount - fbInfo.EnterCnt;
        return true;
    }
    public void UpdateFBInfoList(HA320_tagSCFBInfoList vNetData)
@@ -63,7 +89,6 @@
            fbInfoDict[mapID].PassGrade = item.PassGrade;
            UpdateFBInfoListEvent?.Invoke(mapID);
            UpdateFBInfoChangeEvent?.Invoke(mapID, isADAddCntChange, isBuyAddCntChange, isItemAddCntChange);
        }
    }
Main/System/Equip/BlessLVADWin.cs
@@ -31,7 +31,7 @@
    void OnAD()
    {
        AdsManager.Instance.SendGetReward(4);
        AdsManager.Instance.PlayAds(4);
        CloseWindow();
    }
    
Main/System/Equip/BlessLVManager.cs
@@ -100,7 +100,7 @@
    public int GetMaxEnergyCnt()
    {
        return freeEnergyMax;
        return freeEnergyMax + InvestModel.Instance.GetBlessAddEnergyMax();
    }
    //充能时间倒计时, 用于客户端主动领取 或者 只有从0到1才显示用
Main/System/HappyXB/HeroCallScoreWin.cs
@@ -50,7 +50,7 @@
        {
            scoreProcessText.color = UIHelper.GetUIColor(TextColType.Red);
        }
        if (InvestModel.Instance.IsInvested(InvestModel.monthCardType))
        if (InvestModel.Instance.IsActiveHeroScoreCall())
        {
            tryLockText.SetActive(false);
            call1Btn.SetColorful(null, true);
Main/System/Invest/InvestModel.cs
@@ -12,26 +12,45 @@
    //投资对应奖励
    Dictionary<int, int[][]> m_InvestItems = new Dictionary<int, int[][]>();
    Dictionary<int, int> m_InvestDays = new Dictionary<int, int>(); //投资对应天数
    Dictionary<int, int> m_InvestMaxDays = new Dictionary<int, int>();  //投资对应最大购买累加天数
    //投资对应充值ID
    Dictionary<int, int[]> m_InvestRechargeIds = new Dictionary<int, int[]>();
    Dictionary<int, int> m_InvestCTGIDToType = new Dictionary<int, int>();
    //投资对应购买情况
    Dictionary<int, InvestInfo> m_InvestInfos = new Dictionary<int, InvestInfo>();
    //投资类型
    public List<int> investTypes = new List<int>();
    //--特权--
    //增加副本购买次数
    Dictionary<int, Dictionary<int, int>> m_InvestAddFBCount = new Dictionary<int, Dictionary<int, int>>();
    //副本购买次数免费的副本ID 和 m_InvestAddFBCount 配合使用 相当于 特权增加副本上限但是发包流程需和服务端商量
    Dictionary<int, int[]> m_InvestFreeFBID = new Dictionary<int, int[]>();
    //演武场增加上限
    Dictionary<int, int> m_InvestArenaMaxCnt = new Dictionary<int, int>();
    //祝福树能量增加上限
    Dictionary<int, int> m_InvestAddBlessEnergyCount = new Dictionary<int, int>();
    // 特权权限数量
    Dictionary<int, int> m_PrivilegeLins = new Dictionary<int, int>();
    // 战斗倍数开启对应特权
    Dictionary<int, int> m_PrivilegeFightSpeed = new Dictionary<int, int>();
    // 英雄积分招募开启的特权类型
    int[] heroScoreCallOpenType;
    public event Action<int> onInvestUpdate;
    public const int redpointID = 20931;
    public Redpoint redpoint = new Redpoint(redpointID);
    public Redpoint redpoint1 = new Redpoint(MainRedDot.RedPoint_PrivilegeCard, MainRedDot.RedPoint_PrivilegeCard * 10 + 1);
    public Redpoint redpoint2 = new Redpoint(MainRedDot.RedPoint_PrivilegeCard, MainRedDot.RedPoint_PrivilegeCard * 10 + 2);
    public override void Init()
    {
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
        //通过配置决定是否有此投资项,如港台没有登录投资
        ParseConfig();
@@ -41,9 +60,8 @@
    public override void Release()
    {
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
    }
    public bool IsOpen()
@@ -55,86 +73,88 @@
    public void OnBeforePlayerDataInitialize()
    {
        m_InvestInfos.Clear();
        lastTotalBuyCountDict.Clear();
    }
    public void OnPlayerLoginOk()
    {
        UpdateRedpoint();
    }
    void ParseConfig()
    {
        var funcConfig = FuncConfigConfig.Get("InvestCost");
        m_InvestRechargeIds = ConfigParse.ParseIntArrayDict(funcConfig.Numerical1);
        foreach (var item in m_InvestRechargeIds)
        {
            m_InvestCTGIDToType[item.Value[0]] = item.Key;
        }
        funcConfig = FuncConfigConfig.Get("InvestDay");
        m_InvestDays = ConfigParse.ParseIntDict(funcConfig.Numerical1);
        m_InvestMaxDays = ConfigParse.ParseIntDict(funcConfig.Numerical2);
        m_InvestItems = ConfigParse.ParseIntArray2Dict(funcConfig.Numerical3);
        investTypes = m_InvestRechargeIds.Keys.ToList();
        investTypes.Sort();
        funcConfig = FuncConfigConfig.Get("InvestPower");
        m_InvestAddFBCount = ConfigParse.ParseDictInDict(funcConfig.Numerical1);
        m_InvestFreeFBID = ConfigParse.ParseIntArrayDict(funcConfig.Numerical2);
        m_InvestArenaMaxCnt = ConfigParse.ParseIntDict(funcConfig.Numerical3);
        m_InvestAddBlessEnergyCount = ConfigParse.ParseIntDict(funcConfig.Numerical4);
        funcConfig = FuncConfigConfig.Get("PrivilegeCard");
        m_PrivilegeLins = ConfigParse.ParseIntDict(funcConfig.Numerical1);
        m_PrivilegeFightSpeed = ConfigParse.ParseIntDict(funcConfig.Numerical2);
        heroScoreCallOpenType = JsonMapper.ToObject<int[]>(funcConfig.Numerical3);
        
    }
    public OrderInfoConfig GetOrderInfoId(int type)
    Dictionary<int, int> lastTotalBuyCountDict = new Dictionary<int, int>();
    void OnRechargeCountEvent(int ctgID)
    {
        var ids = m_InvestRechargeIds[type];
        for (int i = 0; i < ids.Length; i++)
        if (m_InvestCTGIDToType.ContainsKey(ctgID))
        {
            OrderInfoConfig config;
            if (RechargeManager.Instance.TryGetOrderInfo(ids[i], out config))
            var type = m_InvestCTGIDToType[ctgID];
            RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount);
            if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
            {
                return config;
                lastTotalBuyCountDict[type] = rechargeCount.totalCount;
                return;
            }
            var count = 0;
            lastTotalBuyCountDict.TryGetValue(type, out count);
            if (count < rechargeCount.totalCount)
            {
                lastTotalBuyCountDict[type] = rechargeCount.totalCount;
                UIManager.Instance.OpenWindow<PrivilegeActiveCardWin>(type);
            }
        }
        return null;
    }
    public bool hasInvestType(int type)
    //获取投资剩余时间 秒
    public int GetInvestLeftTime(int type)
    {
        return investTypes.Contains(type);
        if (type == 1 && m_InvestInfos[type].InvestEndTime > 0)
        {
            //月卡 限时类型的投资 未到期就算投资
            return m_InvestInfos[type].InvestEndTime - TimeUtility.AllSeconds;
        }
        return 0;
    }
    // public int GetInvestPassDays(int type)
    // {
    //     return m_InvestInfos.ContainsKey(type) ? m_InvestInfos[type].days : 0;
    // }
    //id 为表里的ID
    //0-未投资 1-未达成 2-可领取 3-已领取
    public int GetSingleInvestState(int type, int id)
    //0-未投资 1-可领取 2-已领取
    public int GetInvestState(int type)
    {
        // if (IsInvested(type))
        // {
        //     var day = GetInvestPassDays(type);
        //     if (m_InvestItems.ContainsKey(type)
        //         && m_InvestItems[type].ContainsKey(id))
        //     {
        //         if (IsRewardGot(type, id))
        //         {
        //             return 3;
        //         }
        //         var config = InvestConfig.Get(id);
        //         if (!m_InvestSingleInfos.ContainsKey(type))
        //         {
        //             return 0;
        //         }
        //         var index = id % 100;
        //         //每个数按位存31个激活索引
        //         var listIndex = index / 31;
        //         var bitIndex = index % 31;
        //         return day < config.needDay ? 1 : 2;
        //     }
        // }
        if (IsInvested(type))
        {
            if (m_InvestInfos[type].AwardState == 0)
            {
                return 1;
            }
            return 2;
        }
        return 0;
    }
@@ -149,7 +169,7 @@
        if (type == 1)
        {
            //月卡 限时类型的投资 未到期就算投资
            return m_InvestInfos[type].InvestEndTime > 0 && m_InvestInfos[type].InvestEndTime < TimeUtility.AllSeconds;
            return m_InvestInfos[type].InvestEndTime > 0 && m_InvestInfos[type].InvestEndTime > TimeUtility.AllSeconds;
        }
        
        //永久类型的投资 只要购买了就算投资
@@ -157,19 +177,8 @@
    }
    private void OnFuncStateChangeEvent(int id)
    {
        if (id == (int)FuncOpenEnum.PrivilegeCard)
        {
            UpdateRedpoint();
        }
    }
    public void SendGetReward(int type, int id)
    //type 投资类型
    public void SendGetReward(int type, int id = 0)
    {
        var pak = new CA541_tagCMGetInvestReward();
        pak.InvestType = (byte)type;
@@ -180,15 +189,12 @@
    //购买投资
    public void BuyInvest(int type)
    {
        RechargeManager.Instance.CTG(GetOrderInfoId(type));
        RechargeManager.Instance.CTG(GetOrderInfo(type));
    }
    public void UpdateInvestInfo(HA338_tagSCInvestInfo package)
    {
        if (!investTypes.Contains(package.InvestType))
        {
            return;
        }
        m_InvestInfos[package.InvestType] = new InvestInfo()
        {
@@ -197,7 +203,7 @@
            AwardState = package.AwardState
        };
        UpdateRedpoint();
        if (onInvestUpdate != null)
@@ -213,9 +219,167 @@
            return;
        }
        redpoint1.state = GetInvestState(monthCardType) == 1 ? RedPointState.Simple : RedPointState.None;
        redpoint2.state = GetInvestState(foreverCardType) == 1 ? RedPointState.Simple : RedPointState.None;
    }
    #region 特权接口
    //副本增加的购买次数上限
    public int GetAddFBBuyCount(int _mapID)
    {
        int addCount = 0;
        foreach (var item in m_InvestAddFBCount)
        {
            if (!IsInvested(item.Key))
            {
                continue;
            }
            foreach (var mapID in item.Value.Keys)
            {
                if (mapID == _mapID)
                {
                    addCount += item.Value[mapID];
                }
            }
        }
        return addCount;
    }
    //副本免费的购买次数
    public bool GetFBIsFree(int _mapID)
    {
        foreach (var item in m_InvestFreeFBID)
        {
            if (!IsInvested(item.Key))
            {
                continue;
            }
            foreach (var mapID in item.Value)
            {
                if (mapID == _mapID)
                {
                    return true;
                }
            }
        }
        return false;
    }
    public int GetPrivilegeLins(int type)
    {
        if (m_PrivilegeLins.ContainsKey(type))
        {
            return m_PrivilegeLins[type];
        }
        return 0;
    }
    public OrderInfoConfig GetOrderInfo(int type)
    {
        var ids = m_InvestRechargeIds[type];
        for (int i = 0; i < ids.Length; i++)
        {
            OrderInfoConfig config;
            if (RechargeManager.Instance.TryGetOrderInfo(ids[i], out config))
            {
                return config;
            }
        }
        return null;
    }
    public int GetCTGID(int type)
    {
        return m_InvestRechargeIds[type][0];
    }
    public int[][] GetDayAwards(int type)
    {
        return m_InvestItems[type];
    }
    //演武场凭证上限
    public int GetArenaAddMaxCount()
    {
        int addCount = 0;
        foreach (var item in m_InvestArenaMaxCnt)
        {
            if (!IsInvested(item.Key))
            {
                continue;
            }
            addCount += item.Value;
        }
        return addCount;
    }
    //购买天数是否达上限
    public bool IsBuyMaxDay(int type)
    {
        if (m_InvestMaxDays.ContainsKey(type) && m_InvestInfos.ContainsKey(type))
        {
            if (m_InvestInfos[type].InvestEndTime > 0)
            {
                return (m_InvestInfos[type].InvestEndTime - TimeUtility.AllSeconds) / 60 / 60 / 24 + m_InvestDays[type] >= m_InvestMaxDays[type];
            }
        }
        return false;
    }
    //祝福能量上限
    public int GetBlessAddEnergyMax()
    {
        int addCount = 0;
        foreach (var item in m_InvestAddBlessEnergyCount)
        {
            if (!IsInvested(item.Key))
            {
                continue;
            }
            addCount += item.Value;
        }
        return addCount;
    }
    //是否激活英雄积分召唤
    public bool IsActiveHeroScoreCall()
    {
        foreach (var type in heroScoreCallOpenType)
        {
            if (IsInvested(type))
            {
                return true;
            }
        }
        return false;
    }
    public bool IsActiveFightSpeed(int speed)
    {
        foreach (var item in m_PrivilegeFightSpeed)
        {
            if (!IsInvested(item.Key))
            {
                continue;
            }
            if (item.Value == speed)
            {
                return true;
            }
        }
        return false;
    }
    #endregion
    public struct InvestInfo
    {
Main/System/KnapSack/PackManager.cs
@@ -43,12 +43,8 @@
    public Dictionary<int, int> openGirdMoneyDict = new Dictionary<int, int>(); //背包类型:消耗货币类型
    public Dictionary<int, int[]> openGirdMoneyValueDict = new Dictionary<int, int[]>(); //背包类型:消耗货币值(按次数定价)
    public Dictionary<int, int[]> openGirdCountDict = new Dictionary<int, int[]>(); //背包类型:每次开的格子数量
    public static string StrengthAttrShift_RecordKey = "";
    public const string RecordKnapsackTitle = "RecordKnapsackTitle";
    string RoleEquipLocalSave = "";
    List<int> LocalSavePlaceArray { get; set; }
    Dictionary<int, List<int>> sharedUseCountItemDict { get; set; }
    // bool isUpdatePlayerLv = false;
    bool isItemChange = false;  //延迟处理物品变化
@@ -105,7 +101,6 @@
    {
        GlobalTimeEvent.Instance.secondEvent -= UpdateSecond;
        // PlayerDatas.Instance.playerDataRefreshEvent -= UpdatePlayerLv;
        LocalSave.DeleteKey(RecordKnapsackTitle);
        playerPackDict.Clear();
        itemDayUseCntDict.Clear();
        itemSumUseCntDict.Clear();
@@ -117,17 +112,7 @@
    public void OnPlayerLoginOk()
    {
        //ItemOperateUtility.Instance.RequestWarehouseData();
        RoleEquipLocalSave = StringUtility.Contact("RoleEquipLocalSave", PlayerDatas.Instance.baseData.PlayerID);
        StrengthAttrShift_RecordKey = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "StrengthAttrShift");
        if (LocalSave.GetIntArray(RoleEquipLocalSave) != null)
        {
            LocalSavePlaceArray = LocalSave.GetIntArray(RoleEquipLocalSave).ToList();
        }
        else
        {
            LocalSavePlaceArray = null;
        }
        GlobalTimeEvent.Instance.secondEvent += UpdateSecond;
        // PlayerDatas.Instance.playerDataRefreshEvent += UpdatePlayerLv;
        // isUpdatePlayerLv = true;
Main/System/Main/AutoFightModel.cs
@@ -88,14 +88,16 @@
    public int maxCost; //最高消耗
    public int[] autoCostWithBlessLV; //自动战斗消耗倍数关联祝福等级
    public int speed2UnlockMissionID;
    public int speed3UnlockCTGID;
    public override void Init()
    {
        ParseConfig();
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerInit;
        BattleManager.Instance.onBattleFieldCreate += OnCreateBattleField;
        EventBroadcast.Instance.AddListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        BlessLVManager.Instance.OnBlessLVUpdateEvent += UpdateRedpint;
        TaskManager.Instance.OnTaskUpdate += OnTaskUpdate;
        InvestModel.Instance.onInvestUpdate += OnInvestUpdate;
    }
@@ -104,6 +106,9 @@
        BattleManager.Instance.onBattleFieldCreate -= OnCreateBattleField;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerInit;
        EventBroadcast.Instance.RemoveListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        BlessLVManager.Instance.OnBlessLVUpdateEvent -= UpdateRedpint;
        TaskManager.Instance.OnTaskUpdate -= OnTaskUpdate;
        InvestModel.Instance.onInvestUpdate -= OnInvestUpdate;
    }
@@ -112,7 +117,6 @@
        var config = FuncConfigConfig.Get("AutoGuaji");
        autoCostWithBlessLV = JsonMapper.ToObject<int[]>(config.Numerical1);
        speed2UnlockMissionID = int.Parse(config.Numerical2);
        speed3UnlockCTGID = int.Parse(config.Numerical3);
        maxCost = autoCostWithBlessLV.Length;
    }
@@ -263,5 +267,92 @@
    #endregion
    //新增消耗倍数红点
    Redpoint redpoint1 = new Redpoint(MainRedDot.RedPoint_AutoBattleKey, MainRedDot.RedPoint_AutoBattleKey * 10 + 1);
    //新增战斗倍数红点
    Redpoint redpoint2 = new Redpoint(MainRedDot.RedPoint_AutoBattleKey, MainRedDot.RedPoint_AutoBattleKey * 10 + 2);
    void UpdateRedpint()
    {
        //提示红点记录到第几个索引,每次解锁新的消耗红点都提示
        var costIndex = LocalSave.GetInt("redcost" + PlayerDatas.Instance.baseData.PlayerID);
        if (costIndex + 1 < autoCostWithBlessLV.Length)
        {
            redpoint1.state = autoCostWithBlessLV[Math.Min(costIndex + 1, autoCostWithBlessLV.Length - 1)] <= BlessLVManager.Instance.m_TreeLV ?
                                RedPointState.Simple : RedPointState.None;
        }
        else
        {
            redpoint1.state = RedPointState.None;
        }
        var speedIndex = LocalSave.GetInt("redspeed" + PlayerDatas.Instance.baseData.PlayerID);
        redpoint2.state = RedPointState.None;
        if (speedIndex == 0 && TaskManager.Instance.mainTask.TaskID > speed2UnlockMissionID &&
            !InvestModel.Instance.IsActiveFightSpeed(3))
        {
            redpoint2.state = RedPointState.Simple;
        }
        else if (speedIndex < 2 && InvestModel.Instance.IsActiveFightSpeed(3))
        {
            redpoint2.state = RedPointState.Simple;
        }
    }
    public void ClickCostRed()
    {
        int index = 0;
        for (int i = 0; i < autoCostWithBlessLV.Length; i++)
        {
            if (autoCostWithBlessLV[i] <= BlessLVManager.Instance.m_TreeLV)
            {
                index = i;
            }
            else
            {
                break;
            }
        }
        LocalSave.SetInt("redcost" + PlayerDatas.Instance.baseData.PlayerID, index);
        UpdateRedpint();
    }
    public void ClickSpeedRed()
    {
        int index = 0;
        if (!InvestModel.Instance.IsActiveFightSpeed(3))
        {
            if (TaskManager.Instance.mainTask.TaskID > speed2UnlockMissionID)
            {
                index = 1;
            }
        }
        else
        {
            index = 2;
        }
        LocalSave.SetInt("redspeed" + PlayerDatas.Instance.baseData.PlayerID, index);
        UpdateRedpint();
    }
    void OnTaskUpdate()
    {
        //任务刷新比较频繁
        if (TaskManager.Instance.mainTask.TaskID < speed2UnlockMissionID)
        {
            return;
        }
        if (LocalSave.GetInt("redspeed" + PlayerDatas.Instance.baseData.PlayerID) > 0)
            return;
        if (redpoint2.state == RedPointState.Simple)
            return;
        UpdateRedpint();
    }
    void OnInvestUpdate(int type)
    {
        if (type > 2)
            return;
        UpdateRedpint();
    }
}
Main/System/Main/AutoFightWin.cs
@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -38,12 +39,14 @@
            isOpenCostScroll = !isOpenCostScroll;
            costScroll.SetActive(isOpenCostScroll);
            costArrow.transform.localRotation = Quaternion.Euler(0, 0, isOpenCostScroll ? 180 : 0);
            AutoFightModel.Instance.ClickCostRed();
        });
        changeSpeedBtn.AddListener(() =>
        {
            isOpenSpeedScroll = !isOpenSpeedScroll;
            speedScroll.SetActive(isOpenSpeedScroll);
            speedArrow.transform.localRotation = Quaternion.Euler(0, 0, isOpenSpeedScroll ? 180 : 0);
            AutoFightModel.Instance.ClickSpeedRed();
        });
        betterEquipToggle.AddListener((bool value) =>
@@ -115,6 +118,10 @@
            costScroll.AddCell(ScrollerDataType.Header, i + 1);
        }
        costScroll.Restart();
        if (BlessLVManager.Instance.m_TreeLV >= AutoFightModel.Instance.autoCostWithBlessLV[Math.Min(AutoFightModel.Instance.autoCostWithBlessLV.Length - 1, 2)])
        {
            costScroll.JumpIndex(2);
        }
    }
    
    void CreateSpeedScroll()
@@ -166,19 +173,14 @@
    {
        var btn = cell.GetComponent<Button>();
        var needtaskCount = TaskManager.Instance.GetNeedFinishTaskCount(AutoFightModel.Instance.speed2UnlockMissionID);
        RechargeCount _rechargeCount;
        bool isbuy = false;
        if (RechargeManager.Instance.TryGetRechargeCount(AutoFightModel.Instance.speed3UnlockCTGID, out _rechargeCount))
        {
            isbuy = _rechargeCount.totalCount > 0;
        }
        bool isbuy = InvestModel.Instance.IsActiveFightSpeed(3);
        bool isActiveSpeed2 = needtaskCount <= 0 || isbuy;
 
        btn.AddListener(() =>
        {
            if (cell.index == 2)
            {
                if (needtaskCount > 0)
                if (!isActiveSpeed2)
                {
                    SysNotifyMgr.Instance.ShowTip("autofight2", needtaskCount);
                    return;
@@ -201,7 +203,7 @@
        var cntText = cell.GetComponentInChildren<Text>();
        if (cell.index == 2)
        {
            cntText.text = UIHelper.AppendColor(needtaskCount > 0 ? TextColType.Gray : TextColType.LightWhite, cell.index.ToString());
            cntText.text = UIHelper.AppendColor(!isActiveSpeed2 ? TextColType.Gray : TextColType.LightWhite, cell.index.ToString());
        }
        else if (cell.index == 3)
        {
Main/System/Main/RightFuncInHome.cs
@@ -26,8 +26,8 @@
        monthCardBtn.AddListener(() =>
        {
            //用于监听界面,打开时缩进右边功能栏,关闭时显示
            // ListenWindow("");
            InvestModel.Instance.BuyInvest(InvestModel.monthCardType);
            ListenWindow("PrivilegeCardWin");
            UIManager.Instance.OpenWindow<PrivilegeCardWin>();
        });
        storeBtn.AddListener(() =>
        {
@@ -88,7 +88,7 @@
        battlePassBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.BattlePass));
        llmjBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.LLMJ));
        signBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DaySign));
        // monthCardBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.MonthCard));
        monthCardBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard));
    }
Main/System/Recharge/PrivilegeActiveCardWin.cs
New file
@@ -0,0 +1,49 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
//特权卡激活成功
public class PrivilegeActiveCardWin : UIBase
{
    [SerializeField] Transform[] tqLines;
    [SerializeField] Text[] tqTexts;
    [SerializeField] RectTransform bg;
    protected override void OnPreOpen()
    {
        if (functionOrder == 0)
            return;
        int type = functionOrder;
        var lines = InvestModel.Instance.GetPrivilegeLins(type);
        for (int i = 0; i < tqLines.Length; i++)
        {
            if (i < lines)
            {
                tqLines[i].SetActive(true);
                tqTexts[i].text = Language.Get($"PrivilegeCard{type}_{i + 1}");
            }
            else
            {
                tqLines[i].SetActive(false);
            }
        }
    }
    protected override void NextFrameAfterOpen()
    {
        ForceRefreshLayout().Forget();
    }
    /// <summary>
    /// 强制刷新Layout,解决嵌套Layout和ContentSizeFitter的重叠问题
    /// </summary>
    async UniTask ForceRefreshLayout()
    {
        LayoutRebuilder.ForceRebuildLayoutImmediate(bg);
        await UniTask.DelayFrame(2);
        LayoutRebuilder.ForceRebuildLayoutImmediate(bg);
    }
}
Main/System/Recharge/PrivilegeActiveCardWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 056b3f69baabf6b418cdcd0705c849a2
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Recharge/PrivilegeCardCell.cs
New file
@@ -0,0 +1,145 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//特权卡
public class PrivilegeCardCell : MonoBehaviour
{
    [SerializeField] Transform[] tqLines;
    [SerializeField] Text[] tqTexts;
    [SerializeField] ItemCell[] itemCells;
    [SerializeField] ItemCell[] dayItemCells;
    [SerializeField] Text timeText;
    [SerializeField] Button opBtn;
    [SerializeField] Text opBtnText;
    public void Display(int type)
    {
        var lines = InvestModel.Instance.GetPrivilegeLins(type);
        for (int i = 0; i < tqLines.Length; i++)
        {
            if (i < lines)
            {
                tqLines[i].SetActive(true);
                tqTexts[i].text = Language.Get($"PrivilegeCard{type}_{i+1}");
            }
            else
            {
                tqLines[i].SetActive(false);
            }
        }
        var ctgID = InvestModel.Instance.GetCTGID(type);
        var ctgConfig = CTGConfig.Get(ctgID);
        for (int i = 0; i < itemCells.Length; i++)
        {
            if (i < ctgConfig.GainItemList.Length)
            {
                itemCells[i].SetActive(true);
                int itemID = ctgConfig.GainItemList[i][0];
                itemCells[i].Init(new ItemCellModel(itemID, false, ctgConfig.GainItemList[i][1]));
                itemCells[i].button.AddListener(() =>
                {
                    ItemTipUtility.Show(itemID);
                });
            }
            else
            {
                itemCells[i].SetActive(false);
            }
        }
        var dayAwards = InvestModel.Instance.GetDayAwards(type);
        for (int i = 0; i < dayItemCells.Length; i++)
        {
            if (i < dayAwards.Length)
            {
                dayItemCells[i].SetActive(true);
                int itemID = dayAwards[i][0];
                dayItemCells[i].Init(new ItemCellModel(itemID, false, dayAwards[i][1]));
                dayItemCells[i].button.AddListener(() =>
                {
                    ItemTipUtility.Show(itemID);
                });
            }
            else
            {
                dayItemCells[i].SetActive(false);
            }
        }
        var state = InvestModel.Instance.GetInvestState(type);
        if (timeText != null)
        {
            if (state == 0)
            {
                timeText.text = "";
            }
            else
            {
                timeText.text = Language.Get("GoldRush29") + TimeUtility.SecondsToShortDHMS(InvestModel.Instance.GetInvestLeftTime(type));
            }
        }
        if (state == 0)
        {
            var orderInfo = InvestModel.Instance.GetOrderInfo(type);
            opBtnText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
            opBtn.SetInteractable(true);
            opBtn.AddListener(() =>
            {
                RechargeManager.Instance.CTG(ctgID);
            });
        }
        else if (state == 1)
        {
            opBtnText.text = Language.Get("Mail09");
            opBtn.SetInteractable(true);
            opBtn.AddListener(() =>
            {
                InvestModel.Instance.SendGetReward(type);
            });
        }
        else
        {
            if (type == 1)
            {
                var orderInfo = InvestModel.Instance.GetOrderInfo(type);
                opBtnText.text = Language.Get("PayMore", orderInfo.PayRMBNumOnSale);
                opBtn.SetInteractable(true);
                opBtn.AddListener(() =>
                {
                    if (InvestModel.Instance.IsBuyMaxDay(type))
                    {
                        SysNotifyMgr.Instance.ShowTip("BuyIsMax");
                        return;
                    }
                    RechargeManager.Instance.CTG(ctgID);
                });
            }
            else
            {
                opBtn.SetInteractable(false);
                opBtnText.text = Language.Get("L1129_2");
            }
        }
    }
    public void UpdateTime(int type)
    {
        var state = InvestModel.Instance.GetInvestState(type);
        if (state == 0)
        {
            return;
        }
        if (timeText != null)
        {
            timeText.text = Language.Get("GoldRush29") + TimeUtility.SecondsToShortDHMS(InvestModel.Instance.GetInvestLeftTime(type));
        }
    }
}
Main/System/Recharge/PrivilegeCardCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8b475974a10df4408f0ffd29402e7e9
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Recharge/PrivilegeCardWin.cs
@@ -5,129 +5,36 @@
//特权卡
public class PrivilegeCardWin : UIBase
{
    [SerializeField] GroupButtonEx djqBtn;
    [SerializeField] GroupButtonEx goldBtn;
    [SerializeField] ScrollerController djqScroller;
    [SerializeField] ScrollerController goldScroller;
    [SerializeField] Transform djqInfo;
    List<int> _list = new List<int>();
    protected override void InitComponent()
    {
        djqBtn.AddListener(() => { OnSelectFuncType(0); });
        goldBtn.AddListener(() => { OnSelectFuncType(1); });
    }
    //月卡
    [SerializeField] PrivilegeCardCell monthObj;
    [SerializeField] PrivilegeCardCell foreverObj;
    protected override void OnPreOpen()
    {
        djqScroller.OnRefreshCell += OnDjqRefreshCell;
        goldScroller.OnRefreshCell += OnGoldRefreshCell;
        RechargeManager.Instance.rechargeCountEvent += RechargeEvent;
        if (RechargeManager.Instance.selectTabIndex == 0)
        {
            djqBtn.SelectBtn();
        }
        else if (RechargeManager.Instance.selectTabIndex == 1)
        {
            goldBtn.SelectBtn();
        }
        Display();
        InvestModel.Instance.onInvestUpdate += OnInvestUpdate;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        monthObj.Display(1);
        foreverObj.Display(2);
    }
    protected override void OnPreClose()
    {
        djqScroller.OnRefreshCell -= OnDjqRefreshCell;
        goldScroller.OnRefreshCell -= OnGoldRefreshCell;
        RechargeManager.Instance.rechargeCountEvent -= RechargeEvent;
    }
        InvestModel.Instance.onInvestUpdate -= OnInvestUpdate;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
    void RechargeEvent(int id)
    {
        Display();
    }
    void Display()
    {
        CreateScroller();
    }
    void CreateScroller()
    {
        if (RechargeManager.Instance.selectTabIndex == 0)
        {
            _list = RechargeManager.Instance.GetCTGIDListByType(17);
            djqScroller.SetActive(true);
            djqInfo.SetActive(true);
            goldScroller.SetActive(false);
            if (djqScroller.GetCellTotalCount() == 0)
            {
                djqScroller.Refresh();
                for (int i = 0; i < _list.Count; i++)
                {
                    if (i % 3 == 0)
                    {
                        djqScroller.AddCell(ScrollerDataType.Header,i);
                    }
                }
                djqScroller.Restart();
            }
            else
            {
                djqScroller.m_Scorller.RefreshActiveCellViews();
            }
        }
        else if (RechargeManager.Instance.selectTabIndex == 1)
        {
            _list = RechargeManager.Instance.GetCTGIDListByType(2);
            djqScroller.SetActive(false);
            djqInfo.SetActive(false);
            goldScroller.SetActive(true);
            if (goldScroller.GetCellTotalCount() == 0)
            {
                goldScroller.Refresh();
                for (int i = 0; i < _list.Count; i++)
                {
                    if (i % 3 == 0)
                    {
                        goldScroller.AddCell(ScrollerDataType.Header, i);
                    }
                }
                goldScroller.Restart();
            }
            else
            {
                goldScroller.m_Scorller.RefreshActiveCellViews();
            }
        }
    }
    void OnDjqRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as RechargeDJQLineCell;
        _cell.Display(cell.index, _list);
    }
    void OnGoldRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as RechargeGoldLineCell;
        _cell.Display(cell.index, _list);
    }
    void OnSelectFuncType(int index)
    void OnInvestUpdate(int type)
    {
        monthObj.Display(1);
        foreverObj.Display(2);
    }
        RechargeManager.Instance.selectTabIndex = index;
        Display();
    void OnSecondEvent()
    {
        monthObj.UpdateTime(1);
    }
}
Main/System/Recharge/RechargeManager.cs
@@ -107,8 +107,8 @@
    #region 配置
    private static string[] lineSplit = new string[] { "</r>" };
    private int m_CTGDelayTime = 1;   // 充值的公共间隔,见配置ChargeDelayTime
    private int m_CTGLimitDelayTime = 1; // 限购商品的充值间隔,见配置ChargeDelayTime
    private int m_CTGDelayTime = 0;   // 充值的公共间隔,见配置ChargeDelayTime
    private int m_CTGLimitDelayTime = 0; // 限购商品的充值间隔,见配置ChargeDelayTime
    //多倍图片
    public Dictionary<int, string> MultiRechageImageDict = new Dictionary<int, string>();
Main/System/Redpoint/MainRedDot.cs
@@ -58,9 +58,17 @@
    
    //签到
    public const int RedPoint_SignKey = 107;
    //坐骑
    public const int RedPoint_HorseKey = 108;
    //特权卡
    public const int RedPoint_PrivilegeCard = 109;
    Redpoint pcardRedpoint = new Redpoint(RedPoint_PrivilegeCard);
    //自动战斗
    public const int RedPoint_AutoBattleKey = 110;
    Redpoint autoBattleRedpoint = new Redpoint(RedPoint_AutoBattleKey);
    
    //武将卡
    public const int HeroCardRedpoint = 200;
Main/System/TianziBillborad/TianziBillboradManager.cs
@@ -22,7 +22,7 @@
        EventBroadcast.Instance.AddListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
        EventBroadcast.Instance.AddListener<string, JsonData>(EventName.BATTLE_END, OnSettlement);
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
        TimeMgr.Instance.OnDayEvent += OnDayEvent;
@@ -37,7 +37,7 @@
        EventBroadcast.Instance.RemoveListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
        EventBroadcast.Instance.RemoveListener<string, JsonData>(EventName.BATTLE_END, OnSettlement);
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChangeEvent;
        DungeonManager.Instance.UpdateFBInfoListEvent -= OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
@@ -148,17 +148,16 @@
        UpdateRedPoint();
    }
    private void OnUpdateFBInfoChangeEvent(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    private void OnUpdateFBInfoChangeEvent(int mapID)
    {
        int dataMapID = DataMapID;
        if (mapID != dataMapID)
            return;
        if (isADAddCntChange)
            return;
        UpdateRedPoint();
    }
    private void OnAdsInfoListUpdateEvent(int id, int mapId)
    private void OnAdsInfoListUpdateEvent(int id, int type, int mapId)
    {
        if (mapId != DataMapID)
            return;
@@ -209,12 +208,11 @@
        }
        return res;
    }
    public bool TryGetADAwardConfigByMapId(int dataMapID, out ADAwardConfig adAwardConfig)
    {
        adAwardConfig = null;
        if (!ADAwardConfig.TryGetADIDByADMapID(dataMapID, out int adID) || !ADAwardConfig.HasKey(adID))
        if (!ADAwardConfig.TryGetADIDByTypeValue(2, dataMapID, out adAwardConfig))
            return false;
        adAwardConfig = ADAwardConfig.Get(adID);
        return true;
    }
Main/System/TianziBillborad/TianziBillboradWin.cs
@@ -123,7 +123,7 @@
        Display();
    }
    private void OnAdsInfoListUpdateEvent(int id, int mapId)
    private void OnAdsInfoListUpdateEvent(int id, int type, int mapId)
    {
        if (mapId != model.DataMapID)
            return;