lcy
3 天以前 2e7d66b9b7d541d878b2220fa1e50552e7553708
Main/System/HeroDebut/HeroDebutManager.cs
@@ -6,8 +6,13 @@
public class HeroDebutManager : GameSystemManager<HeroDebutManager>, IOpenServerActivity
{
    // 缓存的ZhanLingType列表(从ActHeroAppearConfig获取,后续不变)
    private static List<int> zhanLingTypeList = null;
    public int[] xbGridArr;
    public Dictionary<int, int[][]> heroQaulityColor;
    public int[][] seeArr;
    public int subVulue;
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
@@ -26,8 +31,12 @@
        var config = FuncConfigConfig.Get("HeroAppear");
        xbGridArr = JsonMapper.ToObject<int[]>(config.Numerical1);
        heroQaulityColor = ConfigParse.ParseIntArray2Dict(config.Numerical2);
        seeArr = JsonMapper.ToObject<int[][]>(config.Numerical3);
        subVulue = int.Parse(config.Numerical4);
        InitRedPointId();
        BattlePassManager.Instance.BattlePassDataUpdateEvent += OnBattlePassDataUpdate;
    }
    public void SetheroQaulityColor(GradientText text, int qaulity)
@@ -50,6 +59,8 @@
        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent;
        HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent;
        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
        BattlePassManager.Instance.BattlePassDataUpdateEvent -= OnBattlePassDataUpdate;
    }
    private void OnDayEvent()
@@ -75,9 +86,9 @@
    private void OnBeforePlayerDataInitializeEventOnRelogin()
    {
        isSendFirst = true;
        starHeroIndexDict.Clear();
        starHeroIndex = 0;
        callHeroIndex = 0;
        starFreeAwardDict.Clear();
        callHeroIndexDict.Clear();
    }
    private void OnPlayerLoginOk()
@@ -122,6 +133,8 @@
    {
        if (type == operaType && state == 0)
        {
            gameRecDict.Clear();
            isSendFirst = true;
            onStateUpdate?.Invoke(activityID);
            TryPopWin();
            UpdateRedpoint();
@@ -241,22 +254,23 @@
            OnNowCallChooseHeroIDChangeEvent?.Invoke();
        }
    }
    public event Action<int> OnUpdateHeroAppearPlayerInfoEvent;
    public int starHeroIndex = 0;
    public int callHeroIndex = 0;
    //<升星计划选择的武将ID索引,升星计划免费奖励记录>
    Dictionary<int, uint> starFreeAwardDict = new();
    public event Action OnUpdateHeroAppearPlayerInfoEvent;
    public void UpdateHeroAppearPlayerInfo(HAA22_tagSCActHeroAppearPlayerInfo vNetData)
    {
        if (vNetData == null) return;
        int actNum = vNetData.ActNum;
        starHeroIndexDict[actNum] = vNetData.StarHeroIndex;
        callHeroIndexDict[actNum] = vNetData.CallHeroIndex;
        if (vNetData.ActNum != this.actNum) return;
        if (!starFreeAwardDict.TryGetValue(actNum, out var dict))
        {
            dict = new Dictionary<int, uint>();
            starFreeAwardDict[actNum] = dict;
        }
        dict[vNetData.StarHeroIndex] = vNetData.StarFreeAward;
        int actNum = vNetData.ActNum;
        starHeroIndex = vNetData.StarHeroIndex;
        callHeroIndex = vNetData.CallHeroIndex;
        starFreeAwardDict[starHeroIndex] = vNetData.StarFreeAward;
        UpdateRedpoint();
        OnUpdateHeroAppearPlayerInfoEvent?.Invoke(actNum);
        OnUpdateHeroAppearPlayerInfoEvent?.Invoke();
    }
    public void SendHeroAppearStarHeroSelect(int actNum, int starHeroIndex)
@@ -292,12 +306,14 @@
    public Redpoint starUpRedpoint;
    public Redpoint shopRedpoint;
    public Redpoint giftRedpoint;
    public Redpoint zhanLingRedpoint;
    public void InitRedPointId()
    {
        checkInRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.CheckIn));
        starUpRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.StarUp));
        shopRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.Shop));
        giftRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.Gift));
        zhanLingRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.ZhanLing));
    }
    public void UpdateRedpoint()
@@ -307,6 +323,7 @@
        starUpRedpoint.state = RedPointState.None;
        shopRedpoint.state = RedPointState.None;
        giftRedpoint.state = RedPointState.None;
        zhanLingRedpoint.state = RedPointState.None;
        if (!IsHeroDebutOpen()) return;
