lcy
5 天以前 00efb8f79701e48d3e441f220b1ad6c4c395a8d8
432 【主界面】自动挂机优化-客户端 自动战斗部分
8个文件已添加
8个文件已修改
596 ■■■■■ 已修改文件
Main/Main.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/OperationAgent/AutoModeOperationAgent.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/EquipModel.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightModel.cs 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightWin.cs 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordCell.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordItem.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordItem.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordManager.cs 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordManager.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordWin.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/EquipRecordWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HomeWin.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Setting/QuickSetting.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Settlement/BattleSettlementManager.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Main.cs
@@ -100,6 +100,7 @@
        managers.Add(GubaoManager.Instance);
        managers.Add(WarlordPavilionManager.Instance);
        managers.Add(ViewNPCManager.Instance);
        managers.Add(EquipRecordManager.Instance);
        foreach (var manager in managers)
        {
            manager.Init();
Main/System/Battle/BattleField/OperationAgent/AutoModeOperationAgent.cs
@@ -10,6 +10,7 @@
    }
    float lastTime;
    float lastSendTime;
    public override void Run()
    {
        //最低1秒
@@ -18,6 +19,33 @@
        lastTime = Time.time;
        if (AutoFightModel.Instance.isPause)
            return;
        // 自动挑战boss
        if (AutoFightModel.Instance.isAutoChallengeBoss)
        {
            if (!MainLevelManager.Instance.CanChallengeBoss())
            {
                DoNext();
                return;
            }
            //上次挑战boss失败了,再次尝试要等CD
            if (AutoFightModel.Instance.nowChallengeCount > 0 &&
                Time.time - AutoFightModel.Instance.lastChallengeTime < AutoFightModel.Instance.maxTryChallengeCD)
            {
                DoNext();
                return;
            }
            //已经开始boss战斗
            BattleField battleField = BattleManager.Instance.GetActiveBattleFieldByName(BattleConst.StoryBossBattleField);
            if (battleField != null)
                return;
            if (Time.time - lastSendTime < 1.0f)
                return;
            lastSendTime = Time.time;
            Debug.Log($"开始挑战boss ServerNow{TimeUtility.ServerNow}");
            FightBoss();
            return;
        }
        DoNext();
    }
@@ -25,4 +53,11 @@
    {
        storyBattleField.RequestFight();
    }
    void FightBoss()
    {
        BattleManager.Instance.SendTurnFight(2);
        BattleManager.Instance.storyBattleField.CleanBattle();
        AutoFightModel.Instance.isPause = true;
    }
}
Main/System/Equip/EquipModel.cs
@@ -10,7 +10,7 @@
{
    public const int TotleEquip = 12;  //装备栏大小
    public bool waitEquipOPPack = false;    // 穿戴装备的操作 不含分解
    public float waitEquipOPTime = 0;
    public float waitEquipOPTime = 0;
    public event Action<bool, int> OnEquipOPResultAction;    //是否换上了新装备且分解了 装备索引
    public event Action<BattleDrops> OnItemDropEvent;
@@ -304,6 +304,17 @@
            waitEquipOPTime = Time.time;
            Debug.LogWarning("穿戴装备,向服务器请求");
        }
        //在记录销毁或替换前的装备
        if ((opType == 1 || opType == 2) && !itemIndexList.IsNullOrEmpty())
        {
            foreach (var index in itemIndexList)
            {
                var oldEquip = PackManager.Instance.GetItemByIndex(PackType.Equip, index);
                EquipRecordManager.Instance.oldEquipDic[index] = oldEquip;
            }
        }
        GameNetSystem.Instance.SendInfo(pack);
    }
