825a7d18472150b6fc238ad73ed3efc4659ab37e..91f6a3eb7961367d942b232ed3ea8810a6bf488a
2025-11-05 hch
236 子 【福利内容】每周任务
91f6a3 对比 | 目录
2025-11-05 hch
0312 引导增加展示期,展示过后才能点击引导
f086c1 对比 | 目录
2025-11-05 yyl
125 战斗 计算单位统一
ceda2d 对比 | 目录
2025-11-05 yyl
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
168e03 对比 | 目录
2025-11-05 yyl
125 战斗 吸血跟反伤
39f077 对比 | 目录
2025-11-05 lcy
130 战斗修改回合样式
3b2a6b 对比 | 目录
2025-11-05 hch
340 战斗封包对数据的影响测试
246dc3 对比 | 目录
2025-11-05 lcy
130 战斗移除暂停按钮
690b5d 对比 | 目录
2025-11-05 yyl
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
170e85 对比 | 目录
2025-11-05 yyl
125 战斗血量问题修复
b75bf9 对比 | 目录
2025-11-05 hch
Merge branch 'master' of http://mobile.secondworld.net.cn:10010/r/Project_S...
87bb18 对比 | 目录
2025-11-05 hch
0312 强制刷新淘金聊天排版
55903b 对比 | 目录
2025-11-05 yyl
b419 注册
2f2521 对比 | 目录
2025-11-05 yyl
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
d613cd 对比 | 目录
2025-11-05 yyl
125 战斗 天子血条刷新包
ca85c0 对比 | 目录
2025-11-05 hch
0312 优化掉落体验
bd3e78 对比 | 目录
2025-11-05 yyl
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
c6ccb0 对比 | 目录
2025-11-05 yyl
125 战斗 战斗死亡掉落时间点修改
79756e 对比 | 目录
2025-11-05 hch
0312 功能开启提示调整
bbd202 对比 | 目录
2025-11-05 hch
0312 淘金未开启相关按钮隐藏
76d7d0 对比 | 目录
2025-11-05 hch
0312 武将觉醒增加开启条件
f84552 对比 | 目录
9 文件已复制
2个文件已删除
2 文件已重命名
10个文件已添加
29个文件已修改
1505 ■■■■ 已修改文件
Main/Common/EventName.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/FuncOpen.cs 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/ConfigManager.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/ZhanlingConfig.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/ZhanlingConfig.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/ZhanlingConfig.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/ZhanlingConfig.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0418_tagObjInfoRefresh.cs 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA005_tagOpenServerDay.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA005_tagOpenServerDay.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA103_tagMCOpenServerDay.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA103_tagMCOpenServerDay.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB120_tagMCZhanlingInfo.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB4_FightDefine/DTCB419_tagSCObjHPRefresh.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB4_FightDefine/DTCB419_tagSCObjHPRefresh.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HB4_FightDefine/HB419_tagSCObjHPRefresh.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HB4_FightDefine/HB419_tagSCObjHPRefresh.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Main.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BaseBattleWin.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/BattleField.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/RecordActions/DeathRecordAction.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleObject/BattleObject.cs 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleUtility.cs 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Define/BattleDmgInfo.cs 122 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Motion/MotionBase.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Skill/SkillBase.cs 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/UIComp/BattleHeroInfoBar.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BattlePass.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BattlePass/BattlePassManager.Week.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BattlePass/BattlePassManager.Week.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BattlePass/BattlePassManager.cs 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BattlePass/BattlePassManager.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/DayMissionBaseWin.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/DayMissionManager.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/WeekBattlePassCell.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/WeekBattlePassCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/WeekBattlePassWin.cs 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/DayMission/WeekBattlePassWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/FloorItemCell.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/ItemsOnFloor.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallResultWin.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/AffairBaseWin.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/GoldRushLeader.cs 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/GoldRushTentCell.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/NewBieGuidance/NewBieGuideScriptableObject.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/NewBieGuidance/NewBieWin.cs 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/GlobalTimeEvent.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/TimeUtility.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Common/EventName.cs
@@ -16,4 +16,6 @@
    
    public const string BATTLE_END = "BATTLE_END";//战斗结束
    public const string RECORDPLAYER_END = "RECORDPLAYER_END"; //战斗小片段结束
    public const string BATTLE_TIANZI_REFRESH_HP = "BATTLE_TIANZI_REFRESH_HP";//天子考验 刷新血量
}
Main/Component/UI/Common/FuncOpen.cs
@@ -181,39 +181,36 @@
                switch (errorCode)
                {
                    case 1:
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Level", config.LimitLV)
                        + Language.Get("FuncLimitOpen1"));
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Level", config.LimitLV));
                        break;
                    case 2:
                        //开服多少天 一般是组合
                        if (config.LimitLV != 0)
                        {
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay", config.OpenDay)
                             + Language.Get("FuncLimitOpen2")
                             + Language.Get("FuncLimit_Level", config.LimitLV)
                             + Language.Get("FuncLimitOpen1"));
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay_LV",
                            config.LimitLV, TimeUtility.OpenDay + 1, config.OpenDay));
                        }
                        else if (config.LimitMissionID != 0)
                        {
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay", config.OpenDay)
                             + Language.Get("FuncLimitOpen2")
                             + Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID))
                             + Language.Get("FuncLimitOpen1"));
                        {
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay_Mission",
                            TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID), TimeUtility.OpenDay + 1, config.OpenDay));
                        }
                        else if (config.LimiRealmLV != 0)
                        {
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay_Realm",
                            RealmConfig.Get(config.LimiRealmLV).Name, TimeUtility.OpenDay + 1, config.OpenDay));
                        }
                        else
                        {
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay", config.OpenDay)
                             + Language.Get("FuncLimitOpen1"));
                            SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_OpenDay", config.OpenDay));
                        }
                        break;
                    case 3:
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Realm", RealmConfig.Get(config.LimiRealmLV).Name)
                         + Language.Get("FuncLimitOpen1"));
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Realm", RealmConfig.Get(config.LimiRealmLV).Name));
                        break;
                    case 4:
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID))
                         + Language.Get("FuncLimitOpen1"));
                        SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID)));
                        break;
                }
            }
@@ -231,43 +228,30 @@
            switch (errorCode)
            {
                case 1:
                    return StringUtility.Contact(
                        Language.Get("FuncLimit_Level", config.LimitLV),
                        Language.Get("FuncLimitOpen1"));
                    return Language.Get("FuncLimit_Level", config.LimitLV);
                case 2:
                    //开服多少天 一般是组合
                    if (config.LimitLV != 0)
                    {
                        return StringUtility.Contact(
                            Language.Get("FuncLimit_OpenDay", config.OpenDay),
                            Language.Get("FuncLimitOpen2"),
                        Language.Get("FuncLimit_Level", config.LimitLV),
                        Language.Get("FuncLimitOpen1"));
                        return Language.Get("FuncLimit_OpenDay_LV", config.LimitLV, TimeUtility.OpenDay + 1, config.OpenDay);
                    }
                    else if (config.LimitMissionID != 0)
                    {
                        return StringUtility.Contact(
                            Language.Get("FuncLimit_OpenDay", config.OpenDay),
                            Language.Get("FuncLimitOpen2"),
                        Language.Get("FuncLimit_Mission",
                        TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID)),
                        Language.Get("FuncLimitOpen1"));
                        return Language.Get("FuncLimit_OpenDay_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID), TimeUtility.OpenDay + 1, config.OpenDay);
                    }
                    else if (config.LimiRealmLV != 0)
                    {
                        return Language.Get("FuncLimit_OpenDay_Realm", RealmConfig.Get(config.LimiRealmLV).Name, TimeUtility.OpenDay + 1, config.OpenDay);
                    }
                    else
                    {
                        return StringUtility.Contact(
                            Language.Get("FuncLimit_OpenDay", config.OpenDay),
                            Language.Get("FuncLimitOpen1"));
                        return Language.Get("FuncLimit_OpenDay", config.OpenDay);
                    }
                case 3:
                    return StringUtility.Contact(
                            Language.Get("FuncLimit_Realm", RealmConfig.Get(config.LimiRealmLV).Name),
                            Language.Get("FuncLimitOpen1"));
                    return Language.Get("FuncLimit_Realm", RealmConfig.Get(config.LimiRealmLV).Name);
                case 4:
                    return StringUtility.Contact(
                            Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID)),
                            Language.Get("FuncLimitOpen1"));
                    return Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID));
            }
        }
        return string.Empty;
Main/Config/ConfigManager.cs
@@ -75,7 +75,8 @@
            typeof(TreasureSetConfig),
            typeof(TreeLVConfig),
            typeof(WindowSearchConfig),
            typeof(XBGetItemConfig)
            typeof(XBGetItemConfig),
            typeof(ZhanlingConfig)
        };
#if UNITY_EDITOR
@@ -301,6 +302,8 @@
        ClearConfigDictionary<WindowSearchConfig>();
        // 清空 XBGetItemConfig 字典
        ClearConfigDictionary<XBGetItemConfig>();
        // 清空 ZhanlingConfig 字典
        ClearConfigDictionary<ZhanlingConfig>();
    }
