hch
2025-12-31 4debfee66e8d8aabd179e2f8a61c7ca5ce62af3d
Main/System/Equip/EquipModel.cs
@@ -3,35 +3,79 @@
using UnityEngine;
using System;
using LitJson;
using UnityEngine.UI;
public class EquipModel : GameSystemManager<EquipModel>
{
    public const int TotleEquip = 12;  //装备栏大小
    public bool waitEquipOPPack = false;    // 穿戴装备的操作 不含分解
    public float waitEquipOPTime = 0;
    public event Action<bool, int> OnEquipOPResultAction;    //是否换上了新装备且分解了 装备索引
    public event Action<BattleDrops> OnItemDropEvent;
    //用于飘动逻辑
    // public Dictionary<int, EquipOnFloorInfo> equipFloorInfo = new Dictionary<int, EquipOnFloorInfo>(); //真实背包的索引,对应地板装备的信息
    public void OnPlayerLoginOk()
    {
    public int[] equipUIEffectLights;  //装备掉落特效
    public float[] dropEffectScales;    //掉装备的动画缩放
    public Dictionary<int, int> newEquipIDToGuideID = new Dictionary<int, int>();  //装备掉落id,引导的id
    public int[] equipUIEffects;  //装备TIP面板特效
    public int[] equipUIGirdEffects;  //装备格子特效
    public ItemModel selectFloorEquip; //选中的地板装备
    public int lastShowEquipIndex = -1;  //上一次界面显示装备的索引,拾取后物品消失需记录下做表现
    public Queue<string> waitEquipOP = new Queue<string>();    //等待操作的装备,需要和UI交互确认 不含分解
    }
    public List<int> lastDropIndexs = new List<int>(); //上一次掉落物品索引
    int lastAttackHeroID = 0;
    public override void Init()
    {
        DTCA814_tagMCMakeItemAnswer.MakeItemAnswerEvent += OnEquipResult;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerDataInitialize;
        EventBroadcast.Instance.AddListener<string, BattleDrops, Action>(EventName.BATTLE_DROP_ITEMS, OnDropEvent);
        EventBroadcast.Instance.AddListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        EventBroadcast.Instance.AddListener<string>(EventName.RECORDPLAYER_END, RecordPlayerEnd);
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        ParseConfig();
    }
    public override void Release()
    {
        DTCA814_tagMCMakeItemAnswer.MakeItemAnswerEvent -= OnEquipResult;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerDataInitialize;
        EventBroadcast.Instance.RemoveListener<string, BattleDrops, Action>(EventName.BATTLE_DROP_ITEMS, OnDropEvent);
        EventBroadcast.Instance.RemoveListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
        EventBroadcast.Instance.RemoveListener<string>(EventName.RECORDPLAYER_END, RecordPlayerEnd);
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
    }
    public Dictionary<int, int> EquipLevelFuncID = new Dictionary<int, int>();
    public void OnAfterPlayerDataInitialize()
    void ParseConfig()
    {
        var config = FuncConfigConfig.Get("DropItem");
        equipUIEffectLights = JsonMapper.ToObject<int[]>(config.Numerical1);
        dropEffectScales = JsonMapper.ToObject<float[]>(config.Numerical2);
        newEquipIDToGuideID = ConfigParse.ParseIntDict(config.Numerical3);
        config = FuncConfigConfig.Get("EquipTip");
        equipUIEffects = JsonMapper.ToObject<int[]>(config.Numerical1);
    }
    void BeforePlayerDataInitialize()
    {
        if (UIManager.Instance.IsOpened<EquipExchangeWin>())
        {
            //先关闭,后续再处理掉落
            UIManager.Instance.CloseWindow<EquipExchangeWin>();
        }
        selectFloorEquip = null;
        waitEquipOP.Clear();
        lastShowEquipIndex = -1;
        lastDropIndexs.Clear();
        waitEquipOPPack = false;
    }
    public static int GetItemServerEquipPlace(int itemId)
@@ -42,34 +86,424 @@
            return -1;
        }
        var serverEquipPlace = -1;
        switch ((RoleEquipType)config.EquipPlace)
        if (config.EquipPlace > 0 && config.EquipPlace < 13)
        {
            case RoleEquipType.Weapon:
            case RoleEquipType.Weapon2:
            case RoleEquipType.Hat:
            case RoleEquipType.Clothes:
            case RoleEquipType.Belt:
            case RoleEquipType.Trousers:
            case RoleEquipType.Shoes:
            case RoleEquipType.Neck:
            case RoleEquipType.FairyCan1:
            case RoleEquipType.FairyCan2:
            case RoleEquipType.Glove:
            case RoleEquipType.Jade:
                serverEquipPlace = EquipSet.ClientPlaceToServerPlace(new Int2(config.LV, config.EquipPlace));
                break;
            case RoleEquipType.Wing:
            case RoleEquipType.Guard:
            case RoleEquipType.PeerlessWeapon1:
            case RoleEquipType.PeerlessWeapon2:
                serverEquipPlace = EquipSet.ClientPlaceToServerPlace(new Int2(0, config.EquipPlace));
                break;
            return config.EquipPlace - 1;
        }
        return serverEquipPlace;
        return -1;
    }
    //表现掉落和拾取分离开,先掉落等本武将回合完全结束再拾取
    void OnDropEvent(string guid, BattleDrops drops, Action action)
    {
        if (!string.IsNullOrEmpty(guid))
            return;
        // lastDropIndexs = drops.dropItemPackIndex;
        // Debug.Log("-掉落装备 " + lastDropIndexs.Count + " 个" + JsonMapper.ToJson(lastDropIndexs));
        NotifyItemDrop(drops);
        action?.Invoke();
    }
    //拾取时机为下一武将(含敌我)攻击 或者 本轮结算(MainFightRequest 前)
    void OnSkillCast(string guid, SkillConfig skillConfig, TeamHero teamHero)
    {
        bool checkDrop = false;
        if (!string.IsNullOrEmpty(guid))
            return;
        //防范回收报错
        if (teamHero == null)
            checkDrop = true;
        //只通知玩家武将的战斗
        else if (teamHero.NPCID != 0)
            checkDrop = true;
        else if (teamHero.heroId != lastAttackHeroID)
        {
            lastAttackHeroID = teamHero.heroId;
            checkDrop = true;
        }
        if (checkDrop)
        {
            // CalcAllFloorItems();
        }
    }
    void RecordPlayerEnd(string guid)
    {
        if (!string.IsNullOrEmpty(guid))
            return;
        CalcAllFloorItems();
    }
    //掉落通知
    public void NotifyItemDrop(BattleDrops drops)//(List<int> indexs, RectTransform rect)
    {
        // 界面不显示则立即处理
        // if (!UIManager.Instance.IsOpened<HomeWin>())
        // {
        //     for (int i = 0; i < indexs.Count; i++)
        //     {
        //         CalcFloorEquip(indexs[i]);
        //     }
        // }
        // else
        // {
        //     OnItemDropEvent?.Invoke(indexs, rect);
        // }
        OnItemDropEvent?.Invoke(drops);
    }
    public void CalcFloorEquip(int itemIndex)
    {
        if (itemIndex == -1)
        {
            Debug.Log("CalcFloorEquip 无效的物品索引");
            return;
        }
        var item = PackManager.Instance.GetItemByIndex(PackType.DropItem, itemIndex);
        if (item == null)
        {
            Debug.Log("CalcFloorEquip 无效的物品索引");
            return;
        }
        //非自动模式下,筛选装备打开装备操作界面
        if (IsEquip(item))
        {
            OpenEquipExchangeWin(item);
        }
        else
        {
            SendEquipOP(new ushort[] { (ushort)itemIndex }, 0);
        }
    }
    bool needMoreDrop = false; //由于掉落挤压导致,满掉落掉落背包的时候处理后再主动请求掉落
    //处理所有掉落的物品
    public void CalcAllFloorItems()
    {
        int cnt = PackManager.Instance.GetSinglePack(PackType.DropItem).GetItems().Count;
        if (cnt == 0)
        {
            Debug.Log("CalcAllFloorItems 没有掉落物品");
            return;
        }
        needMoreDrop = cnt == 20;
        //构建所有物品
        foreach (var item in PackManager.Instance.GetSinglePack(PackType.DropItem).GetItems())
        {
            CalcFloorEquip(item.gridIndex);
        }
        if (needMoreDrop)
        {
            SendEquipOP(null, 3);
            needMoreDrop = false;
        }
    }
    void OnSecondEvent()
    {
        if (waitEquipOPPack && Time.time - waitEquipOPTime > 2)
        {
            //避免装备卡死无法继续主线
            waitEquipOPPack = false;
        }
    }
    private void OnEquipResult(HA814_tagMCMakeItemAnswer info)
    {
        if (info.MakeType != (int)MakeType.EquipOP)
            return;
        if (info.MakeValue == 0)
            return;
        if (info.MakeValue == 2)
        {
            waitEquipOPPack = false;
            Debug.LogWarning("穿戴装备,服务器响应解除等待状态");
        }
        bool isDone = false;    // 换上新装备且分解了旧装备
        //选中的地板装备进行处理,替换还是找下一件,检查OnEquipOPResultAction
        if (selectFloorEquip != null)
        {
            Debug.Log("OnEquipResult selectFloorEquip ID:" + selectFloorEquip.itemId);
            if (PackManager.Instance.GetItemByIndex(PackType.DropItem, selectFloorEquip.gridIndex) == null)
            {
                selectFloorEquip = GetSelectFloorEquip();    //删除已选择的装备
                if (info.MakeValue == 2)
                    isDone = true;
            }
        }
        else
        {
            selectFloorEquip = GetSelectFloorEquip();
            if (info.MakeValue == 2)
                isDone = true;
        }
        if (selectFloorEquip == null)
        {
            if (UIManager.Instance.IsOpened<EquipExchangeWin>())
            {
                UIManager.Instance.CloseWindow<EquipExchangeWin>();
            }
        }
        else
        {
            // if (!UIManager.Instance.IsOpened<EquipExchangeWin>())
            // {
            //     UIManager.Instance.OpenWindow<EquipExchangeWin>();
            // }
            //继续处理下一件装备 重新判断
            CalcFloorEquip(selectFloorEquip.gridIndex);
        }
        OnEquipOPResultAction?.Invoke(isDone, lastShowEquipIndex);
    }
    /// <summary>
    /// 装备操作, // 0 - 拾取非装备物品;1 - 分解;2 - 穿戴/替换
    /// </summary>
    /// <param name="itemIndexList"></param>
    /// <param name="opType"></param>
    /// <param name="autoDecompose"></param>
    public void SendEquipOP(ushort[] itemIndexList, byte opType, bool autoDecompose = false)
    {
        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
        {
            return;
        }
        if (opType == 2 && waitEquipOPPack) return;
        // NoteFloorEquip(itemIndexList, opType);
        var pack = new CB415_tagCSMainDropItemOP();
        if (itemIndexList != null)
        {
            pack.Count = (byte)itemIndexList.Length;
            pack.IndexList = itemIndexList;
        }
        pack.OPType = opType;
        pack.OPValue = (byte)(autoDecompose ? 1 : 0); // 替换后是否自动分解原装备:0否1是
        if (opType == 2)
        {
            waitEquipOPPack = true;
            waitEquipOPTime = Time.time;
            Debug.LogWarning("穿戴装备,向服务器请求");
        }
        GameNetSystem.Instance.SendInfo(pack);
    }
    /// <summary>
    /// equipFloorInfo记录地板道具的最新一次信息,用于替换和分解装备的表现
    /// </summary>
    /// <param name="itemIndexList">地板道具索引</param>
    /// <param name="opType"></param>
    // public void NoteFloorEquip(ushort[] itemIndexList, int opType)
    // {
    //     equipFloorInfo.Clear();
    //     foreach (var girdIndex in itemIndexList)
    //     {
    //         var equip = PackManager.Instance.GetItemByIndex(PackType.DropItem, girdIndex);
    //         if (equip == null) continue;
    //         equipFloorInfo[girdIndex] = new EquipOnFloorInfo()
    //         {
    //             equipID = equip.itemId,
    //             posX = floorItemCellArr[girdIndex].transform.position.x,
    //             posY = floorItemCellArr[girdIndex].transform.position.y,
    //             opType = opType
    //         };
    //     }
    // }
    public class EquipOnFloorInfo
    {
        public int equipID; //道具或者装备,道具分解对应不同货币,装备固定货币
        public float posX;  //全局坐标 表现再转成local
        public float posY;
        public int opType;  // 0 - 拾取非装备物品;1 - 分解;2 - 穿戴/替换;
    }
    // public EquipOnFloorInfo FindExchangeEquipInfo()
    // {
    //     foreach (var info in equipFloorInfo)
    //     {
    //         if (info.Value.opType == 2)
    //             return info.Value;
    //     }
    //     return new EquipOnFloorInfo();
    // }
    public bool OpenEquipExchangeWin(ItemModel equip)
    {
        if (equip == null)
        {
            return false;
        }
        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
        {
            return false;
        }
        // if (!IsEquip(equip))
        //     return false;
        if (AutoFightModel.Instance.TryAutoFightDoEquip(equip))
        {
            //自动战力对比, 条件不满足的分解
            return false;
        }
        // 好几件装备需要处理的情况存起来
        if (!waitEquipOP.Contains(equip.guid))
        {
            //检测时机频繁,导致重复推送,需要检测过滤,对应Dequeue 也做一次检测
            waitEquipOP.Enqueue(equip.guid);
        }
        //未回复装备操作结果,否则会显示旧装备
        if (waitEquipOPPack)
        {
            return false;
        }
        if (UIManager.Instance.IsOpened<EquipExchangeWin>())
        {
            return false;
        }
        selectFloorEquip = GetSelectFloorEquip();
        if (selectFloorEquip == null)
        {
            return false;
        }
        UIManager.Instance.OpenWindow<EquipExchangeWin>();
        return true;
    }
    ItemModel GetSelectFloorEquip()
    {
        if (waitEquipOP.Count == 0)
            return null;
        // 新手引导中,不允许切换装备界面
        if (NewBieCenter.Instance.inGuiding)
        {
            Debug.LogWarning("GetSelectFloorEquip: 新手引导中,不允许切换装备界面");
            return null;
        }
        string activeBattleName = BattleManager.Instance.GetActiveBattleName();
        if (activeBattleName != "" && activeBattleName != "StoryBattleField")
        {
            Debug.LogWarning("非主线战斗不弹窗");
            return null;
        }
        var item = PackManager.Instance.GetItemByGuid(waitEquipOP.Dequeue());
        if (item != null && item.packType == PackType.DropItem)
        {
            return item;
        }
        // Debug.LogError("GetSelectFloorEquip: 没有找到可选装备, 该装备已经转移");
        return null;
    }
    //等级
    public int GetEquipLV(ItemModel equip)
    {
        if (equip == null)
        {
            return 0;
        }
        return equip.GetUseDataFirstValue(22);
    }
    //基础属性ID列表
    public List<int> GetEquipBaseAttrs(ItemModel equip)
    {
        if (equip == null)
        {
            return new List<int>();
        }
        return equip.GetUseData(21);
    }
    //基础属性值列表
    public List<int> GetEquipBaseValues(ItemModel equip)
    {
        if (equip == null)
        {
            return new List<int>();
        }
        return equip.GetUseData(23);
    }
    //战斗属性ID列表
    public List<int> GetEquipFightAttrs(ItemModel equip)
    {
        if (equip == null)
        {
            return new List<int>();
        }
        return equip.GetUseData(17);
    }
    //战斗属性值列表
    public List<int> GetEquipFightValues(ItemModel equip)
    {
        if (equip == null)
        {
            return new List<int>();
        }
        return equip.GetUseData(19);
    }
    //得到装备位对应的部位名称
    public string GetEquipPlaceName(int place)
    {
        return Language.Get(string.Concat("equipPlace", place));
    }
    //是否装备
    public bool IsEquip(ItemModel item)
    {
        return item.config.EquipPlace != 0;
    }
    public bool IsEquip(int itemID)
    {
        return ItemConfig.Get(itemID).EquipPlace != 0;
    }
    public ItemModel GetEquip(int index)
    {
        return PackManager.Instance.GetItemByIndex(PackType.Equip, index);
    }
}