@@ -388,7 +399,7 @@
            return false;
        }
        selectFloorEquip = GetSelectFloorEquip();
        if (selectFloorEquip == null)
        {
@@ -501,7 +512,7 @@
    }
    public ItemModel GetEquip(int index)
    {
    {
        return PackManager.Instance.GetItemByIndex(PackType.Equip, index);
    }
}
Main/System/Main/AutoFightModel.cs
@@ -1,7 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using LitJson;
using UnityEngine;
@@ -82,7 +79,65 @@
        }
    }
    //自动挑战首领
    public bool isAutoChallengeBoss
    {
        get
        {
            return QuickSetting.Instance.GetQuickSettingBool(QuickSettingType.AutoFight_ChallengeBoss, 0);
        }
        set
        {
            QuickSetting.Instance.SetQuickSetting(QuickSettingType.AutoFight_ChallengeBoss, value);
        }
    }
    //当前战败了x次
    private int m_NowChallengeCount = 0;
    public float lastChallengeTime = 0;
    public int nowChallengeCount
    {
        get { return m_NowChallengeCount; }
        set
        {
            m_NowChallengeCount = value;
            lastChallengeTime = value == 0 ? 0 : Time.time;
            Debug.Log($"当前在主线Boss战败了{m_NowChallengeCount}次,上次战败时间是{lastChallengeTime}");
            if (m_NowChallengeCount >= tryChallengeCount)
            {
                isAutoAttackSet = false;
                isAutoAttack = false;
                SaveAutoFightSetting();
            }
        }
    }
    //自动挑战首领,战败x次停止
    public int tryChallengeCount
    {
        get
        {
            int value = QuickSetting.Instance.GetQuickSettingValue<int>(QuickSettingType.AutoFight_TryChallengeCount, 0);
            return Math.Min(Math.Max(value, 1), maxCost);
        }
        set
        {
            QuickSetting.Instance.SetQuickSetting(QuickSettingType.AutoFight_TryChallengeCount, value);
        }
    }
    //自动完成任务
    public bool isAutoFinishTask
    {
        get
        {
            return QuickSetting.Instance.GetQuickSettingBool(QuickSettingType.AutoFight_AutoFinishTask, 0);
        }
        set
        {
            QuickSetting.Instance.SetQuickSetting(QuickSettingType.AutoFight_AutoFinishTask, value);
        }
    }
    public event Action ChangeAutoEvent;
    public int maxSpeed = 3; //最高速度 索引