#if UNITY_EDITOR
Main/Config/Configs/ZhanlingConfig.cs
New file
@@ -0,0 +1,56 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           Tuesday, November 4, 2025
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class ZhanlingConfig : ConfigBase<int, ZhanlingConfig>
{
    static ZhanlingConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int ZhanlingId;
    public int ZhanlingType;
    public int NeedValue;
    public int RewardIndex;
    public int[][] FreeRewardItemList;
    public int[][] ZLRewardItemList;
    public int[][] ZLRewardItemListH;
    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 ZhanlingId);
            int.TryParse(tables[1],out ZhanlingType);
            int.TryParse(tables[2],out NeedValue);
            int.TryParse(tables[3],out RewardIndex);
            FreeRewardItemList = JsonMapper.ToObject<int[][]>(tables[4].Replace("(", "[").Replace(")", "]"));
            ZLRewardItemList = JsonMapper.ToObject<int[][]>(tables[5].Replace("(", "[").Replace(")", "]"));
            ZLRewardItemListH = JsonMapper.ToObject<int[][]>(tables[6].Replace("(", "[").Replace(")", "]"));
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/ZhanlingConfig.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/Config/Configs/ZhanlingConfig.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 0a982bd9a3eaef84fa25269ec4301050
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Config/PartialConfigs/ZhanlingConfig.cs
New file
@@ -0,0 +1,25 @@
using System.Collections.Generic;
public partial class ZhanlingConfig : ConfigBase<int, ZhanlingConfig>
{
    //战令类型: 所需值 :ZhanlingId
    static Dictionary<int, Dictionary<int, int>> typeToIDDict = new Dictionary<int, Dictionary<int, int>>();
    protected override void OnConfigParseCompleted()
    {
        if (!typeToIDDict.ContainsKey(ZhanlingType))
        {
            typeToIDDict[ZhanlingType] = new Dictionary<int, int>();
        }
        typeToIDDict[ZhanlingType][NeedValue] = ZhanlingId;
    }
    public static Dictionary<int, int> GetTypeToIDDict(int zhanLingType)
    {
        return typeToIDDict[zhanLingType];
    }
    public static Dictionary<int, Dictionary<int, int>> GetAllTypeToIDListDict()
    {
        return typeToIDDict;
    }
}
Main/Config/PartialConfigs/ZhanlingConfig.cs.meta
File was renamed from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 8aa62178ddc66b2479b841083ee2b290
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DTCFile/ServerPack/H04_Scene/DTC0418_tagObjInfoRefresh.cs
@@ -1,10 +1,17 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//04 18 周围对象刷新#tagObjInfoRefresh
public class DTC0418_tagObjInfoRefresh : DtcBasic {
    static ulong lastPackUID = 0;
    //类型
    static Dictionary<int, ulong> lastPackUIDDict = new Dictionary<int, ulong>()
    {
        {(int)PlayerDataType.ExAttr1, 0},
        {(int)PlayerDataType.ExAttr2, 0},
        {(int)PlayerDataType.default26, 0},
    };
    public override void Done(GameNetPackBasic vNetPack)
    {
        base.Done(vNetPack);
@@ -16,9 +23,16 @@
        switch (vNetData.ObjType)
        {
            case 1:
                if (vNetData.packUID > DTC0102_tagCDBPlayer.loginPackUID && vNetData.packUID > lastPackUID)
                if (vNetData.packUID > DTC0102_tagCDBPlayer.loginPackUID)
                {
                    lastPackUID = vNetData.packUID;
                    if (lastPackUIDDict.ContainsKey(vNetData.RefreshType))
                    {
                        if (vNetData.packUID < lastPackUIDDict[vNetData.RefreshType])
                        {
                            return;
                        }
                        lastPackUIDDict[vNetData.RefreshType] = vNetData.packUID;
                    }
                    //防范断线重连时,战斗中的旧包影响数据
                    Update0418(vNetData);
                }
Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA005_tagOpenServerDay.cs
File was deleted
Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA005_tagOpenServerDay.cs.meta
File was deleted
Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA103_tagMCOpenServerDay.cs
New file
@@ -0,0 +1,12 @@
using UnityEngine;
using System.Collections;
// A1 03 同步开服天数 #tagMCOpenServerDay
public class DTCA103_tagMCOpenServerDay : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HA103_tagMCOpenServerDay vNetData = vNetPack as HA103_tagMCOpenServerDay;
        TimeUtility.OnRefreshServerOpenDay(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA103_tagMCOpenServerDay.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA103_tagMCOpenServerDay.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 639049f3084500b42bd546a764c4ef94
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB120_tagMCZhanlingInfo.cs
@@ -1,11 +1,12 @@
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
// B1 20 战令信息 #tagMCZhanlingInfo
public class DTCB120_tagMCZhanlingInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HB120_tagMCZhanlingInfo vNetData = vNetPack as HB120_tagMCZhanlingInfo;
        BattlePassManager.Instance.UpdateBattlePassInfo(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HB4_FightDefine/DTCB419_tagSCObjHPRefresh.cs
New file
@@ -0,0 +1,18 @@
using UnityEngine;
using System.Collections;
// B4 19 对象最新生命刷新 #tagSCObjHPRefresh
public class DTCB419_tagSCObjHPRefresh : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HB419_tagSCObjHPRefresh vNetData = vNetPack as HB419_tagSCObjHPRefresh;
        BattleField battleField = BattleManager.Instance.GetBattleField(vNetData.packUID);
        if (null != battleField)
        {
            battleField.OnRefreshObjHP(vNetData);
            battleField.DistributeNextPackage();
        }
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HB4_FightDefine/DTCB419_tagSCObjHPRefresh.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HB4_FightDefine/DTCB419_tagSCObjHPRefresh.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 3d2361817f6a81a4ea0d05eaf7b8f59e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -30,7 +30,7 @@
        // 登记相应的数据体及对应的数据转逻辑类(去重后)
        Register(typeof(H0102_tagCDBPlayer), typeof(DTC0102_tagCDBPlayer));
        Register(typeof(HA004_tagServerDateTime), typeof(DTCA004_tagServerDateTime));
        Register(typeof(HA005_tagOpenServerDay), typeof(DTCA005_tagOpenServerDay));
        Register(typeof(HA103_tagMCOpenServerDay), typeof(DTCA103_tagMCOpenServerDay));
        Register(typeof(H0403_tagPlayerLoginLoadOK), typeof(DTC0403_tagPlayerLoginLoadOK));
        Register(typeof(H0101_tagServerPrepared), typeof(DTC0101_tagServerPrepared));
        Register(typeof(H0104_tagServerDisconnect), typeof(DTC0104_tagServerDisconnect));
@@ -79,6 +79,7 @@
        Register(typeof(HA921_tagUpdatePlayerNameResult), typeof(DTCA921_tagUpdatePlayerNameResult));
        Register(typeof(H3202_tagServerResponse), typeof(DTC3202_tagServerResponse));
        Register(typeof(HA130_tagMCViewBillboardRet), typeof(DTCA130_tagMCViewBillboardRet));
        Register(typeof(HB419_tagSCObjHPRefresh), typeof(DTCB419_tagSCObjHPRefresh));
        Register(typeof(HB420_tagMCTurnFightState), typeof(DTCB420_tagMCTurnFightState));
        Register(typeof(HB421_tagMCTurnFightObjAction), typeof(DTCB421_tagMCTurnFightObjAction));
        Register(typeof(HB422_tagMCTurnFightObjDead), typeof(DTCB422_tagMCTurnFightObjDead));
Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs
File was renamed from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs
@@ -1,9 +1,9 @@
using UnityEngine;
using System.Collections;
//A0 05 同步开服天数 #tagOpenServerDay
// A1 03 同步开服天数 #tagMCOpenServerDay
public class HA005_tagOpenServerDay : GameNetPackBasic {
public class HA103_tagMCOpenServerDay : GameNetPackBasic {
    public ushort Day;    // 已开服天数,从0开始
    public byte IsMixServer;    //是否是合服服务器
    public ushort MixDay;    // 已合服天数,从0开始
@@ -17,8 +17,8 @@
    public uint NowMicSecond;
    public byte WeekOfYear;    //一年中的第几周
    public HA005_tagOpenServerDay () {
        _cmd = (ushort)0xA005;
    public HA103_tagMCOpenServerDay () {
        _cmd = (ushort)0xA103;
    }
    public override void ReadFromBytes (byte[] vBytes) {
Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: e092a0db076d7f04f8113dd4269bd9e0
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Core/NetworkPackage/ServerPack/HB4_FightDefine/HB419_tagSCObjHPRefresh.cs
New file
@@ -0,0 +1,25 @@
using UnityEngine;
using System.Collections;
// B4 19 对象最新生命刷新 #tagSCObjHPRefresh
public class HB419_tagSCObjHPRefresh : GameNetPackBasic {
    public uint ObjID;
    public uint HP;    // 当前血量,求余20亿部分
    public uint HPEx;    // 当前血量,整除20亿部分
    public uint MaxHP;    // 最大血量,求余20亿部分
    public uint MaxHPEx;    // 最大血量,整除20亿部分
    public HB419_tagSCObjHPRefresh () {
        _cmd = (ushort)0xB419;
    }
    public override void ReadFromBytes (byte[] vBytes) {
        TransBytes (out ObjID, vBytes, NetDataType.DWORD);
        TransBytes (out HP, vBytes, NetDataType.DWORD);
        TransBytes (out HPEx, vBytes, NetDataType.DWORD);
        TransBytes (out MaxHP, vBytes, NetDataType.DWORD);
        TransBytes (out MaxHPEx, vBytes, NetDataType.DWORD);
    }
}
Main/Core/NetworkPackage/ServerPack/HB4_FightDefine/HB419_tagSCObjHPRefresh.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/Core/NetworkPackage/ServerPack/HB4_FightDefine/HB419_tagSCObjHPRefresh.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 4d172d7090e7f3b42958b6ce5bf20dc3
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/Main.cs
@@ -82,6 +82,7 @@
        managers.Add(BoneFieldManager.Instance);
        managers.Add(ArenaManager.Instance);
        managers.Add(DayMissionManager.Instance);
        managers.Add(BattlePassManager.Instance);
        
        foreach (var manager in managers)
        {
Main/System/Battle/BaseBattleWin.cs
@@ -14,7 +14,6 @@
    [SerializeField] protected Button btnSpeed; // 速度控制
    [SerializeField] protected Text textSpeed; // 速度显示
    [SerializeField] protected Button btnPass; // 跳过战斗
    [SerializeField] protected Button btnPause; // 暂停按钮 (BattleWin中的btnStop可对应此按钮)
    [Header("战斗UI组件")]
    [SerializeField] protected TotalDamageDisplayer totalDamageDisplayer; // 伤害统计
@@ -33,9 +32,6 @@
        if (btnPass != null)
            btnPass.AddListener(OnClickPass);
        if (btnPause != null)
            btnPause.AddListener(OnClickPause);
    }
    protected override void OnPreOpen()
@@ -179,16 +175,6 @@
    /// <summary>
    /// 暂停/继续
    /// </summary>
    protected virtual void OnClickPause()
    {
        if (null == battleField)
            return;
        battleField.IsPause = !battleField.IsPause;
    }
    /// <summary>
    /// 跳过战斗
    /// </summary>
    protected virtual void OnClickPass()
@@ -285,7 +271,7 @@
    {
        if (txtBattleRound != null)
        {
            txtBattleRound.text = string.Format("{0}/{1}", round, maxRound);
            txtBattleRound.text = Language.Get("RoundText", round, maxRound);
        }
    }
Main/System/Battle/BattleField/BattleField.cs
@@ -592,4 +592,20 @@
    {
        return null;
    }
    public void OnRefreshObjHP(HB419_tagSCObjHPRefresh vNetData)
    {
        BattleObject battleObj = battleObjMgr.GetBattleObject((int)vNetData.ObjID);
        if (null != battleObj)
        {
            // battleObj.teamHero.curHp = GeneralDefine.GetFactValue(vNetData.HP, vNetData.HPEx);
            // battleObj.teamHero.maxHp = GeneralDefine.GetFactValue(vNetData.MaxHP, vNetData.MaxHPEx);
            EventBroadcast.Instance.Broadcast<HB419_tagSCObjHPRefresh>(
                EventName.BATTLE_TIANZI_REFRESH_HP, vNetData);
            //battleObj.teamHero.curHp, battleObj.teamHero.maxHp
        }
    }
}
Main/System/Battle/BattleField/RecordActions/DeathRecordAction.cs
@@ -36,13 +36,12 @@
                BattleObject deadObj = battleField.battleObjMgr.GetBattleObject((int)deadPack.ObjID);
                if (null != deadObj)
                {
                    PerformDrop(deadObj);
                    deadObj.OnDeath(() =>
                    {
                        index++;
                        isLastOne = index >= total;
                        OnDeathAnimationEnd(deadObj);
                        if (isLastOne)
                        {
@@ -78,14 +77,14 @@
            BattleObject deadObj = battleField.battleObjMgr.GetBattleObject((int)deadPack.ObjID);
            if (null != deadObj)
            {
                OnDeathAnimationEnd(deadObj);
                PerformDrop(deadObj);
            }
        }
        base.ForceFinish();
    }
    private void OnDeathAnimationEnd(BattleObject deadObj)
    private void PerformDrop(BattleObject deadObj)
    {
        //  只有主线掉落物品
        if (battleField.MapID == 1 || battleField.MapID == 2)
Main/System/Battle/BattleObject/BattleObject.cs
@@ -291,13 +291,11 @@
        return true;
    }
    public virtual void Hurt(List<long> damageValues, long _totalDamage,
        HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, int hitIndex,
        BattleDrops battleDrops, HB422_tagMCTurnFightObjDead deadPack)
    public virtual void Hurt(BattleHurtParam battleHurtParam)
    {
        bool isLastHit = hitIndex >= skillConfig.DamageDivide.Length - 1;
        bool firstHit = hitIndex == 0;
        BattleDmgInfo dmgInfo = PopDamage(damageValues, _totalDamage, hurt, skillConfig, isLastHit);
        bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1;
        bool firstHit = battleHurtParam.hitIndex == 0;
        BattleDmgInfo dmgInfo = PopDamage(battleHurtParam);
        //  这里
@@ -317,7 +315,7 @@
        bool isFatalAttack = (null != deadPack) && isLastHit;
        bool isFatalAttack = (null != battleHurtParam.deadPack) && isLastHit;
        if (isFatalAttack)
        {
@@ -325,7 +323,7 @@
            {
                PushDropItems(battleDrops);
            }
            battleField.OnObjsDead(new List<HB422_tagMCTurnFightObjDead>() { deadPack });
            battleField.OnObjsDead(new List<HB422_tagMCTurnFightObjDead>() { battleHurtParam.deadPack });
            
        }
        else
@@ -346,18 +344,16 @@
            }
        }
    }
    public void SuckHp(uint suckHP, SkillConfig skillConfig)
    {
        teamHero.curHp = Math.Min(teamHero.maxHp, teamHero.curHp + (int)suckHP);
        // teamHero.curHp = Math.Min(teamHero.maxHp, teamHero.curHp + (int)suckHP);
    }
    public void HurtByReflect(uint bounceHP, SkillConfig skillConfig)
    {
        teamHero.curHp = Math.Max(0, teamHero.curHp - (int)bounceHP);
        // teamHero.curHp = Math.Max(0, teamHero.curHp - (int)bounceHP);
    }
@@ -422,22 +418,12 @@
    }
    // 伤害还要看 是否闪避 暴击 and so on 需要有一个DamageType 服务器应该会给
    protected virtual BattleDmgInfo PopDamage(List<long> damageValues, long _totalDamage, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, bool isLastHit)
    protected virtual BattleDmgInfo PopDamage(BattleHurtParam battleHurtParam)
    {
        BattleDmgInfo battleDmgInfo = new BattleDmgInfo(battleField.guid, damageValues, this, hurt, skillConfig, isLastHit);
        BattleDmgInfo battleDmgInfo = new BattleDmgInfo(battleField.guid, battleHurtParam);
        int currentHurtHp = 0;
        for (int i = 0; i < damageValues.Count; i++)
        {
            currentHurtHp += (int)damageValues[i];
        }
        bool isRecovery = battleDmgInfo.IsType(DamageType.Recovery);
        long toHp = Math.Max(0, teamHero.curHp + (isRecovery ? currentHurtHp : -currentHurtHp));
        heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp);
        teamHero.curHp = toHp;
        // 使用传入的 fromHp 和 toHp 更新血条显示
        heroInfoBar.UpdateHP(battleHurtParam.fromHp, battleHurtParam.toHp, teamHero.maxHp);
        // YYL TODO 是否需要挂在在自身的follow点上
        EventBroadcast.Instance.Broadcast(EventName.BATTLE_DAMAGE_TAKEN, battleDmgInfo);
Main/System/Battle/BattleUtility.cs
@@ -185,7 +185,7 @@
                break;
            case 1:
                // 1    对位:
                // 默认只选1个,对位规则为A1优先打B1,A2优先打B2,A3优先打B3,对位目标死亡时,优先前排,比如B2已经死亡,那么A2将优先打B1,前排1、2、3号位置全部死亡之后才开始选择后排4、5、6号位置,对位只可选1个目标,即主目标
                // 默认只选1个,对位规则为A1优先打B1,A2优先打B2,A3优先打B3,对位目标死亡时,优先前排,比如B2已经死亡,那么A2将优先打B
                if (targetList.Count > 0)
                {
                    BattleObject battleObject = caster.battleField.battleObjMgr.GetBattleObject((int)targetList[0].ObjID);
@@ -283,18 +283,133 @@
    public static int GetDamageNumKey(DamageNumConfig config, int _num)
    {
        if (_num == 46)      return config.nums[10]; // '.'
        if (_num == 46) return config.nums[10]; // '.'
        else if (_num == 107) return config.nums[11]; // 'k'
        else if (_num == 109) return config.nums[12]; // 'm'
        else if (_num == 98)  return config.nums[13]; // 'b'
        else if (_num == 98) return config.nums[13]; // 'b'
        else if (_num == 116) return config.nums[14]; // 't'
        int targetNum = _num - 48;
        if (targetNum >= config.nums.Length || targetNum < 0)
        {
            Debug.LogError("damage config " + config.TypeID + " _num is " +  _num + " out of range");
            Debug.LogError("damage config " + config.TypeID + " _num is " + _num + " out of range");
            return _num;
        }
        return config.nums[_num - 48];
    }
    /// <summary>
    /// 将整个技能的总伤害按命中次数和分段配置分配
    /// </summary>
    /// <param name="damageDivideList">整个技能的所有命中分段配置</param>
    /// <param name="hitIndex">当前是第几击(从0开始)</param>
    /// <param name="totalDamage">整个技能的总伤害</param>
    /// <returns>这一击内每一段的伤害值列表</returns>
    public static List<long> DivideDamageToList(int[][] damageDivideList, int hitIndex, long totalDamage)
    {
        if (totalDamage <= 0)
        {
            return new List<long>{};
        }
        if (damageDivideList == null || damageDivideList.Length == 0)
        {
            Debug.LogError("damageDivideList 为空或长度为0");
            return new List<long> { totalDamage };
        }
        if (hitIndex < 0 || hitIndex >= damageDivideList.Length)
        {
            Debug.LogError($"hitIndex={hitIndex} 超出范围, damageDivideList.Length={damageDivideList.Length}");
            return new List<long> { totalDamage };
        }
        int[] currentHitDivide = damageDivideList[hitIndex];
        if (currentHitDivide == null || currentHitDivide.Length == 0)
        {
            Debug.LogError($"damageDivide[{hitIndex}] 为空或长度为0");
            return new List<long> { totalDamage };
        }
        // ============ 第一步: 计算每一击应该造成的伤害 ============
        // 先计算所有击的总权重
        int totalWeight = 0;
        for (int i = 0; i < damageDivideList.Length; i++)
        {
            if (damageDivideList[i] != null && damageDivideList[i].Length > 0)
            {
                // 每一击的权重是其所有分段之和
                for (int j = 0; j < damageDivideList[i].Length; j++)
                {
                    totalWeight += damageDivideList[i][j];
                }
            }
        }
        if (totalWeight == 0)
        {
            Debug.LogError("totalWeight 为 0");
            return new List<long> { totalDamage };
        }
        // 计算当前这一击的权重
        int currentHitWeight = 0;
        for (int i = 0; i < currentHitDivide.Length; i++)
        {
            currentHitWeight += currentHitDivide[i];
        }
        // 计算当前这一击应该造成的总伤害
        long currentHitTotalDamage;
        bool isLastHit = hitIndex >= damageDivideList.Length - 1;
        if (isLastHit)
        {
            // 最后一击: 计算前面所有击已经造成的伤害,剩余的全部给最后一击
            long previousHitsDamage = 0;
            for (int i = 0; i < hitIndex; i++)
            {
                if (damageDivideList[i] != null)
                {
                    int hitWeight = 0;
                    for (int j = 0; j < damageDivideList[i].Length; j++)
                    {
                        hitWeight += damageDivideList[i][j];
                    }
                    previousHitsDamage += (long)((float)totalDamage * (float)hitWeight / (float)totalWeight);
                }
            }
            currentHitTotalDamage = totalDamage - previousHitsDamage;
        }
        else
        {
            // 非最后一击: 按权重计算
            currentHitTotalDamage = (long)((float)totalDamage * (float)currentHitWeight / (float)totalWeight);
        }
        // ============ 第二步: 将当前这一击的伤害分配到各分段 ============
        List<long> fixedDamageList = new List<long>();
        long accumulatedDamage = 0;
        for (int i = 0; i < currentHitDivide.Length; i++)
        {
            long damage;
            // 当前击的最后一段进行误差补偿
            if (i == currentHitDivide.Length - 1)
            {
                damage = currentHitTotalDamage - accumulatedDamage;
            }
            else
            {
                // 按当前击的权重分配
                damage = (long)((float)currentHitTotalDamage * (float)currentHitDivide[i] / (float)currentHitWeight);
                accumulatedDamage += damage;
            }
            fixedDamageList.Add(damage);
        }
        return fixedDamageList;
    }
    /// <summary>
@@ -302,16 +417,53 @@
    /// </summary>
    public static List<long> DivideDamageToList(int[] damageDivide, long totalDamage)
    {
        if (damageDivide == null || damageDivide.Length == 0)
        {
            Debug.LogError("damageDivide 为空或长度为0");
            return new List<long> { totalDamage };
        }
        List<long> fixedDamageList = new List<long>();
        long accumulatedDamage = 0; // 累计已分配的伤害
        for (int i = 0; i < damageDivide.Length; i++)
        {
            float fixedDamage = (float)totalDamage * (float)damageDivide[i] / 10000f;
            fixedDamageList.Add((int)fixedDamage);
            long damage;
            // 最后一次分配:用总伤害减去已分配的伤害,确保总和精确
            if (i == damageDivide.Length - 1)
            {
                damage = totalDamage - accumulatedDamage;
            }
            else
            {
                // 计算当前分段伤害(向下取整)
                damage = (long)((float)totalDamage * (float)damageDivide[i] / 10000f);
                accumulatedDamage += damage;
            }
            fixedDamageList.Add(damage);
        }
        return fixedDamageList;
    }
    public static HB419_tagSCObjHPRefresh FindObjHPRefreshPack(List<GameNetPackBasic> packList)
    {
        for (int i = 0; i < packList.Count; i++)
        {
            var pack = packList[i];
            if (pack is HB419_tagSCObjHPRefresh hpRefreshPack)
            {
                return hpRefreshPack;
            }
            else if (pack is CustomHB426CombinePack)
            {
                break;
            }
        }
        return null;
    }
    public static List<HB422_tagMCTurnFightObjDead> FindDeadPack(List<GameNetPackBasic> packList)
    {
Main/System/Battle/Define/BattleDmgInfo.cs
@@ -16,12 +16,14 @@
{
    public string battleFieldGuid { get; private set; }
    public List<long> damageList { get; private set; }
    public BattleObject hurtObj { get; private set; }
    public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt { get; private set; }
    public BattleHurtParam battleHurtParam { get; private set; }
    public List<long> damageList { get { return battleHurtParam.damageList; } }
    public BattleObject hurtObj { get { return battleHurtParam.hurtObj; } }
    public SkillConfig skillConfig { get; private set; }
    public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt { get { return battleHurtParam.hurt; } }
    public SkillConfig skillConfig { get { return battleHurtParam.skillConfig; } }
    //  是否被格挡了
    public bool isBlocked = false;
@@ -30,14 +32,11 @@
    public List<BattleDmg> battleDamageList = new List<BattleDmg>();
    public BattleDmgInfo(string battleFieldGuid, List<long> damageList, BattleObject hurtObj, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, bool isLastHit)
    public BattleDmgInfo(string battleFieldGuid, BattleHurtParam battleHurtParam)
    {
        this.battleFieldGuid = battleFieldGuid;
        this.damageList = damageList;
        this.hurtObj = hurtObj;
        this.hurt = hurt;
        this.skillConfig = skillConfig;
        this.isLastHit = isLastHit;
        this.battleHurtParam = battleHurtParam;
        this.isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1;
        HandleDamageType();
        HandleAttackTypeAndDamage();
    }
@@ -62,10 +61,40 @@
        int rawAttackType = (int)hurt.AttackTypes;
        float blockRatio = GeneralDefine.blockRatio; // 格挡减伤率
        // 处理每一段伤害及其对应的反伤和吸血
        for (int i = 0; i < damageList.Count; i++)
        {
            long actualDamage = damageList[i];
            // ============ 1. 先处理当前段对应的反伤 ============
            if (battleHurtParam.reflectHpList != null && i < battleHurtParam.reflectHpList.Count)
            {
                long reflectHp = battleHurtParam.reflectHpList[i];
                if (reflectHp > 0)
                {
                    battleDamageList.Add(new BattleDmg
                    {
                        damage = reflectHp,
                        attackType = (int)DamageType.Reflect
                    });
                }
            }
            // ============ 2. 然后处理当前段对应的吸血 ============
            if (battleHurtParam.suckHpList != null && i < battleHurtParam.suckHpList.Count)
            {
                long suckHp = battleHurtParam.suckHpList[i];
                if (suckHp > 0)
                {
                    battleDamageList.Add(new BattleDmg
                    {
                        damage = suckHp,
                        attackType = (int)DamageType.SuckHP
                    });
                }
            }
            // ============ 3. 最后处理主要伤害 ============
            // 格挡处理
            if (isBlocked)
            {
@@ -82,21 +111,22 @@
                {
                    int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
                    battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = showAttackType });
                    continue;
                }
                // 普通伤害/治疗处理
                if (DamageNumConfig.Get(attackType) == null)
                else
                {
                    UnityEngine.Debug.LogError($"服务器给的伤害类型不对,强制转换为普通伤害/治疗, attackType: {attackType}");
                    if ((attackType & (int)DamageType.Damage) != 0)
                        attackType = (int)DamageType.Damage;
                    else if ((attackType & (int)DamageType.Recovery) != 0)
                        attackType = (int)DamageType.Recovery;
                    else
                        UnityEngine.Debug.LogError($"强制转换失败,该类型不是治疗也不是伤害 {attackType}");
                    // 普通伤害/治疗处理
                    if (DamageNumConfig.Get(attackType) == null)
                    {
                        UnityEngine.Debug.LogError($"服务器给的伤害类型不对,强制转换为普通伤害/治疗, attackType: {attackType}");
                        if ((attackType & (int)DamageType.Damage) != 0)
                            attackType = (int)DamageType.Damage;
                        else if ((attackType & (int)DamageType.Recovery) != 0)
                            attackType = (int)DamageType.Recovery;
                        else
                            UnityEngine.Debug.LogError($"强制转换失败,该类型不是治疗也不是伤害 {attackType}");
                    }
                    battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
                }
                battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
            }
            else
            {
@@ -107,21 +137,22 @@
                {
                    int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
                    battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = showAttackType });
                    continue;
                }
                // 普通伤害/治疗处理
                if (DamageNumConfig.Get(attackType) == null)
                else
                {
                    UnityEngine.Debug.LogError($"服务器给的伤害类型不对,强制转换为普通伤害/治疗, attackType: {attackType}");
                    if ((attackType & (int)DamageType.Damage) != 0)
                        attackType = (int)DamageType.Damage;
                    else if ((attackType & (int)DamageType.Recovery) != 0)
                        attackType = (int)DamageType.Recovery;
                    else
                        UnityEngine.Debug.LogError($"强制转换失败,该类型不是治疗也不是伤害 {attackType}");
                    // 普通伤害/治疗处理
                    if (DamageNumConfig.Get(attackType) == null)
                    {
                        UnityEngine.Debug.LogError($"服务器给的伤害类型不对,强制转换为普通伤害/治疗, attackType: {attackType}");
                        if ((attackType & (int)DamageType.Damage) != 0)
                            attackType = (int)DamageType.Damage;
                        else if ((attackType & (int)DamageType.Recovery) != 0)
                            attackType = (int)DamageType.Recovery;
                        else
                            UnityEngine.Debug.LogError($"强制转换失败,该类型不是治疗也不是伤害 {attackType}");
                    }
                    battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
                }
                battleDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
            }
        }
    }
@@ -146,4 +177,27 @@
        return skillConfig.HurtType / 10 == 1;
    }
}
public class BattleHurtParam
{
    public BattleObject casterObj;
    public BattleObject hurtObj;
    public List<long> damageList;
    public List<long> suckHpList;
    public List<long> reflectHpList;
    public long fromHp;
    public long toHp;
    public BattleDrops battleDrops;
    public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt;
    public int hitIndex;
    public HB422_tagMCTurnFightObjDead deadPack;
    public SkillConfig skillConfig;
}
Main/System/Battle/Motion/MotionBase.cs
@@ -23,7 +23,12 @@
    protected Spine.Skeleton skeleton;
    protected float defaultMixDuration = 0f;
    private Spine.TrackEntry currentTrack;
    private Dictionary<int, Spine.TrackEntry> activeSkillTracks = new Dictionary<int, Spine.TrackEntry>(); // 改为字典:trackIndex -> TrackEntry
    private Dictionary<int, Spine.TrackEntry> activeSkillTracks = new Dictionary<int, Spine.TrackEntry>();
    // 子技能轨道池管理(在Init中初始化,不要在这里初始化)
    private Queue<int> availableSubTracks;
    private Dictionary<SkillBase, int> subSkillTrackMap = new Dictionary<SkillBase, int>();
    private SkeletonIllusionShadow illusionShadow;
    private bool playingSkillAnim = false;
@@ -52,6 +57,11 @@
        if (animState != null)
            animState.Data.DefaultMix = defaultMixDuration;
        // 初始化子技能轨道池
        availableSubTracks = new Queue<int>();
        for (int i = 1; i <= 8; i++)
            availableSubTracks.Enqueue(i);
        PlayAnimation(MotionName.idle, true);
        SetupAnimationHandlers();
        
@@ -63,6 +73,8 @@
    {
        trackEntryCallbacks.Clear();
        activeSkillTracks.Clear();
        availableSubTracks?.Clear();
        subSkillTrackMap.Clear();
        if (animState != null)
        {
            animState.Complete -= OnAnimationComplete;
@@ -109,8 +121,8 @@
            return null;
        }
        // 子技能强制使用无动画模式,或者如果没有动画名称
        if (isSubSkill || string.IsNullOrEmpty(skillConfig.SkillMotionName))
        // 如果没有动画名称,使用无动画模式
        if (string.IsNullOrEmpty(skillConfig.SkillMotionName))
        {
            PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill);
            return null;
@@ -136,13 +148,41 @@
        int frameCount = activeFrames.Length;
        float recoveryFrame = skillConfig.RecoveryFrames;
        // 主技能用 track 0,子技能用 track 1
        int trackIndex = isSubSkill ? 1 : 0;
        // 轨道分配策略:主技能用 track 0,子技能从轨道池分配
        int trackIndex = 0;
        if (isSubSkill)
        {
            if (availableSubTracks != null && availableSubTracks.Count > 0)
            {
                trackIndex = availableSubTracks.Dequeue();
                subSkillTrackMap[skillBase] = trackIndex;
            }
            else
            {
                // 轨道池耗尽或未初始化,回退到无动画模式
                Debug.LogWarning($"子技能轨道池已满或未初始化,技能{skillConfig.SkillID}使用无动画模式");
                PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill);
                return null;
            }
        }
        Spine.TrackEntry skillTrack = null;
        
        if (hasAnim)
        {
            skillTrack = animState.SetAnimation(trackIndex, targetAnim, false);
            if (null == skillTrack)
            {
                Debug.LogError($"技能 {skillConfig.SkillID} 动画设置失败");
                // 如果是子技能且分配了轨道,需要回收
                if (isSubSkill && subSkillTrackMap.ContainsKey(skillBase))
                {
                    if (availableSubTracks != null)
                        availableSubTracks.Enqueue(subSkillTrackMap[skillBase]);
                    subSkillTrackMap.Remove(skillBase);
                }
                return null;
            }
            
            // 只有主技能才更新 currentTrack
            if (!isSubSkill)
@@ -175,6 +215,14 @@
                {
                    if (activeSkillTracks[trackIndex] == skillTrack)
                        activeSkillTracks.Remove(trackIndex);
                }
                // 回收子技能轨道
                if (isSubSkill && subSkillTrackMap.ContainsKey(skillBase))
                {
                    if (availableSubTracks != null)
                        availableSubTracks.Enqueue(subSkillTrackMap[skillBase]);
                    subSkillTrackMap.Remove(skillBase);
                }
                
                // 只有当没有其他活跃技能时才复位 playingSkillAnim
@@ -214,6 +262,15 @@
                    // 清理并确保状态复位
                    RemoveAction(frameHandler);
                    // 回收子技能轨道
                    if (isSubSkill && subSkillTrackMap.ContainsKey(skillBase))
                    {
                        if (availableSubTracks != null)
                            availableSubTracks.Enqueue(subSkillTrackMap[skillBase]);
                        subSkillTrackMap.Remove(skillBase);
                    }
                    if (activeSkillTracks.Count == 0)
                        playingSkillAnim = false;
                    return;
@@ -227,6 +284,15 @@
                    RemoveAction(frameHandler);
                    if (activeSkillTracks.ContainsKey(trackIndex))
                        activeSkillTracks.Remove(trackIndex);
                    // 回收子技能轨道
                    if (isSubSkill && subSkillTrackMap.ContainsKey(skillBase))
                    {
                        if (availableSubTracks != null)
                            availableSubTracks.Enqueue(subSkillTrackMap[skillBase]);
                        subSkillTrackMap.Remove(skillBase);
                    }
                    if (activeSkillTracks.Count == 0)
                        playingSkillAnim = false;
                    return;
@@ -303,6 +369,14 @@
                    {
                        if (activeSkillTracks[trackIndex] == skillTrack)
                            activeSkillTracks.Remove(trackIndex);
                    }
                    // 回收子技能轨道
                    if (isSubSkill && subSkillTrackMap.ContainsKey(skillBase))
                    {
                        if (availableSubTracks != null)
                            availableSubTracks.Enqueue(subSkillTrackMap[skillBase]);
                        subSkillTrackMap.Remove(skillBase);
                    }
                    // 只有当没有其他活跃技能时才复位 playingSkillAnim
@@ -436,6 +510,17 @@
        trackEntryCallbacks.Clear();
        runningActions.Clear();
        activeSkillTracks.Clear();
        // 重置子技能轨道池
        if (availableSubTracks == null)
            availableSubTracks = new Queue<int>();
        else
            availableSubTracks.Clear();
        subSkillTrackMap.Clear();
        for (int i = 1; i <= 8; i++)
            availableSubTracks.Enqueue(i);
        playingSkillAnim = false;
        PlayAnimation(MotionName.idle, true);
    }
Main/System/Battle/Skill/SkillBase.cs
@@ -339,6 +339,7 @@
    public void OnSkillStart()
    {
        HandleDead();
        skillEffect = SkillEffectFactory.CreateSkillEffect(caster, skillConfig, tagUseSkillAttack);
        skillEffect.Play(OnHitTargets);
        foreach (var subSkillPack in tagUseSkillAttack.subSkillList)
@@ -374,6 +375,7 @@
    // 技能后摇结束回调:通知技能效果处理后摇结束
    public virtual void OnFinalFrameEnd()
    {
        skillEffect?.OnFinalFrameEnd(); // 修复:添加空值检查
    }
@@ -419,6 +421,9 @@
    // 命中目标回调:处理所有被命中的目标
    protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
    {
        //  造成伤害前先处理血量刷新包
        HandleRefreshHP();
        foreach (var hurt in hitList)
        {
            BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
@@ -432,9 +437,10 @@
        }
    }
    // 处理单个目标被命中:应用伤害和施法者效果
    // 处理单个目标被命中:应用伤害和施法者效果
    protected virtual void OnHitEachTarget(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
    {
        // ============ 第一步:计算伤害分布 ============
        List<int> damageDivide = new List<int>();
        if (_hitIndex == 0 && skillConfig.DamageDivide.Length <= 0)
        {
@@ -453,19 +459,107 @@
            }
        }
        // 伤害分布计算和应用
        // 计算总伤害和分段伤害列表
        long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
        List<long> damageList = BattleUtility.DivideDamageToList(damageDivide.ToArray(), totalDamage);
        List<long> damageList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalDamage);
        // 获取临时数据并应用伤害
        // ============ 第二步:刷新实际血量 ============
        long fromHp = target.teamHero.curHp;
        // ============处理吸血跟反伤 ===============
        //  也要按每一击平均算 最后要补齐伤害
        long suckHp = hurt.SuckHP;
        long reflectHp = hurt.BounceHP;
        List<long> suckHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, suckHp);
        List<long> reflectHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, hurt.BounceHP);
        // long currentSuckHp = suckHp / tagUseSkillAttack.HurtCount;
        // 计算当前这一击的实际伤害(所有分段伤害之和)
        long currentHitDamage = 0;
        foreach (long dmg in damageList)
        {
            currentHitDamage += dmg;
        }
        long currentHitSuckHp = 0;
        foreach (long suck in suckHpList)
        {
            currentHitSuckHp += suck;
        }
        long currentHitReflectHp = 0;
        foreach (long reflect in reflectHpList)
        {
            currentHitReflectHp += reflect;
        }
        long toHp = Math.Max(0, fromHp - currentHitDamage + currentHitSuckHp - currentHitReflectHp);
        // 更新目标血量
        target.teamHero.curHp = toHp;
#if UNITY_EDITOR
        BattleDebug.LogError(
            (caster.Camp == BattleCamp.Red ? "【红方行动】" : "【蓝方行动】") + "\n" +
            $"攻击者: {caster.teamHero.name}\n" +
            $"目标: {target.teamHero.name}\n" +
            $"技能: {skillConfig.SkillName} (第{_hitIndex}击)\n" +
            $"伤害: {currentHitDamage} (总伤害: {totalDamage})\n" +
            $"吸血: {currentHitSuckHp}\n" +
            $"反伤: {currentHitReflectHp}\n" +
            $"血量变化: {fromHp} -> {toHp}"
        );
#endif
        bool isLastHit = _hitIndex >= skillConfig.DamageDivide.Length - 1;
        // ============ 第三步:获取临时数据(掉落、死亡等) ============
        int objID = (int)target.ObjID;
        tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
        tempDeadPackList.TryGetValue(objID, out HB422_tagMCTurnFightObjDead deadPack);
        target.Hurt(damageList, totalDamage, hurt, skillConfig, _hitIndex, battleDrops, deadPack);
        // 处理施法者相关效果
        caster.SuckHp(hurt.SuckHP, skillConfig);
        caster.HurtByReflect(hurt.BounceHP, skillConfig);
        //  参数打包
        BattleHurtParam hurtParam = new BattleHurtParam()
        {
            casterObj = caster,
            hurtObj = target,
            damageList = damageList,
            suckHpList = suckHpList,
            reflectHpList = reflectHpList,
            fromHp = fromHp,
            toHp = toHp,
            battleDrops = battleDrops,
            hurt = hurt,
            hitIndex = _hitIndex,
            deadPack = deadPack,
            skillConfig = skillConfig
        };
        // ============ 第四步:执行表现(飘字、动画等) ============
        target.Hurt(hurtParam);
    }
    // 处理HP刷新包(简化逻辑)
    private void HandleRefreshHP()
    {
        // 查找HP刷新包
        HB419_tagSCObjHPRefresh refreshPack = BattleUtility.FindObjHPRefreshPack(packList);
        if (refreshPack != null)
        {
            // 分发HP刷新包
            PackageRegedit.Distribute(refreshPack);
            packList.Remove(refreshPack);
        }
    }
    // 处理死亡相关逻辑:分配掉落和经验
@@ -583,8 +677,8 @@
                long assignExp = avgExp + (i < remain ? 1 : 0);
                var newPack = new HB405_tagMCAddExp
                {
                    Exp = (uint)(assignExp % 100000000),
                    ExpPoint = (uint)(assignExp / 100000000),
                    Exp = (uint)(assignExp % Constants.ExpPointValue),
                    ExpPoint = (uint)(assignExp / Constants.ExpPointValue),
                    Source = expPack.Source
                };
                expAssign[i].Add(newPack);
Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -150,11 +150,14 @@
    {
        KillTween(ref hpTween);
        
        float fromValue = (float)fromHp / (float)maxHp;
        float targetValue = (float)toHp / (float)maxHp;
        
        if (tween)
        {
            hpTween = sliderHp.DOValue(targetValue, 0.3f);
            // 关键修复:先设置起始值,再播放动画到目标值
            sliderHp.value = fromValue;  // ← 这行是关键!
            hpTween = sliderHp.DOValue(targetValue, 0.3f).SetAutoKill(false);
            battleObject.battleField.battleTweenMgr.OnPlayTween(hpTween);
        }
        else
@@ -170,11 +173,14 @@
    {
        KillTween(ref xpTween);
        
        float fromValue = (float)fromXp / (float)maxXp;
        float targetValue = (float)toXp / (float)maxXp;
        
        if (tween)
        {
            xpTween = sliderXp.DOValue(targetValue, 0.2f);
            // 同样的修复
            sliderXp.value = fromValue;  // ← 这行是关键!
            xpTween = sliderXp.DOValue(targetValue, 0.2f).SetAutoKill(false);
            battleObject.battleField.battleTweenMgr.OnPlayTween(xpTween);
        }
        else
Main/System/BattlePass.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7f66ce03cd8564847bcbc69378d900d9
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BattlePass/BattlePassManager.Week.cs
New file
@@ -0,0 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
//周战令
public partial class BattlePassManager : GameSystemManager<BattlePassManager>
{
    public const int WeekBattlePassType = 6;
    Redpoint redpoint = new Redpoint(MainRedDot.RedPoint_DailyKey, MainRedDot.RedPoint_WeekBPFuncKey);
    void UpdateWeekRedPoint()
    {
        redpoint.state = RedPointState.None;
        //购买,活跃
        battlePassDataDict.TryGetValue(WeekBattlePassType, out BattlePassData battlePassData);
        if (battlePassData == null) return;
        if (HasAnyAward(WeekBattlePassType, (int)battlePassData.value1))
        {
            redpoint.state = RedPointState.Simple;
        }
    }
}
Main/System/BattlePass/BattlePassManager.Week.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/System/BattlePass/BattlePassManager.Week.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: ed678a9060fddbf41adb9d9102d62514
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/BattlePass/BattlePassManager.cs
New file
@@ -0,0 +1,277 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
public partial class BattlePassManager : GameSystemManager<BattlePassManager>
{
    //战令类型:战令数据
    Dictionary<int, BattlePassData> battlePassDataDict = new Dictionary<int, BattlePassData>();
    public event Action<int> BattlePassDataUpdateEvent;
    Dictionary<int, int[]> buyZhanlingTypeDict = new Dictionary<int, int[]>();
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        ParseConfig();
    }
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
    }
    void OnBeforePlayerDataInitialize()
    {
        battlePassDataDict.Clear();
    }
    void ParseConfig()
    {
        var config = FuncConfigConfig.Get("Zhanling");
        buyZhanlingTypeDict = ConfigParse.ParseIntArrayDict(config.Numerical1);
    }
    public void UpdateBattlePassInfo(HB120_tagMCZhanlingInfo netPack)
    {
        if (!battlePassDataDict.ContainsKey(netPack.ZhanlingType))
        {
            battlePassDataDict[netPack.ZhanlingType] = new BattlePassData();
        }
        BattlePassData battlePassData = battlePassDataDict[netPack.ZhanlingType];
        battlePassData.isActivite = netPack.IsActivite;
        battlePassData.isActiviteH = netPack.IsActiviteH;
        battlePassData.allFinishTime = netPack.AllFinishTime;
        battlePassData.value1 = netPack.Value1;
        for (int i = 0; i < netPack.RewardCount; i++)
        {
            HB120_tagMCZhanlingInfo.tagMCZhanling reward = netPack.RewardList[i];
            if (!battlePassData.battlePassCellDict.ContainsKey((int)reward.NeedValue))
            {
                battlePassData.battlePassCellDict[(int)reward.NeedValue] = new BattlePassCell();
            }
            BattlePassCell battlePassCell = battlePassData.battlePassCellDict[(int)reward.NeedValue];
            battlePassCell.freeRewardState = reward.FreeRewardState;
            battlePassCell.zlRewardState = reward.ZLRewardState;
            battlePassCell.zlRewardStateH = reward.ZLRewardStateH;
        }
        UpdateRedpoint(netPack.ZhanlingType);
        BattlePassDataUpdateEvent?.Invoke(netPack.ZhanlingType);
    }
    void UpdateRedpoint(int type)
    {
        switch (type)
        {
            case WeekBattlePassType:
                {
                    UpdateWeekRedPoint();
                    break;
                }
        }
    }
    //是否有任何奖励可以领取
    public bool HasAnyAward(int type, int totalValue)
    {
        battlePassDataDict.TryGetValue(type, out BattlePassData battlePassData);
        if (battlePassData == null)
            return false;
        if (battlePassData.allFinishTime != 0)
            return false;
        var allZhanling = ZhanlingConfig.GetTypeToIDDict(type);
        var keys = allZhanling.Keys.ToList();
        keys.Sort();
        foreach (var needValue in keys)
        {
            if (totalValue < needValue)
            {
                return false;
            }
            if (battlePassData.battlePassCellDict.ContainsKey(needValue))
            {
                if (battlePassData.battlePassCellDict[needValue].freeRewardState == 0)
                {
                    return true;
                }
                else if (battlePassData.isActivite != 0 && battlePassData.battlePassCellDict[needValue].zlRewardState == 0)
                {
                    return true;
                }
                else if (battlePassData.isActiviteH != 0 && battlePassData.battlePassCellDict[needValue].zlRewardStateH == 0)
                {
                    return true;
                }
            }
        }
        return false;
    }
    /// <summary>
    /// 是否有某个奖励可以领取
    /// </summary>
    /// <param name="battlePassData"></param>
    /// <param name="totalValue"></param>
    /// <param name="needValue"></param>
    /// <param name="awardType">0 免费 1 普通 2 高级</param>
    /// <returns>0 未达标 1 可领取 2 已领取</returns>
    public int GetBPCellAwardState(BattlePassData battlePassData, int totalValue, int needValue, int awardType)
    {
        if (totalValue < needValue)
        {
            return 0;
        }
        if (battlePassData.battlePassCellDict.ContainsKey(needValue))
        {
            switch (awardType)
            {
                case 0:
                    {
                        return battlePassData.battlePassCellDict[needValue].freeRewardState == 0 ? 1 : 2;
                    }
                case 1:
                    {
                        if (battlePassData.isActivite != 0)
                        {
                            return battlePassData.battlePassCellDict[needValue].zlRewardState == 0 ? 1 : 2;
                        }
                        break;
                    }
                case 2:
                    {
                        if (battlePassData.isActiviteH != 0)
                        {
                            return battlePassData.battlePassCellDict[needValue].zlRewardStateH == 0 ? 1 : 2;
                        }
                        break;
                    }
            }
        }
        return 0;
    }
    public int GetCTGIDByType(int type)
    {
        if (buyZhanlingTypeDict.ContainsKey(type))
        {
            return buyZhanlingTypeDict[type][0];
        }
        return 0;
    }
    public BattlePassData GetBattlePassData(int type)
    {
        if (battlePassDataDict.ContainsKey(type))
        {
            return battlePassDataDict[type];
        }
        return null;
    }
    //发包 type 0-免费;1-普通战令;2-高级战令
    public void SendGetGift(int zhanLingType, int needValue, int type)
    {
        var pak = new CA504_tagCMPlayerGetReward();
        string dataExStr = (needValue * 10 + type).ToString();
        pak.RewardType = (byte)65;
        pak.DataEx = (uint)zhanLingType;
        pak.DataExStrLen = (byte)dataExStr.Length;
        pak.DataExStr = dataExStr;
        GameNetSystem.Instance.SendInfo(pak);
    }
    //一次性全领取
    public void GetAllAward(BattlePassData battlePassData, int zhanLingType, int totalValue)
    {
        //简单判断背包
        if (PackManager.Instance.GetEmptyGridCount(PackType.Item) <= 1)
        {
            SysNotifyMgr.Instance.ShowTip("GeRen_lhs_202580");
            return;
        }
        var ids = ZhanlingConfig.GetTypeToIDDict(zhanLingType).Values.ToList();
        ids.Sort();
        foreach (var id in ids)
        {
            var config = ZhanlingConfig.Get(id);
            if (config.NeedValue > totalValue)
            {
                break;
            }
            for (int i = 0; i < 3; i++)
            {
                var state = GetBPCellAwardState(battlePassData, totalValue, config.NeedValue, i);
                if (state == 1)
                {
                    SendGetGift(zhanLingType, config.NeedValue, i);
                }
            }
        }
    }
    public int JumpIndex(BattlePassData battlePassData, int zhanLingType, int totalValue)
    {
        var ids = ZhanlingConfig.GetTypeToIDDict(zhanLingType).Values.ToList();
        ids.Sort();
        int index = -1;
        foreach (var id in ids)
        {
            index++;
            var config = ZhanlingConfig.Get(id);
            if (config.NeedValue > totalValue)
            {
                return index - 1;
            }
            for (int i = 0; i < 3; i++)
            {
                var state = GetBPCellAwardState(battlePassData, totalValue, config.NeedValue, i);
                if (state == 1)
                {
                    return index;
                }
            }
        }
        return index;
    }
}
public class BattlePassCell
{
    public byte freeRewardState;        // 免费战令奖励是否已领取
    public byte zlRewardState;        // 普通战令奖励是否已领取
    public byte zlRewardStateH;        // 高级战令奖励是否已领取
}
public class BattlePassData
{
    public byte isActivite;    // 普通战令是否已激活
    public byte isActiviteH;    // 高级战令是否已激活
    public uint allFinishTime;    // 全部奖励领取完毕的时间戳,未完毕时该值为0,后端会在0点过天时检查可否重置,前端自行做倒计时表现即可
    public uint value1;    // 战令对应的自定义值,可选,如登录战令代表开始计算日期时间戳
    public Dictionary<int, BattlePassCell> battlePassCellDict = new Dictionary<int, BattlePassCell>();
}
Main/System/BattlePass/BattlePassManager.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/System/BattlePass/BattlePassManager.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 973e17d74c0fddf43b8085d369f35feb
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/DayMission/DayMissionBaseWin.cs
@@ -22,11 +22,12 @@
                break;
            case 1:
                //周奖励
                // currentSubUI = UIManager.Instance.OpenWindow<HeroCollectionWin>();
                currentSubUI = UIManager.Instance.OpenWindow<WeekBattlePassWin>();
                titleText.text = Language.Get("DayMission3");
                break;
            case 2:
                //主线任务(英雄之路)
                currentSubUI = UIManager.Instance.OpenWindow<DayMissionWin>();
                titleText.text = Language.Get("DayMission4");
                break;
            default:
Main/System/DayMission/DayMissionManager.cs
@@ -20,7 +20,7 @@
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        GlobalTimeEvent.Instance.MS100Event += OnMSEvent;
        ParseConfig();
    }