@@ -329,6 +346,11 @@
        if (HasGiftCanHave())//皇权礼包
        {
            giftRedpoint.state = RedPointState.Simple;
        }
        if (HasZhanLingCanHave())//战令
        {
            zhanLingRedpoint.state = RedPointState.Simple;
        }
    }
    #endregion
@@ -430,12 +452,6 @@
    #region 升星计划
    //<活动编号,升星计划选择的武将ID索引>
    public Dictionary<int, int> starHeroIndexDict = new();
    //<活动编号,<升星计划选择的武将ID索引,升星计划免费奖励记录>>
    public Dictionary<int, Dictionary<int, uint>> starFreeAwardDict = new();
    /// <summary>
    /// 当前升星计划选中的武将ID
    /// </summary>
@@ -443,12 +459,11 @@
    {
        var act = GetOperationHeroAppearInfo();
        if (act == null) return 0;
        if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
        var config = ActHeroAppearConfig.Get(act.CfgID);
        if (config == null || config.ActHeroIDList?.Length <= index) return 0;
        if (config == null || config.ActHeroIDList?.Length <= starHeroIndex) return 0;
        return config.ActHeroIDList[index];
        return config.ActHeroIDList[starHeroIndex];
    }
    private Dictionary<int, Dictionary<int, int[][]>> showHeroGiftItemInfoDict = new();
@@ -503,16 +518,17 @@
        var heroConfig = HeroConfig.Get(heroId);
        if (heroConfig == null) return 0;
        if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
        if (IsStarUpFreeHave(index, config.AwardIndex)) return 2;
        // 没获得武将本体不可领取
        if (!HeroManager.Instance.HasHero(heroId)) return 0;
        if (IsStarUpFreeHave(starHeroIndex, config.AwardIndex)) return 2;
        if (IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar)) return 1;
        return 0;
    }
    private bool IsStarUpFreeHave(int starHeroIndex, int awardIndex)
    {
        if (!starFreeAwardDict.TryGetValue(actNum, out var dict)) return false;
        if (!dict.TryGetValue(starHeroIndex, out uint freeAward)) return false;
        if (!starFreeAwardDict.TryGetValue(starHeroIndex, out uint freeAward)) return false;
        return ((freeAward >> awardIndex) & 1u) == 1u;
    }
@@ -539,7 +555,7 @@
    public bool TryGetStarUpStateIndex(int starGiftTempID, int tarState, out int index)
    {
        index = 0;
        var list = ActHeroAppearStarConfig.GetAwardIndexSortList(starGiftTempID);
        var list = ActHeroAppearStarConfig.GetHeroDebutAwardIndexSortList(starGiftTempID);
        if (list == null) return false;
        for (int i = 0; i < list.Count; i++)
@@ -609,8 +625,17 @@
    #endregion
    #region 皇权礼包
    //没售罄
    public bool IsCanBuyToday(int ctgID)
    {
        CTGConfig config = CTGConfig.Get(ctgID);
        if (config == null) return false;
        if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false;
        if (config.DailyBuyCount == 0) return true;
        return rechargeCount.todayCount < config.DailyBuyCount;
    }
    public bool IsNoSellOutCTGID(int ctgID)
    {
        CTGConfig config = CTGConfig.Get(ctgID);
@@ -680,7 +705,7 @@
        {
            res = res.OrderBy(item =>
            {
                bool isCanBuy = item.type == 0 ? IsNoSellOutShopID(item.id) : IsNoSellOutCTGID(item.id);
                bool isCanBuy = item.type == 0 ? IsNoSellOutShopID(item.id) : IsCanBuyToday(item.id);
                return !isCanBuy;
            })
            .ThenBy(item => item.type)
@@ -719,7 +744,7 @@
    }
    private string GetCallSkipKey(int cfgID, OperationDate startDate, OperationDate endDate)
    {
        return string.Concat("HeroDebutManager_CallSkip_", cfgID, ToInt(startDate), ToInt(endDate), PlayerDatas.Instance.PlayerId);
        return string.Concat("HeroDebutManager_CallSkip_", cfgID, "_", ToInt(startDate), "_", ToInt(endDate), "_", PlayerDatas.Instance.PlayerId);
    }
    public bool LoadCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate)
@@ -732,9 +757,6 @@
        LocalSave.SetBool(GetCallSkipKey(cfgID, startDate, endDate), value);
    }
    //<活动编号,招募选择的武将ID索引>
    public Dictionary<int, int> callHeroIndexDict = new();
    /// <summary>
    /// 当前招募选中的武将ID
    /// </summary>