@@ -90,10 +145,16 @@
    public int[] autoCostWithBlessLV; //自动战斗消耗倍数关联祝福等级
    public int speed2UnlockMissionID;
    public int openAutoChallengeBossMissionID;//自动挑战首领解锁的任务ID(需完成)
    public int maxTryChallengeCount;//自动挑战首领最大战败次数(下拉列表的最大值)
    public int maxTryChallengeCD;
    public int openAutoFinishMissionID;//自动完成任务解锁的任务ID(需完成)
    public override void Init()
    {
        ParseConfig();
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerInit;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
        BattleManager.Instance.onBattleFieldCreate += OnCreateBattleField;
        EventBroadcast.Instance.AddListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        BlessLVManager.Instance.OnBlessLVUpdateEvent += UpdateRedpint;
@@ -106,6 +167,7 @@
    {
        BattleManager.Instance.onBattleFieldCreate -= OnCreateBattleField;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerInit;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
        EventBroadcast.Instance.RemoveListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        BlessLVManager.Instance.OnBlessLVUpdateEvent -= UpdateRedpint;
        TaskManager.Instance.OnTaskUpdate -= OnTaskUpdate;
@@ -119,6 +181,11 @@
        autoCostWithBlessLV = JsonMapper.ToObject<int[]>(config.Numerical1);
        speed2UnlockMissionID = int.Parse(config.Numerical2);
        maxCost = autoCostWithBlessLV.Length;
        config = FuncConfigConfig.Get("AutoGuaji1");
        openAutoChallengeBossMissionID = int.Parse(config.Numerical1);
        maxTryChallengeCount = int.Parse(config.Numerical2);
        maxTryChallengeCD = int.Parse(config.Numerical3);
        openAutoFinishMissionID = int.Parse(config.Numerical4);
    }
@@ -126,6 +193,11 @@
    {
        fightingHeroSkinID = 0;
        heroGuid = "";
    }
    private void OnBeforePlayerDataInitializeEventOnRelogin()
    {
        nowChallengeCount = 0;
    }
    public void SaveAutoFightSetting()
@@ -160,7 +232,7 @@
            return true;
        long showFightPower = FightPowerManager.Instance.GetFightPowerChange(item);
        if (showFightPower < 0)
        {
            EquipModel.Instance.SendEquipOP(new ushort[] { (ushort)item.gridIndex }, 1);
@@ -178,6 +250,7 @@
    }
    #region 主线战斗(自动和手动)
    public void StartFight()
Main/System/Main/AutoFightWin.cs
@@ -1,6 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
@@ -13,8 +11,8 @@
    [SerializeField] Button autoSaveBtn;
    [SerializeField] Button changeCostBtn;
    [SerializeField] Text costText;
    [SerializeField] Image costArrow;
    [SerializeField] Text costText;
    [SerializeField] Text costTip;
    [SerializeField] ScrollerController costScroll;
@@ -25,14 +23,34 @@
    [SerializeField] Toggle betterEquipToggle;
    [SerializeField] Toggle autoChallengeBossToggle;
    [SerializeField] Button tryChallengeBtn;
    [SerializeField] Text tryChallengeText;
    [SerializeField] Image tryChallengeArrow;
    [SerializeField] ScrollerController tryChallengeScroll;
    [SerializeField] Button tryChallengeTipBtn;
    [SerializeField] Toggle autoFinishTaskToggle;
    [SerializeField] Button autoFinishTaskTipBtn;
    bool isOpenCostScroll = false;
    bool isOpenSpeedScroll = false;
    bool isOpenTryChallengeScroll = false;
    protected override void InitComponent()
    {
        autoStartBtn.AddListener(OnClickAutoStart);
        autoStopBtn.AddListener(OnClickAutoStop);
        autoSaveBtn.AddListener(OnClickAutoStart);
        tryChallengeTipBtn.AddListener(() =>
        {
            DislayTip("AutoFight15", tryChallengeTipBtn.transform.position);
        });
        autoFinishTaskTipBtn.AddListener(() =>
        {
            DislayTip("AutoFight16",autoFinishTaskTipBtn.transform.position);
        });
        changeCostBtn.AddListener(() =>
        {
@@ -41,6 +59,7 @@
            costArrow.transform.localRotation = Quaternion.Euler(0, 0, isOpenCostScroll ? 180 : 0);
            AutoFightModel.Instance.ClickCostRed();
        });
        changeSpeedBtn.AddListener(() =>
        {
            isOpenSpeedScroll = !isOpenSpeedScroll;
@@ -49,9 +68,38 @@
            AutoFightModel.Instance.ClickSpeedRed();
        });
        tryChallengeBtn.AddListener(() =>
        {
            isOpenTryChallengeScroll = !isOpenTryChallengeScroll;
            tryChallengeScroll.SetActive(isOpenTryChallengeScroll);
            tryChallengeArrow.transform.localRotation = Quaternion.Euler(0, 0, isOpenTryChallengeScroll ? 180 : 0);
            AutoFightModel.Instance.ClickSpeedRed();
        });
        betterEquipToggle.AddListener((bool value) =>
        {
            betterEquipToggle.isOn = value;
        });
        autoChallengeBossToggle.AddListener((bool value) =>
        {
            if (!IsOpenTryChallenge(out int needtaskCount))
            {
                SysNotifyMgr.Instance.ShowTip("autofight2", needtaskCount);
                autoChallengeBossToggle.SetIsOnWithoutNotify(false);
                return;
            }
            autoChallengeBossToggle.isOn = value;
        });
        autoFinishTaskToggle.AddListener((bool value) =>
        {
            if (!IsOpenAutoFinishTask(out int needtaskCount))
            {
                SysNotifyMgr.Instance.ShowTip("autofight2", needtaskCount);
                autoFinishTaskToggle.SetIsOnWithoutNotify(false);
                return;
            }
            autoFinishTaskToggle.isOn = value;
        });
        costScroll.GetComponent<ClickScreenOtherSpace>().AddListener(() =>
@@ -65,12 +113,19 @@
            isOpenSpeedScroll = false;
            speedArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        });
        tryChallengeScroll.GetComponent<ClickScreenOtherSpace>().AddListener(() =>
        {
            isOpenTryChallengeScroll = false;
            tryChallengeArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        });
    }
    protected override void OnPreOpen()
    {
        costScroll.OnRefreshCell += OnRefreshCostCell;
        speedScroll.OnRefreshCell += OnRefreshSpeedCell;
        tryChallengeScroll.OnRefreshCell += OnRefreshTryChallengeCell;
        Display();
    }