@@ -28,7 +28,7 @@
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
        GlobalTimeEvent.Instance.MS100Event -= OnMSEvent;
    }
    void OnBeforePlayerDataInitialize()
@@ -39,7 +39,7 @@
        taskProcessDict.Clear();
    }
    void OnSecondEvent()
    void OnMSEvent()
    {
        if (isRefreshDayMission)
        {
Main/System/DayMission/WeekBattlePassCell.cs
New file
@@ -0,0 +1,88 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class WeekBattlePassCell : CellView
{
    [SerializeField] ItemCell baseAward;
    [SerializeField] Transform baseGotRect;
    [SerializeField] Transform baseCanGetAwardRect;
    [SerializeField] Transform upProcssBGRect;
    [SerializeField] Transform upProcessRect;
    [SerializeField] Transform downProcssBGRect;
    [SerializeField] Transform downProcessRect;
    [SerializeField] Text valueText;
    [SerializeField] Image valueBGImg;
    [SerializeField] ItemCell[] betterAwards;
    [SerializeField] Transform[] betterGotRects;
    [SerializeField] Transform[] betterCanGetAwardRects;
    [SerializeField] Transform[] betterLockRects;
    [SerializeField] Transform mask;
    public void Display(int id, BattlePassData battlePassData)
    {
        var config = ZhanlingConfig.Get(id);
        int freeItemID = config.FreeRewardItemList[0][0];
        baseAward.Init(new ItemCellModel(freeItemID, false, config.FreeRewardItemList[0][1]));
        var baseAwardState = BattlePassManager.Instance.GetBPCellAwardState(battlePassData, (int)battlePassData.value1, config.NeedValue, 0);
        baseAward.button.AddListener(() =>
        {
            GetAward(battlePassData, baseAwardState, freeItemID);
        });
        baseGotRect.SetActive(baseAwardState == 2);
        baseCanGetAwardRect.SetActive(baseAwardState == 1);
        mask.SetActive(baseAwardState == 0);
        var ids = ZhanlingConfig.GetTypeToIDDict(BattlePassManager.WeekBattlePassType).Values.ToList();
        ids.Sort();
        upProcssBGRect.SetActive(ids[0] != id);
        upProcessRect.SetActive(baseAwardState != 0);
        downProcssBGRect.SetActive(ids[ids.Count - 1] != id);
        var nextConfig = ZhanlingConfig.Get(id + 1);
        if (nextConfig != null)
        {
            downProcessRect.SetActive((int)battlePassData.value1 >= nextConfig.NeedValue);
        }
        else
        {
            downProcessRect.SetActive(false);
        }
        valueText.text = config.NeedValue.ToString();
        valueBGImg.SetOrgSprite(baseAwardState == 0 ? "DayMission_img_99" : "DayMission_img_100", "DayMission");
        var betterAwardState = BattlePassManager.Instance.GetBPCellAwardState(battlePassData, (int)battlePassData.value1, config.NeedValue, 1);
        for (int i = 0; i < betterAwards.Length; i++)
        {
            int itemID = config.ZLRewardItemList[i][0];
            betterAwards[i].Init(new ItemCellModel(itemID, false, config.ZLRewardItemList[i][1]));
            betterAwards[i].button.AddListener(() =>
            {
                GetAward(battlePassData, betterAwardState, itemID);
            });
            betterGotRects[i].SetActive(betterAwardState == 2);
            betterCanGetAwardRects[i].SetActive(betterAwardState == 1);
            betterLockRects[i].SetActive(battlePassData.isActivite == 0);
        }
    }
    void GetAward(BattlePassData battlePassData, int awardState, int itemID)
    {
        if (awardState != 1)
        {
            ItemTipUtility.Show(itemID);
            return;
        }
        BattlePassManager.Instance.GetAllAward(battlePassData, BattlePassManager.WeekBattlePassType, (int)battlePassData.value1);
    }
}
Main/System/DayMission/WeekBattlePassCell.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/System/DayMission/WeekBattlePassCell.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: 22ee6f5381c87b443a607448c096a1af
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/DayMission/WeekBattlePassWin.cs
New file
@@ -0,0 +1,116 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
//周战令
public class WeekBattlePassWin : UIBase
{
    [SerializeField] Text totalActivityText;
    [SerializeField] Text timeText;
    [SerializeField] ScrollerController scroller;
    [SerializeField] Transform lockRect;
    [SerializeField] Button buyBtn;
    [SerializeField] Text buyText;
    BattlePassData battlePassData;
    protected override void InitComponent()
    {
        buyBtn.AddListener(() =>
        {
            RechargeManager.Instance.CTG(BattlePassManager.Instance.GetCTGIDByType(BattlePassManager.WeekBattlePassType));
        });
    }
    protected override void OnPreOpen()
    {
        battlePassData = BattlePassManager.Instance.GetBattlePassData(BattlePassManager.WeekBattlePassType);
        if (battlePassData == null) return;
        scroller.OnRefreshCell += OnRefreshCell;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        BattlePassManager.Instance.BattlePassDataUpdateEvent += BattlePassDataUpdateEvent;
        CreateScroller();
        Display();
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
        BattlePassManager.Instance.BattlePassDataUpdateEvent -= BattlePassDataUpdateEvent;
    }
    void OnSecondEvent()
    {
        //按开服天 7天一个循环
        var day = 7 - (TimeUtility.OpenDay % 7) - 1;
        if (day == 0)
        {
            timeText.text = Language.Get("GoldRush29") + TimeUtility.SecondsToShortDHMS((int)(TimeUtility.GetTodayEndTime() - TimeUtility.ServerNow).TotalSeconds);
        }
        else
        {
            timeText.text = Language.Get("GoldRush29") + day + Language.Get("L1074");
        }
    }
    void BattlePassDataUpdateEvent(int type)
    {
        if (type == BattlePassManager.WeekBattlePassType)
        {
            Display();
        }
    }
    void Display()
    {
        totalActivityText.text = battlePassData.value1.ToString();
        lockRect.SetActive(battlePassData.isActivite == 0);
        scroller.m_Scorller.RefreshActiveCellViews();
        if (battlePassData.isActivite == 0)
        {
            var ctgID = BattlePassManager.Instance.GetCTGIDByType(BattlePassManager.WeekBattlePassType);
            RechargeManager.Instance.TryGetOrderInfo(ctgID, out var orderInfoConfig);
            buyText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
            buyBtn.SetInteractable(true);
        }
        else
        {
            buyText.text = Language.Get("L1133");
            buyBtn.SetInteractable(false);
        }
    }
    void CreateScroller()
    {
        scroller.Refresh();
        var values = ZhanlingConfig.GetTypeToIDDict(BattlePassManager.WeekBattlePassType).Values.ToList();
        values.Sort();
        for (int i = 0; i < values.Count; i++)
        {
            scroller.AddCell(ScrollerDataType.Header, values[i]);
        }
        scroller.Restart();
        scroller.JumpIndex(BattlePassManager.Instance.JumpIndex(battlePassData, BattlePassManager.WeekBattlePassType, (int)battlePassData.value1));
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as WeekBattlePassCell;
        _cell.Display(cell.index, battlePassData);
    }
}
Main/System/DayMission/WeekBattlePassWin.cs.meta
copy from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta copy to Main/System/DayMission/WeekBattlePassWin.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/HA0_Sys/HA005_tagOpenServerDay.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a6484a8278af59643850fd9225f7338d
guid: e87e9af324b150d4fb0c3f0732593f2b
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/Equip/FloorItemCell.cs
@@ -1,4 +1,5 @@
using DG.Tweening;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using System;
using System.Linq;
using UnityEngine;
@@ -21,8 +22,9 @@
    /// </summary>
    /// <param name="index">掉落背包索引</param>
    /// <param name="isAnimate">是否播放掉落动画</param>
    public void Display(int index, bool isAnimate, RectTransform rect)
    public async UniTask Display(int index, bool isAnimate, RectTransform rect)
    {
        await UniTask.Delay(300);
        itemIndex = index;
        float duration = 0.5f / AutoFightModel.Instance.fightSpeed; //掉落时间
        var item = PackManager.Instance.GetItemByIndex(PackType.DropItem, index);
@@ -31,6 +33,7 @@
            this.transform.SetActive(false);
            return;
        }
        this.transform.SetActive(true);
        itemImage.SetOrgSprite(item.config.IconKey);
        int effectID = EquipModel.Instance.equipUIEffectLights[Math.Min(item.config.ItemColor, EquipModel.Instance.equipUIEffectLights.Length) - 1];
        if (effectID == 0)
Main/System/Equip/ItemsOnFloor.cs
@@ -115,8 +115,6 @@
                continue;
            }
            item.SetActive(true);
            item.Display(i, isAnimate, rect == null ? defaultDropRect : rect);
        }
    }