@@ -742,15 +764,50 @@
    {
        var act = GetOperationHeroAppearInfo();
        if (act == null) return 0;
        if (!callHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
        var config = ActHeroAppearConfig.Get(act.CfgID);
        if (config == null || config.ActHeroIDList?.Length <= index) return 0;
        if (config == null || config.ActHeroIDList?.Length <= callHeroIndex) return 0;
        return config.ActHeroIDList[index];
        return config.ActHeroIDList[callHeroIndex];
    }
    public int GetLuckValueAward(int type)
    {
        XBTypeInfo typeInfo = HappyXBModel.Instance.GetXBInfoByType(type);
        if (typeInfo == null) return 0;
        var xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(type);
        var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList();
        luckList.Sort();
        for (int i = 0; i < luckList.Count; i++)
        {
            var luckyValue = typeInfo.luckValue;
            if (luckyValue < luckList[i])
            {
                return luckList[i];
            }
        }
        return 0;
    }
    public int GetNextXBCountForBigAward(int type)
    {
        XBTypeInfo typeInfo = HappyXBModel.Instance.GetXBInfoByType(type);
        if (typeInfo == null) return 0;
        var xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(type);
        var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList();
        luckList.Sort();
        for (int i = 0; i < luckList.Count; i++)
        {
            var luckyValue = typeInfo.luckValue;
            if (luckyValue < luckList[i])
            {
                return luckList[i] - luckyValue;
            }
        }
        return 0;
    }
    #endregion
    #region 时装特卖
@@ -850,6 +907,26 @@
        return ctgDict;
    }
    public bool HasItemInSkinCTGIDList(int cfgID, int findItemID)
    {
        var config = ActHeroAppearConfig.Get(cfgID);
        if (config == null || config.SkinCTGIDList == null) return false;
        for (int i = 0; i < config.SkinCTGIDList.Length; i++)
        {
            var ctgID = config.SkinCTGIDList[i];
            var ctgConfig = CTGConfig.Get(ctgID);
            if (ctgConfig == null || ctgConfig.GainItemList == null) continue;
            for (int j = 0; j < ctgConfig.GainItemList.Length; j++)
            {
                var itemID = ctgConfig.GainItemList[j][0];
                if (itemID == findItemID) return true;
            }
        }
        return false;
    }
    public List<int> GetSkinIDList(int cfgID, int heroID, int mainSkinID)
    {
@@ -907,6 +984,354 @@
    #endregion
    #region 战令
    /// <summary>
    /// 武将登场战令类型(从配置实时获取)
    /// </summary>
    public int ZhanLingType => GetCurrentZhanLingType();
    /// <summary>
    /// 获取当前战令类型
    /// </summary>
    private int GetCurrentZhanLingType()
    {
        var act = GetOperationHeroAppearInfo();
        if (act == null)
            return 0;
        var config = ActHeroAppearConfig.Get(act.CfgID);
        return config?.ActZhanlingType ?? 0;
    }
    /// <summary>
    /// 武将登场战令功能ID
    /// </summary>
    public const int ZhanLingFuncId = 63;
    /// <summary>
    /// 战令数据更新事件
    /// </summary>
    public event Action OnZhanLingUpdateEvent;
    private void OnBattlePassDataUpdate(int type)
    {
        if (type == ZhanLingType)
        {
            OnZhanLingUpdateEvent?.Invoke();
        }
    }
    /// <summary>
    /// 获取武将登场战令的当前进度值
    /// </summary>
    public int GetZhanLingValue()
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        return data != null ? (int)data.value1 : 0;
    }
    /// <summary>
    /// 判断指定类型是否为ZhanLing类型(缓存查询)
    /// </summary>
    public static bool IsZhanLingType(int type)
    {
        if (zhanLingTypeList == null)
        {
            zhanLingTypeList = ActHeroAppearConfig.GetValues()
                .Select(x => x.ActZhanlingType)
                .Where(x => x > 0)
                .Distinct()
                .ToList();
        }
        return zhanLingTypeList.Contains(type);
    }
    /// <summary>
    /// 获取指定ZhanLing类型的进度值
    /// </summary>
    public static int GetZhanLingValueByType(int zhanLingType)
    {
        var data = BattlePassManager.Instance.GetBattlePassData(zhanLingType);
        return data != null ? (int)data.value1 : 0;
    }
    /// <summary>
    /// 判断武将登场战令的指定等级是否达成
    /// </summary>
    public bool IsZhanLingNeedValueOk(int needValue)
    {
        return GetZhanLingValue() >= needValue;
    }
    /// <summary>
    /// 获取武将登场战令的购买状态
    /// 0 没购买进阶和玄级 1 购买了进阶没买玄级 2 购买了玄级没买进阶 3 购买了进阶和玄级
    /// </summary>
    public int GetZhanLingBuyState()
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return 0;
        bool isBuyPaid = data.isActivite > 0;
        bool isBuyPaidH = data.isActiviteH > 0;
        if (isBuyPaid && isBuyPaidH)
            return 3;
        if (isBuyPaid)
            return 1;
        if (isBuyPaidH)
            return 2;
        return 0;
    }
    /// <summary>
    /// 是否有可领取的战令奖励
    /// </summary>
    public bool HasZhanLingCanHave()
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return false;
        var dict = ZhanlingConfig.GetTypeToIDDict(ZhanLingType);
        if (dict.IsNullOrEmpty())
            return false;
        int buyState = GetZhanLingBuyState();
        bool isBuyPaid = buyState == 1 || buyState == 3;
        bool isBuyPaidH = buyState == 2 || buyState == 3;
        foreach (var kvp in dict)
        {
            int needValue = kvp.Key;
            // 检查免费奖励
            int freeState = GetZhanLingFreeGiftState(needValue);
            if (freeState == 1)
                return true;
            // 检查普通奖励(需要已购买进阶)
            if (isBuyPaid)
            {
                int paidState = GetZhanLingPaidGiftState(needValue);
                if (paidState == 1)
                    return true;
            }
            // 检查高级奖励(需要已购买玄级)
            if (isBuyPaidH)
            {
                int paidHState = GetZhanLingPaidGiftHState(needValue);
                if (paidHState == 1)
                    return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 获取武将登场战令免费奖励状态
    /// 0 不能领 1 未领取 2 已领取
    /// </summary>
    public int GetZhanLingFreeGiftState(int needValue)
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return 0;
        var totalValue = BattlePassManager.Instance.GetTotalValue(ZhanLingType);
        return BattlePassManager.Instance.GetBPCellAwardState(data, totalValue, needValue, 0);
    }
    /// <summary>
    /// 获取武将登场战令普通奖励状态
    /// 0 不能领 1 未领取 2 已领取
    /// </summary>
    public int GetZhanLingPaidGiftState(int needValue)
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return 0;
        var totalValue = BattlePassManager.Instance.GetTotalValue(ZhanLingType);
        return BattlePassManager.Instance.GetBPCellAwardState(data, totalValue, needValue, 1);
    }
    /// <summary>
    /// 获取武将登场战令高级奖励状态
    /// 0 不能领 1 未领取 2 已领取
    /// </summary>
    public int GetZhanLingPaidGiftHState(int needValue)
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return 0;
        var totalValue = BattlePassManager.Instance.GetTotalValue(ZhanLingType);
        return BattlePassManager.Instance.GetBPCellAwardState(data, totalValue, needValue, 2);
    }
    /// <summary>
    /// 一键领取武将登场战令所有可领取奖励
    /// </summary>
    public void HaveAllZhanLingGift()
    {
        var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType);
        if (data == null)
            return;
        if (PackManager.Instance.GetEmptyGridCount(PackType.Item) < 1)
        {
            SysNotifyMgr.Instance.ShowTip("GeRen_lhs_202580");
            return;
        }
        var totalValue = BattlePassManager.Instance.GetTotalValue(ZhanLingType);
        BattlePassManager.Instance.GetAllAward(data, ZhanLingType, totalValue);
    }
    #endregion
    #region 战令预览购买
    /// <summary>
    /// 当前预览的战令类型
    /// </summary>
    public int previewZhanLingType { get; private set; }
    /// <summary>
    /// 当前预览的礼包类型 1 普通战令礼包 2 高级战令礼包
    /// </summary>
    public int previewGiftType { get; private set; }
    /// <summary>
    /// 显示战令购买预览界面
    /// </summary>
    public void ShowZhanLingHBuy(int zhanLingType, int showGiftType)
    {
        previewZhanLingType = zhanLingType;
        previewGiftType = showGiftType;
        if (showGiftType == 1)
        {
            UIManager.Instance.OpenWindow<HeroDebutZhanLingPreviewWin>();
        }
        else if (showGiftType == 2)
        {
            UIManager.Instance.OpenWindow<HeroDebutZhanLingPreviewHWin>();
        }
    }
    /// <summary>
    /// 获取当前预览类型的充值ID
    /// </summary>
    public int GetPreviewCtgID()
    {
        int ctgid = 0;
        if (previewGiftType == 1)
        {
            ctgid = BattlePassManager.Instance.GetCTGIDByType(previewZhanLingType);
        }
        else if (previewGiftType == 2)
        {
            // 高级战令使用 Numerical3
            var config = FuncConfigConfig.Get("Zhanling");
            if (config != null)
            {
                var dict = ConfigParse.ParseIntArrayDict(config.Numerical3);
                if (dict.TryGetValue(previewZhanLingType, out var arr) && arr.Length > 0)
                {
                    ctgid = arr[0];
                }
            }
        }
        return ctgid;
    }
    /// <summary>
    /// 获取购买后所有等级的奖励
    /// </summary>
    /// <param name="maxCountPerSlot">每个相同的itemid每个格子最大同时显示的数量</param>
    public List<Item> GetPreviewGiftAllItem(int maxCountPerSlot = 20)
    {
        List<int> collectList = new List<int>();
        var dict = ZhanlingConfig.GetTypeToIDDict(previewZhanLingType);
        if (dict.IsNullOrEmpty())
            return new List<Item>();
        var arr = dict.Keys.ToArray();
        for (int i = 0; i < arr.Length; i++)
        {
            int needValue = arr[i];
            int zhanLingId = dict[needValue];
            collectList.Add(zhanLingId);
        }
        return CollectPreviewItems(collectList, maxCountPerSlot);
    }
    private List<Item> CollectPreviewItems(List<int> collectList, int maxCountPerSlot)
    {
        Dictionary<int, int> resultDict = new Dictionary<int, int>();
        for (int i = 0; i < collectList.Count; i++)
        {
            int zhanLingId = collectList[i];
            int[][] itemArr = GetPreviewItemArr(zhanLingId, previewGiftType);
            if (itemArr.IsNullOrEmpty())
                continue;
            for (int j = 0; j < itemArr.Length; j++)
            {
                int itemID = itemArr[j][0];
                int count = itemArr[j][1];
                if (resultDict.ContainsKey(itemID))
                    resultDict[itemID] += count;
                else
                    resultDict[itemID] = count;
            }
        }
        List<Item> result = GetItemListByDict(resultDict, maxCountPerSlot);
        result.Sort(CmpPreviewItem);
        return result;
    }
    private int[][] GetPreviewItemArr(int zhanLingId, int showGiftType)
    {
        var config = ZhanlingConfig.Get(zhanLingId);
        if (config == null)
            return new int[][] { };
        if (showGiftType == 1)
            return config.ZLRewardItemList;
        if (showGiftType == 2)
            return config.ZLRewardItemListH;
        return new int[][] { };
    }
    private List<Item> GetItemListByDict(Dictionary<int, int> dict, int maxCountPerSlot)
    {
        List<Item> result = new List<Item>();
        var arr = dict.Keys.ToArray();
        for (int i = 0; i < arr.Length; i++)
        {
            int itemID = arr[i];
            int count = dict[itemID];
            // 根据maxCountPerSlot拆分数量,每个Item最多显示maxCountPerSlot个
            int slotCount = Mathf.CeilToInt((float)count / maxCountPerSlot);
            for (int s = 0; s < slotCount; s++)
            {
                int itemCount = Mathf.Min(maxCountPerSlot, count - s * maxCountPerSlot);
                result.Add(new Item(itemID, itemCount));
            }
        }
        return result;
    }
    private int CmpPreviewItem(Item a, Item b)
    {
        int quality1 = ItemConfig.Get(a.id).ItemColor;
        int quality2 = ItemConfig.Get(b.id).ItemColor;
        if (quality1 != quality2)
            return quality2.CompareTo(quality1);
        return a.countEx.CompareTo(b.countEx);
    }
    #endregion
    #region 获奖记录
    public static readonly int RecordType = 311;
@@ -926,19 +1351,10 @@
    {
        return gameRecDict;
    }
    public List<HeroDebutGameRec> GetLastFourRecords()
    {
        if (gameRecDict == null || gameRecDict.Count == 0) return new List<HeroDebutGameRec>();
        int count = gameRecDict.Count;
        int takeCount = Math.Min(4, count);
        return gameRecDict.GetRange(count - takeCount, takeCount);
    }
    public event Action OnUpdateGameRecInfo;
    public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData)
    {
        var act = GetOperationHeroAppearInfo();
        if (act == null) return;
@@ -1004,6 +1420,7 @@
    StarUp = 2,
    Shop = 3,
    Gift = 4,
    ZhanLing = 5,
}
public class HeroDebutGameRec