@@ -78,14 +133,36 @@
    {
        costScroll.OnRefreshCell -= OnRefreshCostCell;
        speedScroll.OnRefreshCell -= OnRefreshSpeedCell;
        tryChallengeScroll.OnRefreshCell -= OnRefreshTryChallengeCell;
    }
    bool IsOpenTryChallenge(out int needtaskCount)
    {
        needtaskCount = TaskManager.Instance.GetNeedFinishTaskCount(AutoFightModel.Instance.openAutoChallengeBossMissionID);
        return needtaskCount <= 0;
    }
    bool IsOpenAutoFinishTask(out int needtaskCount)
    {
        needtaskCount = TaskManager.Instance.GetNeedFinishTaskCount(AutoFightModel.Instance.openAutoChallengeBossMissionID);
        return needtaskCount <= 0;
    }
    void DislayTip(string key, Vector3 worldPos)
    {
        SmallTipWin.showText = Language.Get(key);
        SmallTipWin.worldPos = worldPos;
        SmallTipWin.isDownShow = false;
        UIManager.Instance.OpenWindow<SmallTipWin>();
    }
    void Display()
    {
        costText.text = AutoFightModel.Instance.fightCost.ToString();
        speedText.text = AutoFightModel.Instance.fightSpeed.ToString();
        tryChallengeText.text = AutoFightModel.Instance.tryChallengeCount.ToString();
        betterEquipToggle.isOn = AutoFightModel.Instance.isStopFightByBetterEquip;
        autoChallengeBossToggle.isOn = AutoFightModel.Instance.isAutoChallengeBoss;
        autoFinishTaskToggle.isOn = AutoFightModel.Instance.isAutoFinishTask;
        costTip.text = Language.Get("AutoFight2", ItemConfig.Get(GeneralDefine.MoneyDisplayModel[41]).ItemName, AutoFightModel.Instance.fightCost);
        if (AutoFightModel.Instance.isAutoAttackSet)
@@ -98,15 +175,16 @@
            usingAutoObj.SetActive(false);
            autoStartBtn.SetActive(true);
        }
        costScroll.SetActive(false);
        speedScroll.SetActive(false);
        tryChallengeScroll.SetActive(false);
        costArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        speedArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        tryChallengeArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
        CreateCostScroll();
        CreateSpeedScroll();
        CreateTryChallengeScroll();
    }
@@ -123,7 +201,7 @@
            costScroll.JumpIndex(2);
        }
    }
    void CreateSpeedScroll()
    {
        speedScroll.Refresh();
@@ -134,6 +212,15 @@
        speedScroll.Restart();
    }
    void CreateTryChallengeScroll()
    {
        tryChallengeScroll.Refresh();
        for (int i = 0; i < AutoFightModel.Instance.maxTryChallengeCount; i++)
        {
            tryChallengeScroll.AddCell(ScrollerDataType.Header, i + 1);
        }
        tryChallengeScroll.Restart();
    }
    void OnRefreshCostCell(ScrollerDataType type, CellView cell)
    {
@@ -157,9 +244,9 @@
        var cntText = cell.GetComponentInChildren<Text>();
        if (AutoFightModel.Instance.autoCostWithBlessLV[cell.index - 1] <= BlessLVManager.Instance.m_TreeLV)
        {
        {
            cntText.text = UIHelper.AppendColor(TextColType.LightWhite, cell.index.ToString());
        }
        else
@@ -175,7 +262,7 @@
        var needtaskCount = TaskManager.Instance.GetNeedFinishTaskCount(AutoFightModel.Instance.speed2UnlockMissionID);
        bool isbuy = InvestModel.Instance.IsActiveFightSpeed(3);
        bool isActiveSpeed2 = needtaskCount <= 0 || isbuy;
        btn.AddListener(() =>
        {
            if (cell.index == 2)
@@ -198,7 +285,7 @@
            speedScroll.SetActive(false);
            speedArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
            speedText.text = cell.index.ToString();
        });
        });
        var cntText = cell.GetComponentInChildren<Text>();
        if (cell.index == 2)