Main/System/HappyXB/HeroCallResultWin.cs
@@ -71,7 +71,14 @@
            HeroUIManager.Instance.selectCallIndex = 1;
            HappyXBModel.Instance.SendXBManyQuest((int)HeroUIManager.Instance.selectCallType);
        });
        showNextlhOrCloseBtn.AddListener(RefreshLihui);
        showNextlhOrCloseBtn.AddListener(()=>
        {
            if (Time.time - lastShowLHTime < 0.5f)
            {
                return;
            }
            RefreshLihui();
        });
    }
@@ -285,8 +292,10 @@
        }
    }
    float lastShowLHTime = 0;   //上次显示立绘的时间 设置点击间隔
    void RefreshLihui()
    {
        lastShowLHTime = Time.time;
        //汇总品质传说及以上的立绘
        int heroID = 0;
        if (showLHHeroIDList.Count > 0)
Main/System/HeroUI/HeroTrainWin.cs
@@ -130,6 +130,10 @@
        deleteBtn.AddListener(DeleteHero);
        awakeBtn.AddListener(() =>
        {
            if (!FuncOpen.Instance.IsFuncOpen(38, true))
            {
                return;
            }
            HeroUIManager.Instance.selectAwakeHeroGuid = guid;
            UIManager.Instance.OpenWindow<HeroAwakeWin>();
        });
Main/System/InternalAffairs/AffairBaseWin.cs
@@ -76,6 +76,17 @@
        fullGoldRush.SetActive(GoldRushManager.Instance.GetFinishGoldRushCount() >= GoldRushManager.Instance.warehouseMaxCnt);
        RefreshGoldRushMoney();
        autoText.text = Language.Get(GoldRushManager.Instance.isAutoWorking ? "GoldRush34" : "GoldRush24");
        if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.GoldRush))
        {
            autoBtn.SetActive(true);
            goldRushItemBtn.SetActive(true);
        }
        else
        {
            autoBtn.SetActive(false);
            goldRushItemBtn.SetActive(false);
        }
    }
Main/System/InternalAffairs/GoldRushLeader.cs
@@ -164,8 +164,9 @@
        {
            leaderWord.SetActive(true);
            leaderWord.Play();
            leaderText.text = Language.Get(!pathPosEvent.m_IsRandom ? pathPosEvent.m_Text1 :
            leaderText.text = Language.Get(!pathPosEvent.m_IsRandom ? pathPosEvent.m_Text1 :
                pathPosEvent.m_Text1 + UnityEngine.Random.Range((int)pathPosEvent.m_Value1, (int)pathPosEvent.m_Value2 + 1));
            ForceRefreshLayout();
        }
        else if (pathPosEvent.m_PosEvent == PosEvent.TargetWord)
        {
@@ -211,6 +212,13 @@
    }
    /// <summary>
    /// 强制刷新Layout,解决嵌套Layout和ContentSizeFitter的重叠问题
    /// </summary>
    async UniTask ForceRefreshLayout()
    {
        await UniTask.DelayFrame(2);
        LayoutRebuilder.ForceRebuildLayoutImmediate(leaderWord.GetComponent<RectTransform>());
    }
}
Main/System/InternalAffairs/GoldRushTentCell.cs
@@ -4,6 +4,7 @@
using DG.Tweening;
using System.Linq;
using System;
using Cysharp.Threading.Tasks;
//工人是固定的跟随模式,监工是随机分配的,场上的监工数量会比实际更多
//分配监工
@@ -421,6 +422,7 @@
            wordArr[index].SetActive(true);
            wordArr[index].Play();
            textArr[index].text = Language.Get(content);
            ForceRefreshLayout();
        }
        else if (posEvent == PosEvent.TargetAction)
        {
@@ -432,7 +434,17 @@
    }
    /// <summary>
    /// 强制刷新Layout,解决嵌套Layout和ContentSizeFitter的重叠问题
    /// </summary>
    async UniTask ForceRefreshLayout()
    {
        await UniTask.DelayFrame(2);
        foreach (var word in wordArr)
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(word.GetComponent<RectTransform>());
        }
    }
    void AssignLeader(int addCount)