@@ -215,12 +302,51 @@
        }
    }
    void OnRefreshTryChallengeCell(ScrollerDataType type, CellView cell)
    {
        bool isOpen = IsOpenTryChallenge(out int needtaskCount);
        bool isbuy = InvestModel.Instance.IsInvested(InvestModel.monthCardType);
        var btn = cell.GetComponent<Button>();
        btn.AddListener(() =>
        {
            if (cell.index != 1)
            {
                if (!isOpen)
                {
                    SysNotifyMgr.Instance.ShowTip("autofight2", needtaskCount);
                    return;
                }
                if (!isbuy)
                {
                    SysNotifyMgr.Instance.ShowTip("autofight3");
                    return;
                }
            }
            isOpenTryChallengeScroll = false;
            tryChallengeScroll.SetActive(false);
            tryChallengeArrow.transform.localRotation = Quaternion.Euler(0, 0, 0);
            tryChallengeText.text = cell.index.ToString();
        });
        var cntText = cell.GetComponentInChildren<Text>();
        if (cell.index != 1)
        {
            cntText.text = UIHelper.AppendColor(!isOpen || !isbuy ? TextColType.Gray : TextColType.LightWhite, cell.index.ToString());
        }
        else
        {
            cntText.text = cell.index.ToString();
        }
    }
    void OnClickAutoStart()
    {
        AutoFightModel.Instance.isAutoAttackSet = true;
        AutoFightModel.Instance.fightCost = int.Parse(costText.text);
        AutoFightModel.Instance.fightSpeed = int.Parse(speedText.text);
        AutoFightModel.Instance.isStopFightByBetterEquip = betterEquipToggle.isOn;
        AutoFightModel.Instance.isAutoChallengeBoss = autoChallengeBossToggle.isOn;
        AutoFightModel.Instance.nowChallengeCount = 0;
        AutoFightModel.Instance.tryChallengeCount = int.Parse(tryChallengeText.text);
        AutoFightModel.Instance.isAutoFinishTask = autoFinishTaskToggle.isOn;
        AutoFightModel.Instance.SaveAutoFightSetting();
        CloseWindow();
        SysNotifyMgr.Instance.ShowTip("autofight1");
@@ -238,6 +364,9 @@
                    AutoFightModel.Instance.fightCost = int.Parse(costText.text);
                    AutoFightModel.Instance.fightSpeed = int.Parse(speedText.text);
                    AutoFightModel.Instance.isStopFightByBetterEquip = betterEquipToggle.isOn;
                    AutoFightModel.Instance.isAutoChallengeBoss = autoChallengeBossToggle.isOn;
                    AutoFightModel.Instance.tryChallengeCount = int.Parse(tryChallengeText.text);
                    AutoFightModel.Instance.isAutoFinishTask = autoFinishTaskToggle.isOn;
                    AutoFightModel.Instance.SaveAutoFightSetting();
                    CloseWindow();
                }
Main/System/Main/EquipRecordCell.cs
New file
@@ -0,0 +1,13 @@
using UnityEngine;
public class EquipRecordCell : MonoBehaviour
{
    [SerializeField] EquipRecordItem fromEquip;
    [SerializeField] EquipRecordItem toEquip;
    [SerializeField] ImageEx imgWear;
    [SerializeField] ImageEx imgDecompose;
    public void Display(int index)
    {
    }
}
Main/System/Main/EquipRecordCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 046355c8bdca2a54884b68bcd0ccc112
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Main/EquipRecordItem.cs
New file
@@ -0,0 +1,16 @@
using UnityEngine;
public class EquipRecordItem : MonoBehaviour
{
    [SerializeField] ImageEx imgQuality;
    [SerializeField] ImageEx imgEquip;
    [SerializeField] TextEx txtName;
    [SerializeField] TextEx txtQualityName;
    [SerializeField] OutlineEx itemNameOutline;
    [SerializeField] OutlineEx qualityNameOutline;
    [SerializeField] TextEx txtLV;
    public void Display(EquipRecordManager.EquipDetail detail)
    {
    }
}
Main/System/Main/EquipRecordItem.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01bd7c1ab16c45046a13f1394fec26ec
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Main/EquipRecordManager.cs
New file
@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using LitJson;
using UnityEngine;
public class EquipRecordManager : GameSystemManager<EquipRecordManager>
{
    private List<EquipRecordData> recordList = new List<EquipRecordData>();
    public Dictionary<int, ItemModel> oldEquipDic = new Dictionary<int, ItemModel>();
    /// <summary>
    /// 调试用:遍历输出所有装备记录的详细信息(单条Log)
    /// </summary>
    public void DebugLogAllRecords()
    {
        var sb = new System.Text.StringBuilder();
        sb.AppendLine($"=== 装备记录总数: {recordList.Count} | 旧装备字典条目数: {oldEquipDic.Count} ===");
        for (int i = 0; i < recordList.Count; i++)
        {
            var record = recordList[i];
            sb.AppendLine($"--- 记录 {i + 1} ---");
            sb.AppendLine($"记录ID: {record.recordId} | 时间: {TimeStampToDateTime(record.timestamp)} | 类型: {record.recordType}");
            // 新装备详情
            if (record.newEquip != null)
            {
                sb.AppendLine($"[新装备] ID:{record.newEquip.itemId} | 名称:{record.newEquip.itemName} | 强化:{record.newEquip.level} | 评分:{record.newEquip.score} | 部位:{record.newEquip.equipPlace} | 战力:{record.newEquip.fightPower} | GUID:{record.newEquip.guid}");
            }
            else
            {
                sb.AppendLine($"[新装备] 无数据");
            }
            // 旧装备详情
            if (record.oldEquip != null)
            {
                sb.AppendLine($"[旧装备] ID:{record.oldEquip.itemId} | 名称:{record.oldEquip.itemName} | 强化:{record.oldEquip.level} | 评分:{record.oldEquip.score} | 部位:{record.oldEquip.equipPlace} | 战力:{record.oldEquip.fightPower} | GUID:{record.oldEquip.guid}");
            }
            else
            {
                sb.AppendLine($"[旧装备] 无数据");
            }
            sb.AppendLine(); // 空行分隔
        }
        // 旧装备字典
        sb.AppendLine("=== 旧装备字典详情 ===");
        foreach (var kvp in oldEquipDic)
        {
            sb.AppendLine($"Key:{kvp.Key} | Value:ItemModel(itemId={kvp.Value?.itemId}, guid={kvp.Value?.guid})");
        }
        UnityEngine.Debug.Log(sb.ToString());
    }
    /// <summary>
    /// 时间戳转日期时间
    /// </summary>
    private DateTime TimeStampToDateTime(long timestamp)
    {
        return DateTimeOffset.FromUnixTimeSeconds(timestamp).ToLocalTime().DateTime;
    }
    private int maxCnt;
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
        // 监听装备操作结果
        EquipModel.Instance.OnEquipOPResultAction += OnEquipOPResult;
        var config = FuncConfigConfig.Get("AutoGuaji1");
        maxCnt = int.Parse(config.Numerical5);
    }
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
        EquipModel.Instance.OnEquipOPResultAction -= OnEquipOPResult;
    }
    private void OnBeforePlayerDataInitializeEventOnRelogin()
    {
    }
    private void OnPlayerLoginOk()
    {
        LoadRecords();
    }
    string Key { get { return $"EquipRecordData_{PlayerDatas.Instance.PlayerId}"; } }
    private void SaveRecords()
    {
        // 持久化存储
        var json = JsonMapper.ToJson(recordList);
        LocalSave.SetString(Key, json);
    }
    private void LoadRecords()
    {
        var json = LocalSave.GetString(Key);
        if (!string.IsNullOrEmpty(json))
        {
            recordList = JsonMapper.ToObject<List<EquipRecordData>>(json);
        }
    }
    /// <summary>
    /// 装备操作结果回调 - 记录装备变化
    /// </summary>
    /// <param name="isDone">是否成功更换</param>
    /// <param name="equipIndex">装备栏索引</param>
    private void OnEquipOPResult(bool isDone, int equipIndex)
    {
        if (equipIndex < 0) return;
        // 获取新装备和旧装备信息
        var newEquip = PackManager.Instance.GetItemByIndex(PackType.Equip, equipIndex);
        if (newEquip == null) return;
        // 获取被替换的装备(需要从其他地方记录)
        // 这里需要配合 EquipModel 的 OnEquipResult 记录被替换的装备
        // ...
    }
    /// <summary>
    /// 获取装备详情
    /// </summary>
    private EquipDetail GetEquipDetail(ItemModel item)
    {
        if (item == null) return null;
        var detail = new EquipDetail
        {
            itemId = item.itemId,
            level = item.GetUseDataFirstValue(22),
            equipPlace = item.config.EquipPlace,
            guid = item.guid,
        };
        return detail;
    }
    // 装备记录数据类型
    public class EquipRecordData
    {
        public string recordId;              // 记录唯一ID
        public long timestamp;               // 时间戳
        public RecordType recordType;        // 记录类型
        public EquipDetail newEquip;         // 新装备详情
        public EquipDetail oldEquip;         // 旧装备详情
    }
    public class EquipDetail
    {
        public int itemId;                   // 物品配置ID
        public string itemName;              // 物品名称
        public int level;                    // 强化等级
        public int score;                    // 装备评分
        public int equipPlace;               // 装备部位
        public long fightPower;              // 战力
        public string guid;                  // 装备唯一ID
    }
    public enum RecordType
    {
        Equip = 0,        // 装备
        Decompose = 1     // 分解
    }
}
Main/System/Main/EquipRecordManager.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cd3bf4ecc67bfbc4c9e1fffe527e1b04
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Main/EquipRecordWin.cs
New file
@@ -0,0 +1,33 @@
using UnityEngine;
public class EquipRecordWin : UIBase
{
    [SerializeField] ScrollerController scroller;
    protected override void OnPreOpen()
    {
        scroller.OnRefreshCell += OnRefreshCell;
        CreateScroller();
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
    }
    private void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell.GetComponent<EquipRecordCell>();
        _cell?.Display(cell.index);
    }
    private void CreateScroller()
    {
        scroller.Refresh();
        for (int i = 0; i < 20; i++)
        {
            scroller.AddCell(ScrollerDataType.Header, i);
        }
        scroller.Restart();
    }
}
Main/System/Main/EquipRecordWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01cb6a0b7572e0642929fb24575d0c6d
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Main/HomeWin.cs
@@ -588,6 +588,14 @@
            }
            awardIcon.SetItemSprite(taskConfig.AwardItemList[0][0]);
            awardCnt.text = taskConfig.AwardItemList[0][1].ToString();
            if (AutoFightModel.Instance.isAutoFinishTask)
            {
                if (TaskManager.Instance.GetMainTaskState() != 2)
                {
                    return;
                }
                OnClickTaskButton();
            }
        }
    }