Main/System/NewBieGuidance/NewBieGuideScriptableObject.cs
@@ -22,7 +22,7 @@
    //  如果后续想做:不想要蒙版 又想要点击引导的位置才有效 则可以是在勾选clickAnyWhereComplete情况下,改变mask的alpha值即可配合提示
    public bool clickAnyWhereComplete = false;  
    public bool clickCompleteNoMask = false;    //非强制引导,任意点击关闭,勾选此项会隐藏蒙版,且点击其他区域不会响应按钮事件
    public int delayTime = 0;  //展示时间(毫秒),期间不可点击
    // 引导的文本的箭头位置
    public enum ArrowPosition
Main/System/NewBieGuidance/NewBieWin.cs
@@ -45,12 +45,13 @@
    GuideConfig config;
    NewBieGuideScriptableObject stepConfig; //引导步骤
    float lastShowTime;
    #region Built-in
    protected override void InitComponent()
    {
        m_ClickTalk.AddListener(()=>
        m_ClickTalk.AddListener(() =>
        {
            ReportStepOver();
        });
@@ -110,6 +111,7 @@
            CloseWindow();
            return;
        }
        lastShowTime = Time.time;
        if (config.WinName != "EquipExchangeWin" && UIManager.Instance.IsOpened<EquipExchangeWin>())
        {
@@ -284,10 +286,8 @@
        }
        m_ClickEffect.effectId = stepConfig.effect; //如果需要点击特效也增加偏移量
        m_ClickEffect.SetActive(true);
        m_ClickEffect.Play();
        m_ClickEffect.transform.position = m_ClickTarget.position;
        m_ClickEffect.transform.localPosition = m_ClickEffect.transform.localPosition + (Vector3)stepConfig.usherPosition;
        m_ClickEffect.SetActive(false);
        DelayShowClickEffect().Forget();
        if (stepConfig.clickCompleteNoMask)
        {
@@ -304,6 +304,16 @@
        }
    }
    async UniTask DelayShowClickEffect()
    {
        await UniTask.Delay(stepConfig.delayTime);
        m_ClickEffect.SetActive(true);
        m_ClickEffect.Play();
        m_ClickEffect.transform.position = m_ClickTarget.position;
        m_ClickEffect.transform.localPosition = m_ClickEffect.transform.localPosition + (Vector3)stepConfig.usherPosition;
    }
    void LateUpdate()
    {
        if (Input.GetMouseButtonUp(0))
@@ -318,6 +328,10 @@
            }
            if (stepConfig.clickAnyWhereComplete || m_NewBieMask.mask.IsInCirleArea(Input.mousePosition, CameraManager.uiCamera))
            {
                if (stepConfig.delayTime > 0 && (Time.time - lastShowTime)*1000 < stepConfig.delayTime)
                {
                    return;
                }
                if (m_ClickTarget == null)
                {
                    Debug.LogError("引导 m_ClickTarget == null; step = " + NewBieCenter.Instance.guideStep);
Main/Utility/GlobalTimeEvent.cs
@@ -5,8 +5,8 @@
public class GlobalTimeEvent : SingletonMonobehaviour<GlobalTimeEvent>
{
    public event Action MS100Event;
    public event Action secondEvent;
    public event Action fiveSecondEvent;
    public event Action minuteEvent;
@@ -16,6 +16,7 @@
    public event Action hourEvent;
    public event Action halfMinuteEvent;
    float msBuf = 0f;
    int secondBuf = -1;
    int fiveSecondBuf = -1;
    int minuteBuf = -1;
@@ -32,6 +33,17 @@
    private void Update()
    {
        var ms = Time.time;
        if (ms - msBuf >= 0.1f)
        {
            if (MS100Event != null)
            {
                MS100Event();
            }
            msBuf = ms;
        }
        var second = DateTime.Now.Second;
        if (second != secondBuf)
        {
Main/Utility/TimeUtility.cs
@@ -194,7 +194,7 @@
    }
    public static event Action OnServerOpenDayRefresh;
    public static void OnRefreshServerOpenDay(HA005_tagOpenServerDay package)
    public static void OnRefreshServerOpenDay(HA103_tagMCOpenServerDay package)
    {
        {
            OpenDay = package.Day;