Main/System/Setting/QuickSetting.cs
@@ -1,5 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System;
@@ -22,6 +21,9 @@
        quickSettingDic.Add(QuickSettingType.BattleSpeed, new QuickSettingRange(QuickSettingType.BattleSpeed, 14, 1));
        quickSettingDic.Add(QuickSettingType.HeroCountLock, new QuickSettingRange(QuickSettingType.HeroCountLock, 15, 2));
        quickSettingDic.Add(QuickSettingType.CreateRole, new QuickSettingRange(QuickSettingType.CreateRole, 17, 1));
        quickSettingDic.Add(QuickSettingType.AutoFight_ChallengeBoss, new QuickSettingRange(QuickSettingType.AutoFight_ChallengeBoss, 18, 1));
        quickSettingDic.Add(QuickSettingType.AutoFight_TryChallengeCount, new QuickSettingRange(QuickSettingType.AutoFight_TryChallengeCount, 19, 1));
        quickSettingDic.Add(QuickSettingType.AutoFight_AutoFinishTask, new QuickSettingRange(QuickSettingType.AutoFight_AutoFinishTask, 20, 1));
        setting = new string(UCharacter, 100);
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerDataInitializeEvent;
@@ -170,6 +172,9 @@
    BattleSpeed,    //战斗速度索引  非主线部分
    HeroCountLock,  //上阵人数条件锁定
    CreateRole, //创建角色成功
    AutoFight_ChallengeBoss,   //自动挑战首领
    AutoFight_TryChallengeCount,    //自动挑战首领,战败x次停止
    AutoFight_AutoFinishTask,   //自动完成任务
}
public class QuickSettingRange
Main/System/Settlement/BattleSettlementManager.cs
@@ -150,6 +150,12 @@
        if (_data.ContainsKey("winFaction"))
        {
            var result = (int)_data["winFaction"];
            if (battleName == BattleConst.StoryBossBattleField)
            {
                AutoFightModel.Instance.nowChallengeCount += result != 1 ? 1 : 0;
            }
            if (battleName == activeBattleName)
            {
                //自己场景结算