yyl
2 天以前 cb0d3169ed35fea4716f55ca6596ca88fb6884f0
Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
13个文件已修改
33个文件已添加
2490 ■■■■■ 已修改文件
Main/Config/Configs/BeautyConfig.cs 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautyConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautyQualityLVConfig.cs 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautyQualityLVConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautySkinConfig.cs 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautySkinConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/TravelEventConfig.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/TravelEventConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/TravelSceneryConfig.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/TravelSceneryConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/BeautyQualityLVConfig.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/BeautyQualityLVConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/BeautySkinConfig.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/BeautySkinConfig.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/PlayerPropertyConfig.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CB4_FightDefine/CB415_tagCSMainDropItemOP.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB0_Event/DTCB040_tagSCTravelInfo.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB130_tagSCBeautyInfo.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Main.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Arena/ArenaManager.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMBaseWin.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMBaseWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMCell.cs 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMLineCell.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMLineCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMListWin.cs 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMListWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMManager.Travel.cs 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMManager.Travel.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMManager.cs 555 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMManager.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMShowWin.cs 443 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMShowWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMTravelCell.cs 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMTravelCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMTravelWin.cs 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BeautyMM/BeautyMMTravelWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/BoneField/AdsManager.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Equip/EquipModel.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/InternalAffairs/AffairFuncCell.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/PackManager.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/MainRedDot.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/EnumHelper.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/BeautyConfig.cs
New file
@@ -0,0 +1,116 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年12月23日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class BeautyConfig : ConfigBase<int, BeautyConfig>
{
    static BeautyConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int BeautyID;
    public string Name;
    public int BeautyQuality;
    public int UnlockWay;
    public int UnlockValue;
    public int UnlockNeedCnt;
    public int ExclusiveItemID;
    public int[] TalentAttrIDList;
    public int[] TalentAttrValueList;
    public int[] TalentPerLVAddList;
    public int EffType;
    public int EffTypeValue;
    public int EffValue;
    public int EffPerLVAdd;
    public string Desc;
    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 BeautyID);
            Name = tables[1];
            int.TryParse(tables[2],out BeautyQuality);
            int.TryParse(tables[3],out UnlockWay);
            int.TryParse(tables[4],out UnlockValue);
            int.TryParse(tables[5],out UnlockNeedCnt);
            int.TryParse(tables[6],out ExclusiveItemID);
            if (tables[7].Contains("["))
            {
                TalentAttrIDList = JsonMapper.ToObject<int[]>(tables[7]);
            }
            else
            {
                string[] TalentAttrIDListStringArray = tables[7].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                TalentAttrIDList = new int[TalentAttrIDListStringArray.Length];
                for (int i=0;i<TalentAttrIDListStringArray.Length;i++)
                {
                     int.TryParse(TalentAttrIDListStringArray[i],out TalentAttrIDList[i]);
                }
            }
            if (tables[8].Contains("["))
            {
                TalentAttrValueList = JsonMapper.ToObject<int[]>(tables[8]);
            }
            else
            {
                string[] TalentAttrValueListStringArray = tables[8].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                TalentAttrValueList = new int[TalentAttrValueListStringArray.Length];
                for (int i=0;i<TalentAttrValueListStringArray.Length;i++)
                {
                     int.TryParse(TalentAttrValueListStringArray[i],out TalentAttrValueList[i]);
                }
            }
            if (tables[9].Contains("["))
            {
                TalentPerLVAddList = JsonMapper.ToObject<int[]>(tables[9]);
            }
            else
            {
                string[] TalentPerLVAddListStringArray = tables[9].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                TalentPerLVAddList = new int[TalentPerLVAddListStringArray.Length];
                for (int i=0;i<TalentPerLVAddListStringArray.Length;i++)
                {
                     int.TryParse(TalentPerLVAddListStringArray[i],out TalentPerLVAddList[i]);
                }
            }
            int.TryParse(tables[10],out EffType);
            int.TryParse(tables[11],out EffTypeValue);
            int.TryParse(tables[12],out EffValue);
            int.TryParse(tables[13],out EffPerLVAdd);
            Desc = tables[14];
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/BeautyConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 646fb0599edaa1546b6617bf5d7cc6e2
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/Configs/BeautyQualityLVConfig.cs
New file
@@ -0,0 +1,80 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年12月21日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class BeautyQualityLVConfig : ConfigBase<int, BeautyQualityLVConfig>
{
    static BeautyQualityLVConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int ID;
    public int BeautyQuality;
    public int BeautyLV;
    public int LVNeedExp;
    public int[] AttrIDList;
    public int[] AttrValueList;
    public int[][] AwardItemList;
    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 ID);
            int.TryParse(tables[1],out BeautyQuality);
            int.TryParse(tables[2],out BeautyLV);
            int.TryParse(tables[3],out LVNeedExp);
            if (tables[4].Contains("["))
            {
                AttrIDList = JsonMapper.ToObject<int[]>(tables[4]);
            }
            else
            {
                string[] AttrIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                AttrIDList = new int[AttrIDListStringArray.Length];
                for (int i=0;i<AttrIDListStringArray.Length;i++)
                {
                     int.TryParse(AttrIDListStringArray[i],out AttrIDList[i]);
                }
            }
            if (tables[5].Contains("["))
            {
                AttrValueList = JsonMapper.ToObject<int[]>(tables[5]);
            }
            else
            {
                string[] AttrValueListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                AttrValueList = new int[AttrValueListStringArray.Length];
                for (int i=0;i<AttrValueListStringArray.Length;i++)
                {
                     int.TryParse(AttrValueListStringArray[i],out AttrValueList[i]);
                }
            }
            AwardItemList = JsonMapper.ToObject<int[][]>(tables[6].Replace("(", "[").Replace(")", "]"));
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/BeautyQualityLVConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cd6551a3725246a41b7ee227f77a56db
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/Configs/BeautySkinConfig.cs
New file
@@ -0,0 +1,110 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年12月21日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class BeautySkinConfig : ConfigBase<int, BeautySkinConfig>
{
    static BeautySkinConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int SkinID;
    public int BeautyID;
    public int UnlockWay;
    public int UnlockValue;
    public int UnlockNeedCnt;
    public int UpNeedCnt;
    public int StarMax;
    public int[] AttrIDList;
    public int[] InitAttrValueList;
    public int[] AttrPerStarAddList;
    public string HeadIcon;
    public string SmallRole;
    public string BigRole;
    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 SkinID);
            int.TryParse(tables[1],out BeautyID);
            int.TryParse(tables[2],out UnlockWay);
            int.TryParse(tables[3],out UnlockValue);
            int.TryParse(tables[4],out UnlockNeedCnt);
            int.TryParse(tables[5],out UpNeedCnt);
            int.TryParse(tables[6],out StarMax);
            if (tables[7].Contains("["))
            {
                AttrIDList = JsonMapper.ToObject<int[]>(tables[7]);
            }
            else
            {
                string[] AttrIDListStringArray = tables[7].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                AttrIDList = new int[AttrIDListStringArray.Length];
                for (int i=0;i<AttrIDListStringArray.Length;i++)
                {
                     int.TryParse(AttrIDListStringArray[i],out AttrIDList[i]);
                }
            }
            if (tables[8].Contains("["))
            {
                InitAttrValueList = JsonMapper.ToObject<int[]>(tables[8]);
            }
            else
            {
                string[] InitAttrValueListStringArray = tables[8].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                InitAttrValueList = new int[InitAttrValueListStringArray.Length];
                for (int i=0;i<InitAttrValueListStringArray.Length;i++)
                {
                     int.TryParse(InitAttrValueListStringArray[i],out InitAttrValueList[i]);
                }
            }
            if (tables[9].Contains("["))
            {
                AttrPerStarAddList = JsonMapper.ToObject<int[]>(tables[9]);
            }
            else
            {
                string[] AttrPerStarAddListStringArray = tables[9].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
                AttrPerStarAddList = new int[AttrPerStarAddListStringArray.Length];
                for (int i=0;i<AttrPerStarAddListStringArray.Length;i++)
                {
                     int.TryParse(AttrPerStarAddListStringArray[i],out AttrPerStarAddList[i]);
                }
            }
            HeadIcon = tables[10];
            SmallRole = tables[11];
            BigRole = tables[12];
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/BeautySkinConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9725e78e336a4fd43a27a4530f95e85d
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/Configs/TravelEventConfig.cs
New file
@@ -0,0 +1,47 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年12月21日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class TravelEventConfig : ConfigBase<int, TravelEventConfig>
{
    static TravelEventConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int EventID;
    public int AwardItemID;
    public int AwardItemCnt;
    public string ShowRate;
    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 EventID);
            int.TryParse(tables[1],out AwardItemID);
            int.TryParse(tables[2],out AwardItemCnt);
            ShowRate = tables[3];
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/TravelEventConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f7be2f35c0d86c43ad82c5cac661a7b
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/Configs/TravelSceneryConfig.cs
New file
@@ -0,0 +1,44 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           2025年12月21日
//--------------------------------------------------------
using System.Collections.Generic;
using System;
using UnityEngine;
using LitJson;
public partial class TravelSceneryConfig : ConfigBase<int, TravelSceneryConfig>
{
    static TravelSceneryConfig()
    {
        // 访问过静态构造函数
        visit = true;
    }
    public int ID;
    public int SceneryType;
    public int AwardQuality;
    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 ID);
            int.TryParse(tables[1],out SceneryType);
            int.TryParse(tables[2],out AwardQuality);
        }
        catch (Exception exception)
        {
            Debug.LogError(exception);
        }
    }
}
Main/Config/Configs/TravelSceneryConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5ef31d5d0e91bd40aa2f8a1ff715ebd
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/PartialConfigs/BeautyQualityLVConfig.cs
New file
@@ -0,0 +1,47 @@
using System.Collections.Generic;
public partial class BeautyQualityLVConfig : ConfigBase<int, BeautyQualityLVConfig>
{
    static Dictionary<int, Dictionary<int, BeautyQualityLVConfig>> beautyQualityLVConfigDict = new Dictionary<int, Dictionary<int, BeautyQualityLVConfig>>();
    static Dictionary<int, int> beautyQualityMaxLVDict = new Dictionary<int, int>();
    protected override void OnConfigParseCompleted()
    {
        if (!beautyQualityLVConfigDict.ContainsKey(BeautyQuality))
        {
            beautyQualityLVConfigDict[BeautyQuality] = new Dictionary<int, BeautyQualityLVConfig>();
        }
        beautyQualityLVConfigDict[BeautyQuality][BeautyLV] = this;
        if (!beautyQualityMaxLVDict.ContainsKey(BeautyQuality))
        {
            beautyQualityMaxLVDict[BeautyQuality] = BeautyLV;
        }
        else
        {
            if (beautyQualityMaxLVDict[BeautyQuality] < BeautyLV)
            {
                beautyQualityMaxLVDict[BeautyQuality] = BeautyLV;
            }
        }
    }
    public static bool TryGetBeautyQualityLVConfig(int beautyQuality, int beautyLV, out BeautyQualityLVConfig config)
    {
        config = null;
        if (beautyQualityLVConfigDict.TryGetValue(beautyQuality, out var beautyQualityDict) && beautyQualityDict.TryGetValue(beautyLV, out config))
        {
            return true;
        }
        return false;
    }
    public static int GetBeautyQualityMaxLV(int beautyQuality)
    {
        if (beautyQualityMaxLVDict.TryGetValue(beautyQuality, out var maxLV))
        {
            return maxLV;
        }
        return 0;
    }
}
Main/Config/PartialConfigs/BeautyQualityLVConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0660a23b092ec664ebfc5f9767299a4b
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/PartialConfigs/BeautySkinConfig.cs
New file
@@ -0,0 +1,34 @@
using System.Collections.Generic;
public partial class BeautySkinConfig : ConfigBase<int, BeautySkinConfig>
{
    private static Dictionary<int, List<BeautySkinConfig>> mmIDToSkinDict = new Dictionary<int, List<BeautySkinConfig>>();
    protected override void OnConfigParseCompleted()
    {
        if (!mmIDToSkinDict.ContainsKey(BeautyID))
        {
            List<BeautySkinConfig> skinList = new List<BeautySkinConfig>();
            skinList.Add(this);
            mmIDToSkinDict.Add(BeautyID, skinList);
        }
        else
        {
            mmIDToSkinDict[BeautyID].Add(this);
        }
    }
    public static List<BeautySkinConfig> GetSkinListByMMID(int mmID)
    {
        List<BeautySkinConfig> skinList = null;
        mmIDToSkinDict.TryGetValue(mmID, out skinList);
        return skinList;
    }
}
Main/Config/PartialConfigs/BeautySkinConfig.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90057d768cacf89479f093c7d875eff4
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/Config/PartialConfigs/PlayerPropertyConfig.cs
@@ -81,6 +81,7 @@
        return GetFullDescription(property.x, property.y);
    }
    // 获取属性全描述,包括属性名和属性值 参考格式 string format = "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}");
    public static string GetFullDescription(int id, long value, string format="{0}+{1}")
    {
        var config = Get(id);
Main/Core/NetworkPackage/ClientPack/CB4_FightDefine/CB415_tagCSMainDropItemOP.cs
@@ -1,12 +1,12 @@
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
public class CB415_tagCSMainDropItemOP : GameNetPackBasic {
    public byte Count;
    public  ushort[] IndexList;    // 掉落背包中的物品格子索引列表
    public byte OPType;    // 0 - 拾取非装备物品;1 - 分解;2 - 穿戴/替换;
    public byte OPType;    // 0 - 拾取非装备物品;1 - 分解;2 - 穿戴/替换; 3- 主动请求掉落
    public byte OPValue;    // 操作额外指令值,由操作类型决定,如穿戴时可发送穿戴后是否自动分解
    public CB415_tagCSMainDropItemOP () {
Main/Core/NetworkPackage/DTCFile/ServerPack/HB0_Event/DTCB040_tagSCTravelInfo.cs
@@ -1,11 +1,13 @@
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
// B0 40 游历信息 #tagSCTravelInfo
public class DTCB040_tagSCTravelInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HB040_tagSCTravelInfo vNetData = vNetPack as HB040_tagSCTravelInfo;
        BeautyMMManager.Instance.UpdateTravelInfo(vNetData);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB130_tagSCBeautyInfo.cs
@@ -1,11 +1,12 @@
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
// B1 30 红颜信息 #tagSCBeautyInfo
public class DTCB130_tagSCBeautyInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack) {
        base.Done(vNetPack);
        HB130_tagSCBeautyInfo vNetData = vNetPack as HB130_tagSCBeautyInfo;
        BeautyMMManager.Instance.UpdateBeautyMMData(vNetData);
    }
}
Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -136,6 +136,8 @@
        Register(typeof(HB129_tagSCLineupRecommendInfo), typeof(DTCB129_tagSCLineupRecommendInfo));
        Register(typeof(HAB05_tagSCOSACelebrationInfo), typeof(DTCAB05_tagSCOSACelebrationInfo));
        Register(typeof(HB131_tagSCHeroFatesInfo), typeof(DTCB131_tagSCHeroFatesInfo));
        Register(typeof(HB130_tagSCBeautyInfo), typeof(DTCB130_tagSCBeautyInfo));
        Register(typeof(HB040_tagSCTravelInfo), typeof(DTCB040_tagSCTravelInfo));
    }
    //主工程注册封包
Main/Main.cs
@@ -95,6 +95,7 @@
        managers.Add(LineupRecommendManager.Instance);
        managers.Add(OSActivityManager.Instance);
        managers.Add(HeroFatesManager.Instance);
        managers.Add(BeautyMMManager.Instance);
        foreach (var manager in managers)
        {
            manager.Init();
Main/System/Arena/ArenaManager.cs
@@ -27,6 +27,7 @@
    public Dictionary<int, int[][]> seasonRankRewards;  // 赛季排行奖励 {"名次":[[物品ID, 个数,是否拍品], ...], ...}
    public uint score;    // 当前积分
    public int totalWinCnt;  //累计胜利次数
    public List<ArenaMatchInfo> matchInfoList = new List<ArenaMatchInfo>();
    //用于用来拿战斗胜利失败的头像信息
@@ -155,6 +156,7 @@
        if (vNetData == null)
            return;
        this.score = vNetData.Score;
        totalWinCnt = (int)vNetData.WinCnt;
        OnUpdateArenaPlayerInfo?.Invoke();
    }
    public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData)
Main/System/BeautyMM.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8042b4dcd2800143ae2663d7b0c5765
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMBaseWin.cs
New file
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMBaseWin : OneLevelWin
{
    protected override void OpenSubUIByTabIndex()
    {
        switch (functionOrder)
        {
            case 0:
                currentSubUI = UIManager.Instance.OpenWindow<BeautyMMListWin>();
                break;
            case 1:
                // 充值界面
                currentSubUI = UIManager.Instance.OpenWindow<BeautyMMTravelWin>();
                break;
            default:
                Debug.LogWarning("未知的标签索引: " + functionOrder);
                break;
        }
    }
}
Main/System/BeautyMM/BeautyMMBaseWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 48ac597434993c24eb71702157db3aa0
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMCell.cs
New file
@@ -0,0 +1,113 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMCell : MonoBehaviour
{
    [SerializeField] Image bgIcon;
    [SerializeField] ImageEx roleImg;
    [SerializeField] Text nameText;
    [SerializeField] Transform costRect;
    [SerializeField] Image costIcon;
    [SerializeField] Text costText;
    [SerializeField] Text[] talentTexts;
    [SerializeField] Image redImg;
    [SerializeField] Image activeImg;
    [SerializeField] Image lvBg;
    [SerializeField] Text lvText;
    [SerializeField] Button mmBtn;
    [SerializeField] Transform mask;
    public void Display(int index)
    {
        var mmID = BeautyMMManager.Instance.beautyMMIDSortList[index];
        var isActive = BeautyMMManager.Instance.isActiveMM(mmID);
        var mmConfig = BeautyConfig.Get(mmID);
        bgIcon.SetSprite($"mmBG{mmConfig.BeautyQuality}");
        int skinID = BeautyMMManager.Instance.GetUsedSkinID(mmID);
        var skinConfig = BeautySkinConfig.Get(skinID);
        roleImg.SetOrgSprite(skinConfig.SmallRole, "BeautyMMSmallRole");
        roleImg.gray = !isActive;
        mask.SetActive(!isActive);
        nameText.text = mmConfig.Name;
        if (!isActive)
        {
            costRect.SetActive(mmConfig.UnlockWay == 1);
            costIcon.SetItemSprite(mmConfig.UnlockValue);
            var cnt = PackManager.Instance.GetItemCountByID(PackType.Item, mmConfig.UnlockValue);
            costText.text = $"{cnt}/{mmConfig.UnlockNeedCnt}";
            costText.color = cnt >= mmConfig.UnlockNeedCnt ? Color.green : Color.red;
        }
        else
        {
            costRect.SetActive(false);
        }
        //先显示天赋属性,再显示天赋特性
        var attrs = BeautyMMManager.Instance.GetMMTalentAttrForUI(mmID, true);
        int talentIndex = 0;
        if (attrs.IsNullOrEmpty())
        {
            talentIndex = 0;
        }
        else
        {
            foreach (var attr in attrs)
            {
                if (talentIndex < talentTexts.Length)
                {
                    talentTexts[talentIndex].SetActive(true);
                    talentTexts[talentIndex].text = PlayerPropertyConfig.GetFullDescription(attr.Key, attr.Value);
                }
                else
                {
                    break;
                }
                talentIndex++;
            }
        }
        for (int i = talentIndex; i < talentTexts.Length; i++)
        {
            if (i == talentIndex && mmConfig.EffType != 0)
            {
                //天赋效果约定最多一个
                talentTexts[talentIndex].SetActive(true);
                talentTexts[i].text = Language.Get($"BeautyMMTalentDefault{mmConfig.EffType}");
            }
            else
            {
                talentTexts[i].SetActive(false);
            }
        }
        redImg.SetActive(BeautyMMManager.Instance.IsMMRed(mmID));
        activeImg.SetActive(BeautyMMManager.Instance.GetMMBaseState(mmConfig) > 1);
        var mmData = BeautyMMManager.Instance.GetBeautyMMData(mmID);
        if (mmData != null)
        {
            lvText.text = mmData.LV.ToString();
            lvBg.SetActive(mmData.LV > 0);
        }
        else
        {
            lvBg.SetActive(false);
        }
        mmBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<BeautyMMShowWin>(mmID);
        });
    }
}
Main/System/BeautyMM/BeautyMMCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14d2e2937f1af8e41a99e3aa09ea85a5
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMLineCell.cs
New file
@@ -0,0 +1,29 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMLineCell : CellView
{
    [SerializeField] BeautyMMCell[] mmCells;
    public void Display(int index)
    {
        for (int i = 0; i < mmCells.Length; i++)
        {
            if (index + i < BeautyMMManager.Instance.beautyMMIDSortList.Count)
            {
                mmCells[i].SetActive(true);
                mmCells[i].Display(index + i);
            }
            else
            {
                mmCells[i].SetActive(false);
            }
        }
    }
}
Main/System/BeautyMM/BeautyMMLineCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20109e4945479c3438f8b35aad598423
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMListWin.cs
New file
@@ -0,0 +1,101 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMListWin : UIBase
{
    [SerializeField] Button seeAttrBtn;
    [SerializeField] ScrollerController scroller;
    [SerializeField] GroupButtonEx allMMBtn;
    [SerializeField] GroupButtonEx knownMMBtn;
    [SerializeField] GroupButtonEx unknownMMBtn;
    protected override void InitComponent()
    {
        seeAttrBtn.AddListener(() =>
        {
            // UIManager.Instance.OpenWindow<BeautyMMAttrWin>();
        });
        allMMBtn.AddListener(() =>
        {
            functionOrder = 0;
            BeautyMMManager.Instance.SortMMList(functionOrder);
            CreateScroller();
        });
        knownMMBtn.AddListener(() =>
        {
            functionOrder = 1;
            BeautyMMManager.Instance.SortMMList(functionOrder);
            CreateScroller();
        });
        unknownMMBtn.AddListener(() =>
        {
            functionOrder = 2;
            BeautyMMManager.Instance.SortMMList(functionOrder);
            CreateScroller();
        });
    }
    protected override void OnPreOpen()
    {
        BeautyMMManager.Instance.SortMMList(functionOrder);
        scroller.OnRefreshCell += OnRefreshCell;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        Display();
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
    }
    void CreateScroller()
    {
        scroller.Refresh();
        for (int i = 0; i < BeautyMMManager.Instance.beautyMMIDSortList.Count; i++)
        {
            if (i % 3 == 0)
            {
                scroller.AddCell(ScrollerDataType.Header, i);
            }
        }
        scroller.Restart();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as BeautyMMLineCell;
        _cell.Display(cell.index);
    }
    void Display()
    {
        switch (functionOrder)
        {
            case 0:
                allMMBtn.SelectBtn(true);
                break;
            case 1:
                knownMMBtn.SelectBtn(true);
                break;
            case 2:
                unknownMMBtn.SelectBtn(true);
                break;
        }
        CreateScroller();
    }
    void OnCloseWindow(UIBase ui)
    {
        if (ui is BeautyMMShowWin)
        {
            scroller.m_Scorller.RefreshActiveCellViews();
        }
    }
}
Main/System/BeautyMM/BeautyMMListWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05c8f6d48338973479402594fb503785
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMManager.Travel.cs
New file
@@ -0,0 +1,147 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using LitJson;
public partial class BeautyMMManager : GameSystemManager<BeautyMMManager>
{
    public byte m_Energy;    //剩余体力
    public uint m_EnergyTime;    //上次恢复体力时间戳
    public uint m_TravelCnt;    //累计游历次数
    public byte m_SceneryType;    //景观类型
    public byte m_SceneryRow;    //景观左上角所在行,从1开始
    public byte m_SceneryCol;    //景观左上角所在列,从1开始
    public uint m_SceneryLVInfo;    //景观升级信息:0-还未处理景观升级;个位数-第1次升级成功与否,1-成功,2-失败;十位-第2次 ...
    public byte m_Result;    //后端处理:0-无;1-常规;2-马车炸弹;3-传送门;4-景观;5-重置开始;!!!重登会变成0,只做即时判断用
    Dictionary<Int2, TravelGrid> m_GridDict = new Dictionary<Int2, TravelGrid>();
    public List<Int2> openChangeGridList = new List<Int2>(); // 前后对比,有变化的格子 ,打开前面前需清理
    public event Action<int> OnTravelInfoUpdate;
    public int maxGirds = 0;
    public Int2 clickGirdPos = new Int2();
    public void UpdateTravelInfo(HB040_tagSCTravelInfo netPack)
    {
        m_Energy = netPack.Energy;
        m_EnergyTime = netPack.EnergyTime;
        m_TravelCnt = netPack.TravelCnt;
        m_SceneryType = netPack.SceneryType;
        m_SceneryRow = netPack.SceneryRow;
        m_SceneryCol = netPack.SceneryCol;
        m_SceneryLVInfo = netPack.SceneryLVInfo;
        m_Result = netPack.Result;
        openChangeGridList.Clear();
        for (int i = 0; i < netPack.GridCnt; i++)
        {
            var grid = netPack.GridList[i];
            var key = new Int2(grid.Row, grid.Col);
            if (m_GridDict.ContainsKey(key))
            {
                if (m_GridDict[key].State != grid.State)
                {
                    openChangeGridList.Add(key);
                }
                m_GridDict[key].State = grid.State;
                m_GridDict[key].Multi = grid.Multi;
                m_GridDict[key].EventID = grid.EventID;
            }
            else
            {
                if (grid.State != 0)
                {
                    openChangeGridList.Add(key);
                }
                m_GridDict.Add(key, new TravelGrid() { State = grid.State, Multi = grid.Multi, EventID = grid.EventID });
            }
        }
        OnTravelInfoUpdate?.Invoke(m_Result);
        UpdateTravelRedpoint();
    }
    //index从0开始,转格子坐标(1,1)开始
    public Int2 ChangeIndexToGrid(int index)
    {
        int row = index / travelRowCol[1] + 1;
        int col = index % travelRowCol[1] + 1;
        return new Int2(row, col);
    }
    public TravelGrid GetGrid(Int2 gridPos)
    {
        if (m_GridDict.ContainsKey(gridPos))
        {
            return m_GridDict[gridPos];
        }
        return null;
    }
    public bool CanOpenBuild()
    {
        if (m_SceneryType == 0)
        {
            return false;
        }
        //判断建筑格子是否全开,计算数量
        int cnt = 0;
        foreach (var grid in m_GridDict)
        {
            if (grid.Value.State == 1 && grid.Value.EventID > 0 && grid.Value.EventID < (int)GirdEventType.Door)
            {
                cnt++;
            }
        }
        return cnt >= m_SceneryType;
    }
    public bool HasDoor()
    {
        if (m_SceneryType == 0)
        {
            return false;
        }
        foreach (var grid in m_GridDict)
        {
            if (grid.Value.EventID == (int)GirdEventType.Door)
            {
                return true;
            }
        }
        return false;
    }
    Redpoint redpointTravel = new Redpoint(MainRedDot.Redpoint_BeautyMM, MainRedDot.Redpoint_BeautyMM * 10 + 2);
    void UpdateTravelRedpoint()
    {
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.BeautyMM))
        {
            return;
        }
        redpointTravel.state = m_Energy > 0 ? RedPointState.Simple : RedPointState.None;
    }
}
public class TravelGrid
{
    public byte State;        //状态:0-未点击;1-已开启;2-裂纹
    public byte Multi;        //奖励倍值: 默认1倍;2-双倍;...
    public ushort EventID;        //事件ID
}
//低于99的为建筑格子 大于200的为物品格子
public enum GirdEventType
{
    None = 0,
    Door = 99,      // 门
    Empty = 100,    // 空格子
    Horse = 101,    // 马匹
}
Main/System/BeautyMM/BeautyMMManager.Travel.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a952f6ec1e792504886a22be9d63bd63
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMManager.cs
New file
@@ -0,0 +1,555 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using LitJson;
public partial class BeautyMMManager : GameSystemManager<BeautyMMManager>
{
    public List<int> beautyMMIDSortList = new List<int>();
    public Dictionary<int, BeautyMMData> beautyMMDataDict = new Dictionary<int, BeautyMMData>();    //MMID 对应 数据
    public Dictionary<int, BeautyMMSkinData> beautyMMSkinDataDict = new Dictionary<int, BeautyMMSkinData>();    //皮肤ID 对应 数据
    public event Action OnBeautyMMDataUpdate;
    public int selectLoveItemID = 0;
    //配置
    //道具ID 对应 好感度
    public Dictionary<int, int> giftIDToLoveDict = new Dictionary<int, int>();
    public int[] loveItemIDs;
    public int specialGiftLove = 0; // 数值3:专属信物道具好感度
    public int needLVForTalent = 0; // 数值4:每x级好感度提升一级天赋效果
    public int baseTravelEnergy = 0;    // 数值1:基础体力上限
    public int recoverTravelEnergyTime = 0;   // 数值2:恢复1点体力所需时间,分钟
    public int[] travelRowCol = new int[2]; // 数值3:游历行列数  行|列
    public override void Init()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitialize;
        ParseConfig();
    }
    public override void Release()
    {
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitialize;
    }
    void OnBeforePlayerDataInitialize()
    {
        beautyMMIDSortList.Clear();
        beautyMMDataDict.Clear();
        beautyMMSkinDataDict.Clear();
        m_GridDict.Clear();
    }
    void ParseConfig()
    {
        var config = FuncConfigConfig.Get("BeautyLVUP");
        loveItemIDs = JsonMapper.ToObject<int[]>(config.Numerical1);
        var _list2 = JsonMapper.ToObject<int[]>(config.Numerical2);
        for (int i = 0; i < loveItemIDs.Length; i++)
        {
            giftIDToLoveDict[loveItemIDs[i]] = _list2[i];
        }
        specialGiftLove = int.Parse(config.Numerical3);
        needLVForTalent = int.Parse(config.Numerical4);
        config = FuncConfigConfig.Get("TravelSet");
        baseTravelEnergy = int.Parse(config.Numerical1);
        recoverTravelEnergyTime = int.Parse(config.Numerical2);
        travelRowCol = ConfigParse.GetMultipleStr<int>(config.Numerical3);
        maxGirds = travelRowCol[0] * travelRowCol[1];
    }
    public void UpdateBeautyMMData(HB130_tagSCBeautyInfo data)
    {
        foreach (var beauty in data.BeautyList)
        {
            beautyMMDataDict[beauty.BeautyID] = new BeautyMMData()
            {
                State = beauty.State,
                LV = beauty.LV,
                Exp = beauty.Exp,
                AwardLV = beauty.AwardLV,
            };
            foreach (var skin in beauty.SkinList)
            {
                beautyMMSkinDataDict[skin.SkinID] = new BeautyMMSkinData()
                {
                    State = skin.State,
                    Used = skin.Used,
                    Star = skin.Star,
                };
            }
        }
        UpdateRedpoint();
        OnBeautyMMDataUpdate?.Invoke();
    }
    //0 全部 1 已激活 2 未激活
    public void SortMMList(int type)
    {
        var _list = BeautyConfig.GetKeys();
        beautyMMIDSortList.Clear();
        if (type == 0)
        {
            beautyMMIDSortList = _list;
        }
        else if (type == 1)
        {
            foreach (var mmID in _list)
            {
                if (beautyMMDataDict.ContainsKey(mmID) && beautyMMDataDict[mmID].State == 1)
                {
                    beautyMMIDSortList.Add(mmID);
                }
            }
        }
        else if (type == 2)
        {
            foreach (var mmID in _list)
            {
                if (!beautyMMDataDict.ContainsKey(mmID) || beautyMMDataDict[mmID].State == 0)
                {
                    beautyMMIDSortList.Add(mmID);
                }
            }
        }
        beautyMMIDSortList.Sort(CmpMM);
    }
    int CmpMM(int mmIDA, int mmIDB)
    {
        bool isActiveA = false;
        if (beautyMMDataDict.ContainsKey(mmIDA))
        {
            isActiveA = beautyMMDataDict[mmIDA].State == 1;
        }
        bool isActiveB = false;
        if (beautyMMDataDict.ContainsKey(mmIDB))
        {
            isActiveB = beautyMMDataDict[mmIDB].State == 1;
        }
        if (isActiveA != isActiveB)
        {
            return isActiveA ? -1 : 1;
        }
        return mmIDA - mmIDB;
    }
    public BeautyMMData GetBeautyMMData(int mmID)
    {
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            return beautyMMDataDict[mmID];
        }
        return null;
    }
    public int GetUsedSkinID(int mmID)
    {
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            var _beauty = beautyMMDataDict[mmID];
            if (_beauty.State == 1)
            {
                foreach (var skin in beautyMMSkinDataDict)
                {
                    if (skin.Value.Used == 1)
                    {
                        return skin.Key;
                    }
                }
            }
        }
        //默认第一个
        var _list = BeautySkinConfig.GetSkinListByMMID(mmID);
        if (_list.Count > 0)
        {
            return _list[0].SkinID;
        }
        return 0;
    }
    public bool isActiveMM(int mmID)
    {
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            return beautyMMDataDict[mmID].State == 1;
        }
        return false;
    }
    // 获取MM天赋属性属性, defaultAttr 是否使用默认属性
    public Dictionary<int, int> GetMMTalentAttrForUI(int mmID, bool defaultAttr = false)
    {
        var _dict = new Dictionary<int, int>();
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            var _beauty = beautyMMDataDict[mmID];
            if (_beauty.State == 1)
            {
                var config = BeautyConfig.Get(mmID);
                if (config != null)
                {
                    //初始天赋属性
                    for (int i = 0; i < config.TalentAttrIDList.Length; i++)
                    {
                        _dict[config.TalentAttrIDList[i]] = config.TalentAttrValueList[i];
                    }
                    //按x级好感度提升一级天赋效果
                    var _lv = _beauty.LV;
                    var _addLV = _lv / needLVForTalent;
                    if (_addLV > 0)
                    {
                        for (int i = 0; i < config.TalentAttrIDList.Length; i++)
                        {
                            _dict[config.TalentAttrIDList[i]] += _addLV * config.TalentPerLVAddList[i];
                        }
                    }
                }
                return _dict;
            }
        }
        if (defaultAttr)
        {
            var config = BeautyConfig.Get(mmID);
            if (config != null)
            {
                //初始天赋属性
                for (int i = 0; i < config.TalentAttrIDList.Length; i++)
                {
                    _dict[config.TalentAttrIDList[i]] = config.TalentAttrValueList[i];
                }
            }
        }
        return _dict;
    }
    // 真实属性
    public Dictionary<int, int> GetMMTalentAttr(int mmID)
    {
        var _dict = new Dictionary<int, int>();
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            var _beauty = beautyMMDataDict[mmID];
            if (_beauty.State == 1)
            {
                var config = BeautyConfig.Get(mmID);
                if (config != null)
                {
                    //初始天赋属性
                    for (int i = 0; i < config.TalentAttrIDList.Length; i++)
                    {
                        _dict[config.TalentAttrIDList[i]] = config.TalentAttrValueList[i];
                    }
                    //按x级好感度提升一级天赋效果
                    var _lv = _beauty.LV;
                    var _addLV = _lv / needLVForTalent;
                    if (_addLV > 0)
                    {
                        for (int i = 0; i < config.TalentAttrIDList.Length; i++)
                        {
                            _dict[config.TalentAttrIDList[i]] += _addLV * config.TalentPerLVAddList[i];
                        }
                    }
                }
                return _dict;
            }
        }
        return _dict;
    }
    public int GetMMTalentEffectForUI(int mmID, bool defaultAttr = true)
    {
        int _effect = 0;
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            var _beauty = beautyMMDataDict[mmID];
            if (_beauty.State == 1)
            {
                var config = BeautyConfig.Get(mmID);
                if (config != null)
                {
                    //初始天赋效果
                    _effect = config.EffValue;
                    //按x级好感度提升一级天赋效果
                    var _lv = _beauty.LV;
                    var _addLV = _lv / needLVForTalent;
                    if (_addLV > 0)
                    {
                        _effect += _addLV * config.EffPerLVAdd;
                    }
                }
                return _effect;
            }
        }
        if (defaultAttr)
        {
            var config = BeautyConfig.Get(mmID);
            if (config != null)
            {
                //初始天赋效果
                _effect = config.EffValue;
            }
        }
        return _effect;
    }
    // 获取MM天赋效果
    public int GetMMTalentEffect(int mmID)
    {
        int _effect = 0;
        if (beautyMMDataDict.ContainsKey(mmID))
        {
            var _beauty = beautyMMDataDict[mmID];
            if (_beauty.State == 1)
            {
                var config = BeautyConfig.Get(mmID);
                if (config != null)
                {
                    //初始天赋效果
                    _effect = config.EffValue;
                    //按x级好感度提升一级天赋效果
                    var _lv = _beauty.LV;
                    var _addLV = _lv / needLVForTalent;
                    if (_addLV > 0)
                    {
                        _effect += _addLV * config.EffPerLVAdd;
                    }
                }
                return _effect;
            }
        }
        return _effect;
    }
    #region 红点
    Redpoint redpoint = new Redpoint(MainRedDot.MainAffairsRedpoint, MainRedDot.Redpoint_BeautyMM);
    Redpoint redpointMM = new Redpoint(MainRedDot.Redpoint_BeautyMM, MainRedDot.Redpoint_BeautyMM * 10 + 1);
    Redpoint redpointMMTotal = new Redpoint(MainRedDot.Redpoint_BeautyMM * 10 + 1, (MainRedDot.Redpoint_BeautyMM * 10 + 1) * 10);
    Redpoint redpointMMKnown = new Redpoint((MainRedDot.Redpoint_BeautyMM * 10 + 1) * 10, (MainRedDot.Redpoint_BeautyMM * 10 + 1) * 10 + 1);
    Redpoint redpointMMUnKnown = new Redpoint((MainRedDot.Redpoint_BeautyMM * 10 + 1) * 10, (MainRedDot.Redpoint_BeautyMM * 10 + 1) * 10 + 2);
    void UpdateRedpoint()
    {
        redpointMMKnown.state = RedPointState.None;
        redpointMMUnKnown.state = RedPointState.None;
        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.BeautyMM))
        {
            return;
        }
        var _list = BeautyConfig.GetValues();
        foreach (var beauty in _list)
        {
            var state = GetMMBaseState(beauty);
            if (state == 1)
            {
                redpointMMKnown.state = RedPointState.Simple;
            }
            else if (state == 2)
            {
                redpointMMUnKnown.state = RedPointState.Simple;
            }
        }
        // 时装MM 红点
        if (redpointMMKnown.state == RedPointState.None)
        {
            foreach (var beauty in _list)
            {
                if (IsMMSkinRed(beauty.BeautyID))
                {
                    redpointMMKnown.state = RedPointState.Simple;
                    break;
                }
            }
        }
    }
    //MM基础状态 0 无 1 有奖励 2 可物品激活 3 需功能激活
    public int GetMMBaseState(BeautyConfig beauty)
    {
        //是否可激活,是否有奖励可领取
        if (beautyMMDataDict.ContainsKey(beauty.BeautyID))
        {
            var _beauty = beautyMMDataDict[beauty.BeautyID];
            if (_beauty.State == 1)
            {
                if (_beauty.LV > _beauty.AwardLV)
                {
                    //有奖励可领取
                    return 1;
                }
                return 0;
            }
        }
        //功能性激活
        switch (beauty.UnlockWay)
        {
            case 1:
                if (PackManager.Instance.GetItemCountByID(PackType.Item, beauty.UnlockValue) >= beauty.UnlockNeedCnt)
                {
                    //可激活
                    return 2;
                }
                break;
            case 2:
                if (TaskManager.Instance.mainTask.TaskID > beauty.UnlockValue)
                {
                    //任务
                    return 3;
                }
                break;
            case 3:
                if (ArenaManager.Instance.totalWinCnt >= beauty.UnlockNeedCnt)
                {
                    return 3;
                }
                break;
            case 4:
                if (GoldRushManager.Instance.maxWorkerCount >= beauty.UnlockNeedCnt)
                {
                    //可激活
                    return 3;
                }
                break;
            case 5:
                int dataMapID = BoneFieldManager.Instance.DataMapID;
                if (DungeonManager.Instance.TryGetFBInfoByMapID(dataMapID, out var fbInfo))
                {
                    if (BoneFieldManager.Instance.GetNowPassLineID(fbInfo) > beauty.UnlockValue)
                    {
                        return 3;
                    }
                }
                break;
            case 6:
                if (PlayerDatas.Instance.baseData.realmLevel >= beauty.UnlockValue)
                {
                    return 3;
                }
                break;
            case 7:
                if (m_TravelCnt >= beauty.UnlockNeedCnt)
                {
                    return 3;
                }
                break;
        }
        return 0;
    }
    // 时装MM 状态 (前提是已激活本体的情况) 0 无 1 可激活 2 可升星;
    public int GetMMSkinStateBySkinID(BeautySkinConfig skin)
    {
        if (beautyMMSkinDataDict.ContainsKey(skin.SkinID))
        {
            //升星判断
            var _skin = beautyMMSkinDataDict[skin.SkinID];
            if (_skin.State == 1)
            {
                if (_skin.Star < skin.StarMax && PackManager.Instance.GetItemCountByID(PackType.Item, skin.UnlockValue) >= skin.UpNeedCnt)
                {
                    return 2;
                }
                return 0;
            }
        }
        //激活
        if (skin.UnlockWay == 2 && PackManager.Instance.GetItemCountByID(PackType.Item, skin.UnlockValue) >= skin.UnlockNeedCnt)
        {
            return 1;
        }
        return 0;
    }
    public bool IsMMSkinRed(int mmID)
    {
        var _list = BeautySkinConfig.GetSkinListByMMID(mmID);
        if (_list == null || _list.Count == 0)
        {
            return false;
        }
        if (!beautyMMDataDict.ContainsKey(mmID))
        {
            return false;
        }
        var _beauty = beautyMMDataDict[mmID];
        if (_beauty.State == 0)
        {
            return false;
        }
        foreach (var skin in _list)
        {
            if (GetMMSkinStateBySkinID(skin) > 0)
            {
                return true;
            }
        }
        return false;
    }
    // 判断基础的养成 和 时装
    public bool IsMMRed(int mmID)
    {
        var config = BeautyConfig.Get(mmID);
        if (GetMMBaseState(config) > 0)
        {
            return true;
        }
        return IsMMSkinRed(mmID);
    }
    #endregion
}
public class BeautyMMData
{
    public byte State;        //是否已激活
    public ushort LV;        //红颜好感等级,激活时为0级
    public ushort Exp;        //当前等级经验
    public ushort AwardLV;        //已经领取到的奖励等级记录
}
public class BeautyMMSkinData {
    public byte State;        //是否已激活
    public byte Used;        //是否已穿戴该时装,某个红颜的所有时装穿戴可能都为0,则前端取默认时装进行展示,如果有同步已穿戴的则以后端为准
    public byte Star;        //时装星级,激活时为0星
}
Main/System/BeautyMM/BeautyMMManager.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f7899b33b25dc84ab06ff2189d57448
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMShowWin.cs
New file
@@ -0,0 +1,443 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMShowWin : UIBase
{
    [SerializeField] Image qualityImg;
    [SerializeField] Text qualityText1; // 品质分两字显示,注意海外版本
    [SerializeField] Text qualityText2;
    [SerializeField] Text nameText;
    [SerializeField] Button descBtn;
    [SerializeField] ImageEx roleImg;
    [SerializeField] UIEffectPlayer roleUPEffect;
    [SerializeField] Button leftBtn;
    [SerializeField] Button rightBtn;
    [SerializeField] Button skinBtn;
    [SerializeField] Transform trainRect;
    [SerializeField] Transform activeRect;
    [SerializeField] Text activeTipText;
    [SerializeField] Button activeBtn;
    [SerializeField] Text lvNameText;
    [SerializeField] Text lvText;
    [SerializeField] Text expText;
    [SerializeField] Image process;
    [SerializeField] ItemCell showAwardCell;
    [SerializeField] Button[] awardBtns;   //小奖励
    [SerializeField] Image[] awardImgs;
    [SerializeField] Button seeAttrBtn;
    [SerializeField] Text nextAddAttrText;
    [SerializeField] Text[] talentTexts;
    [SerializeField] Transform nextLVTalentTipRect;
    [SerializeField] Text nextLVTalentTip;
    [SerializeField] ScrollerController loveScroller;
    [SerializeField] Toggle onekeyToggle;
    [SerializeField] Button giftBtn;
    [SerializeField] Transform giftOPRect;
    [SerializeField] Transform fullRect;
    int mmID;
    BeautyConfig mmConfig;
    List<int> itemlist = new List<int>();
    protected override void InitComponent()
    {
        descBtn.AddListener(() =>
        {
            SmallTipWin.showText = mmConfig.Desc;
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            SmallTipWin.isDownShow = true;
            UIManager.Instance.OpenWindow<SmallTipWin>();
        });
        leftBtn.AddListener(() =>
        {
            var index = BeautyMMManager.Instance.beautyMMIDSortList.IndexOf(mmID);
            if (index > 0)
            {
                mmID = BeautyMMManager.Instance.beautyMMIDSortList[index - 1];
            }
            else
            {
                mmID = BeautyMMManager.Instance.beautyMMIDSortList[BeautyMMManager.Instance.beautyMMIDSortList.Count - 1];
            }
            Display();
        });
        rightBtn.AddListener(() =>
        {
            var index = BeautyMMManager.Instance.beautyMMIDSortList.IndexOf(mmID);
            if (index < BeautyMMManager.Instance.beautyMMIDSortList.Count - 1)
            {
                mmID = BeautyMMManager.Instance.beautyMMIDSortList[index + 1];
            }
            else
            {
                mmID = BeautyMMManager.Instance.beautyMMIDSortList[0];
            }
            Display();
        });
        skinBtn.AddListener(() =>
        {
            // UIManager.Instance.OpenWindow<BeautyMMListWin>();
        });
        seeAttrBtn.AddListener(() =>
        {
            // UIManager.Instance.OpenWindow<BeautyMMAttrWin>();
        });
        activeBtn.AddListener(ActiveMM);
        giftBtn.AddListener(SendGift);
        for (int i = 0; i < awardBtns.Length; i++)
        {
            awardBtns[i].AddListener(() =>
            {
                var pack = new CA504_tagCMPlayerGetReward();
                pack.RewardType = 6;
                pack.DataEx = (uint)mmID;
                GameNetSystem.Instance.SendInfo(pack);
            });
        }
    }
    protected override void OnPreOpen()
    {
        mmID = functionOrder;
        loveScroller.OnRefreshCell += OnRefreshCell;
        BeautyMMManager.Instance.OnBeautyMMDataUpdate += OnBeautyMMDataUpdate;
        PackManager.Instance.RefreshItemEvent += OnRefreshItemEvent;
        Display();
    }
    protected override void OnPreClose()
    {
        loveScroller.OnRefreshCell -= OnRefreshCell;
        BeautyMMManager.Instance.OnBeautyMMDataUpdate -= OnBeautyMMDataUpdate;
        PackManager.Instance.RefreshItemEvent -= OnRefreshItemEvent;
    }
    void OnBeautyMMDataUpdate()
    {
        Display();
    }
    void OnRefreshItemEvent(PackType packType, int index, int itemID)
    {
        if (packType == PackType.Item)
        {
            if (itemlist.Contains(itemID))
            {
                loveScroller.m_Scorller.RefreshActiveCellViews();
            }
        }
    }
    void Display()
    {
        mmConfig = BeautyConfig.Get(mmID);
        qualityImg.SetSprite($"mmMark{mmConfig.BeautyQuality}");
        string qualityStr = Language.Get($"CommonQuality{mmConfig.BeautyQuality}");
        qualityText1.text = qualityStr[0].ToString();
        qualityText2.text = qualityStr.Substring(1);
        nameText.text = mmConfig.Name;
        var skinID = BeautyMMManager.Instance.GetUsedSkinID(mmID);
        var skinConfig = BeautySkinConfig.Get(skinID);
        roleImg.SetOrgSprite(skinConfig.BigRole, "BeautyMMBigRole");
        roleImg.SetNativeSize();
        var isActive = BeautyMMManager.Instance.isActiveMM(mmID);
        trainRect.SetActive(isActive);
        activeRect.SetActive(!isActive);
        activeTipText.text = !isActive ? GetActiveTip(mmConfig) : "";
        var mmData = BeautyMMManager.Instance.GetBeautyMMData(mmID);
        var rank = mmData != null ? mmData.LV / BeautyMMManager.Instance.needLVForTalent + 1 : 1;
        lvNameText.text = Language.Get($"BeautyMMLVName{rank}");
        lvText.text = mmData != null ? mmData.LV.ToString() : "0";
        var maxLV = BeautyQualityLVConfig.GetBeautyQualityMaxLV(mmConfig.BeautyQuality);
        bool isMaxLV = mmData != null && mmData.LV >= maxLV;
        int needExp;
        if (isMaxLV)
        {
            needExp = 0;
            process.fillAmount = 1;
            showAwardCell.SetActive(false);
            nextAddAttrText.text = Language.Get("L1055");
            nextLVTalentTipRect.SetActive(false);
            fullRect.SetActive(true);
            giftOPRect.SetActive(false);
        }
        else
        {
            int curLV = mmData != null ? mmData.LV : 0;
            BeautyQualityLVConfig nextLVConfig;
            BeautyQualityLVConfig.TryGetBeautyQualityLVConfig(mmConfig.BeautyQuality, curLV + 1, out nextLVConfig);
            needExp = nextLVConfig.LVNeedExp;
            expText.text = (mmData != null ? mmData.Exp.ToString() : "0") + "/" + needExp;
            process.fillAmount = mmData != null ? mmData.Exp / needExp : 0;
            showAwardCell.SetActive(true);
            int itemID = nextLVConfig.AwardItemList[0][0];
            showAwardCell.Init(new ItemCellModel(itemID, false, nextLVConfig.AwardItemList[0][1]));
            showAwardCell.button.AddListener(() =>
            {
                ItemTipUtility.Show(itemID);
            });
            var awardCnt = mmData != null ? mmData.LV - mmData.AwardLV : 0;
            for (int i = 0; i < awardBtns.Length; i++)
            {
                if (mmData != null && i < awardCnt)
                {
                    awardBtns[i].SetActive(true);
                    awardImgs[i].SetSprite(ItemConfig.Get(itemID).IconKey);
                }
                else
                {
                    awardBtns[i].SetActive(false);
                }
            }
            string format = "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}");
            nextAddAttrText.text = Language.Get("BeautyMM23") + PlayerPropertyConfig.GetFullDescription(nextLVConfig.AttrIDList[0], nextLVConfig.AttrValueList[0], format);
            ShowTalent();
            nextLVTalentTipRect.SetActive(true);
            nextLVTalentTip.text = Language.Get("BeautyMM26", rank * BeautyMMManager.Instance.needLVForTalent);
            giftOPRect.SetActive(true);
            fullRect.SetActive(false);
        }
        CreateScroller();
    }
    // 解锁方式        方式值    所需数
    // 1.物品解锁        碎片物品ID    数量
    // 2.完成主线任务ID    任务ID
    // 3.演武场胜利次数    无    次数
    // 4.拥有监工数量        无    数量
    // 5.白骨盈野过关        funcLineID
    // 6.官职达到        官职ID
    // 7.游历次数        无    次数
    string GetActiveTip(BeautyConfig beauty)
    {
        TextColType colorType = TextColType.Red;
        switch (beauty.UnlockWay)
        {
            case 1:
                var cnt = PackManager.Instance.GetItemCountByID(PackType.Item, beauty.UnlockValue);
                colorType = cnt >= beauty.UnlockNeedCnt ? TextColType.Green : TextColType.Red;
                return UIHelper.AppendColor(colorType, Language.Get("BeautyMMUnLockTip1", ItemConfig.Get(beauty.UnlockValue).IconKey, cnt, beauty.UnlockNeedCnt));
            case 2:
                colorType = TaskConfig.Get(TaskManager.Instance.mainTask.TaskID).Index > TaskConfig.Get(beauty.UnlockValue).Index ? TextColType.Green : TextColType.Red;
                return Language.Get("BeautyMMUnLockTip2", TaskConfig.Get(beauty.UnlockValue).Index) +
                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", TaskConfig.Get(TaskManager.Instance.mainTask.TaskID).Index, TaskConfig.Get(beauty.UnlockValue).Index));
            case 3:
                colorType = ArenaManager.Instance.totalWinCnt >= beauty.UnlockNeedCnt ? TextColType.Green : TextColType.Red;
                return Language.Get("BeautyMMUnLockTip3", beauty.UnlockNeedCnt) +
                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", ArenaManager.Instance.totalWinCnt, beauty.UnlockNeedCnt));
            case 4:
                colorType = GoldRushManager.Instance.maxWorkerCount >= beauty.UnlockNeedCnt ? TextColType.Green : TextColType.Red;
                return Language.Get("BeautyMMUnLockTip4", beauty.UnlockNeedCnt) +
                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", GoldRushManager.Instance.maxWorkerCount, beauty.UnlockNeedCnt));
            case 5:
                int dataMapID = BoneFieldManager.Instance.DataMapID;
                if (DungeonManager.Instance.TryGetFBInfoByMapID(dataMapID, out var fbInfo))
                {
                    colorType = fbInfo.PassLineID > beauty.UnlockValue ? TextColType.Green : TextColType.Red;
                    return Language.Get("BeautyMMUnLockTip5", beauty.UnlockValue) +
                    UIHelper.AppendColor(colorType, Language.Get("HeroFates11", fbInfo.PassLineID, beauty.UnlockValue));
                }
                return "";
            case 6:
                colorType = PlayerDatas.Instance.baseData.realmLevel >= beauty.UnlockValue ? TextColType.Green : TextColType.Red;
                var config = RealmConfig.Get(beauty.UnlockValue);
                return Language.Get("BeautyMMUnLockTip6", config.Name) +
                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", PlayerDatas.Instance.baseData.realmLevel, beauty.UnlockValue));
            case 7:
                colorType = BeautyMMManager.Instance.m_TravelCnt >= beauty.UnlockNeedCnt ? TextColType.Green : TextColType.Red;
                return Language.Get("BeautyMMUnLockTip7", beauty.UnlockNeedCnt) +
                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", BeautyMMManager.Instance.m_TravelCnt, beauty.UnlockNeedCnt));
        }
        return "";
    }
    void ShowTalent()
    {
        //先显示天赋属性,再显示天赋特性
        var attrs = BeautyMMManager.Instance.GetMMTalentAttrForUI(mmID, true);
        int talentIndex = 0;
        if (attrs.IsNullOrEmpty())
        {
            talentIndex = 0;
        }
        else
        {
            foreach (var attr in attrs)
            {
                if (talentIndex < talentTexts.Length)
                {
                    talentTexts[talentIndex].SetActive(true);
                    string format = "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}");
                    talentTexts[talentIndex].text = PlayerPropertyConfig.GetFullDescription(attr.Key, attr.Value, format);
                }
                else
                {
                    break;
                }
                talentIndex++;
            }
        }
        var talentValue = BeautyMMManager.Instance.GetMMTalentEffectForUI(mmID);
        for (int i = talentIndex; i < talentTexts.Length; i++)
        {
            if (i == talentIndex && mmConfig.EffType != 0)
            {
                //天赋效果约定最多一个
                talentTexts[talentIndex].SetActive(true);
                switch (mmConfig.EffType)
                {
                    case 1:
                        talentTexts[i].text = Language.Get($"BeautyMMTalent1", talentValue);
                        break;
                    case 2:
                        talentTexts[i].text = Language.Get($"BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
                        break;
                    case 3:
                        talentTexts[i].text = Language.Get($"BeautyMMTalent3", talentValue);
                        break;
                    case 4:
                        talentTexts[i].text = Language.Get($"BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
                        break;
                }
            }
            else
            {
                talentTexts[i].SetActive(false);
            }
        }
    }
    void ActiveMM()
    {
        var state = BeautyMMManager.Instance.GetMMBaseState(mmConfig);
        if (state <= 1)
        {
            SysNotifyMgr.Instance.ShowTip("BeautyMM1");
            return;
        }
        var pack = new CB219_tagCSBeautyActivate();
        pack.BeautyID = (ushort)mmID;
        GameNetSystem.Instance.SendInfo(pack);
    }
    void CreateScroller()
    {
        loveScroller.Refresh();
        itemlist = BeautyMMManager.Instance.loveItemIDs.ToList();
        BeautyMMManager.Instance.selectLoveItemID = itemlist[0];
        if (mmConfig.ExclusiveItemID > 0)
        {
            itemlist.Add(mmConfig.ExclusiveItemID);    //专属信物
        }
        for (int i = 0; i < itemlist.Count; i++)
        {
            loveScroller.AddCell(ScrollerDataType.Header, itemlist[i]);
        }
        loveScroller.Restart();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell.GetComponent<ItemCell>();
        int itemID = cell.index;
        var cnt = PackManager.Instance.GetItemCountByID(PackType.Item, itemID);
        _cell.Init(new ItemCellModel(itemID, false, cnt));
        _cell.button.AddListener(() =>
        {
            if (BeautyMMManager.Instance.selectLoveItemID != itemID)
            {
                BeautyMMManager.Instance.selectLoveItemID = itemID;
                loveScroller.m_Scorller.RefreshActiveCellViews();
            }
            else
            {
                ItemTipUtility.Show(itemID);
            }
        });
        if (BeautyMMManager.Instance.selectLoveItemID == itemID)
        {
            _cell.FindComponent("Image", "selectImage").SetActive(true);
        }
        else
        {
            _cell.FindComponent("Image", "selectImage").SetActive(false);
        }
        _cell.FindComponent("Image", "mask").SetActive(cnt == 0);
    }
    void SendGift()
    {
        var cnt = PackManager.Instance.GetItemCountByID(PackType.Item, BeautyMMManager.Instance.selectLoveItemID);
        if (cnt == 0)
        {
            ItemTipUtility.Show(BeautyMMManager.Instance.selectLoveItemID, true);
            return;
        }
        //使用到可升级的数量,或者总数
        var mmData = BeautyMMManager.Instance.GetBeautyMMData(mmID);
        var maxLV = BeautyQualityLVConfig.GetBeautyQualityMaxLV(mmConfig.BeautyQuality);
        bool isMaxLV = mmData != null && mmData.LV >= maxLV;
        if (isMaxLV)
        {
            return;
        }
        else
        {
            int curLV = mmData != null ? mmData.LV : 0;
            BeautyQualityLVConfig nextLVConfig;
            BeautyQualityLVConfig.TryGetBeautyQualityLVConfig(mmConfig.BeautyQuality, curLV + 1, out nextLVConfig);
            int needExp = nextLVConfig.LVNeedExp - mmData.Exp;
            int value = BeautyMMManager.Instance.giftIDToLoveDict.ContainsKey(BeautyMMManager.Instance.selectLoveItemID) ?
                BeautyMMManager.Instance.giftIDToLoveDict[BeautyMMManager.Instance.selectLoveItemID] : BeautyMMManager.Instance.specialGiftLove;
            int useCnt = (int)Mathf.Min(Mathf.CeilToInt(needExp * 1.0f / value), cnt);
            var pack = new CB220_tagCSBeautyLVUP();
            pack.BeautyID = (ushort)mmID;
            pack.ItemID = (uint)BeautyMMManager.Instance.selectLoveItemID;
            pack.IsQuick = (byte)(onekeyToggle.isOn ? 1 : 0);
            GameNetSystem.Instance.SendInfo(pack);
            roleUPEffect.Play();
            SysNotifyMgr.Instance.ShowTip("BeautyMM2", mmConfig.Name, useCnt * value);
        }
    }
}
Main/System/BeautyMM/BeautyMMShowWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 51e44717165ef6d4d945d1dfad6a83a6
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMTravelCell.cs
New file
@@ -0,0 +1,148 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMTravelCell : MonoBehaviour
{
    [SerializeField] Button clickGirdBtn; //根据状态决定
    [SerializeField] Image itemImage;
    [SerializeField] Text multiText;
    [SerializeField] Image horseImg;
    [SerializeField] Image notOpenImg;
    [SerializeField] Image crackImg;    // 破碎图标
    [SerializeField] UIEffectPlayer openEffect;
    [SerializeField] UIEffectPlayer boomEffect;
    [SerializeField] UIEffectPlayer gateEffect;
    public void Display(int index)
    {
        Int2 girdPos = BeautyMMManager.Instance.ChangeIndexToGrid(index);
        var grid = BeautyMMManager.Instance.GetGrid(girdPos);
        clickGirdBtn.AddListener(() =>
        {
            ClickGird(girdPos, grid);
        });
        if (grid == null)
        {
            notOpenImg.SetActive(true);
            itemImage.SetActive(false);
            horseImg.SetActive(false);
            crackImg.SetActive(false);
            gateEffect.SetActive(false);
            return;
        }
        ////状态:0-未点击;1-已开启;2-裂纹
        if (grid.State == 0 || grid.State == 2)
        {
            notOpenImg.SetActive(true);
            itemImage.SetActive(false);
            horseImg.SetActive(false);
            crackImg.SetActive(grid.State == 2);
            gateEffect.SetActive(false);
            return;
        }
        notOpenImg.SetActive(false);
        // 99            -    代表该格是 传送门
        // 100          -    代表该格是 空格子
        // 101          -    代表该格是 马匹
        // 大于200 对应表里的 物品
        if (grid.EventID == 99)
        {
            gateEffect.SetActive(true);
            gateEffect.Play();
            itemImage.SetActive(false);
            horseImg.SetActive(false);
            crackImg.SetActive(false);
        }
        else if (grid.EventID == 100)
        {
            itemImage.SetActive(false);
            horseImg.SetActive(false);
            crackImg.SetActive(false);
            gateEffect.SetActive(false);
        }
        else if (grid.EventID == 101)
        {
            itemImage.SetActive(false);
            horseImg.SetActive(true);
            crackImg.SetActive(false);
            gateEffect.SetActive(false);
        }
        else if (grid.EventID > 200)
        {
            itemImage.SetActive(true);
            horseImg.SetActive(false);
            crackImg.SetActive(false);
            gateEffect.SetActive(false);
            itemImage.SetItemSprite(TravelEventConfig.Get(grid.EventID).AwardItemID);
            if (grid.Multi > 1)
            {
                multiText.text = $"x{grid.Multi}";
            }
            else
            {
                multiText.text = "";
            }
        }
        else
        {
            itemImage.SetActive(false);
            horseImg.SetActive(false);
            crackImg.SetActive(false);
            gateEffect.SetActive(false);
        }
        if (BeautyMMManager.Instance.openChangeGridList.Contains(girdPos))
        {
            openEffect.Play();
        }
    }
    // 99            -    代表该格是 传送门
    // 100          -    代表该格是 空格子
    // 101          -    代表该格是 马匹
    // 大于200 对应表里的 物品
    void ClickGird(Int2 girdPos, TravelGrid grid)
    {
        ////状态:0-未点击;1-已开启;2-裂纹
        if (grid.State == 0 || grid.State == 2)
        {
            SoundPlayer.Instance.PlayUIAudio(25);
        }
        if (grid.EventID == 100)
        {
            // 空格子
            return;
        }
        if (grid.EventID < 99 && grid.EventID > 0)
        {
            //判断建筑是否都开全了没
            if (!BeautyMMManager.Instance.CanOpenBuild())
            {
                SysNotifyMgr.Instance.ShowTip("BeautyMM3");
                return;
            }
        }
        if (grid.EventID == 101)
        {
            boomEffect.Play();
        }
        var pack = new CB040_tagCSTravelClick();
        pack.Row = (byte)girdPos.x;
        pack.Col = (byte)girdPos.y;
        GameNetSystem.Instance.SendInfo(pack);
        BeautyMMManager.Instance.clickGirdPos = girdPos;
    }
}
Main/System/BeautyMM/BeautyMMTravelCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71e82a96c3e36af4f97b52bcebc58d36
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BeautyMM/BeautyMMTravelWin.cs
New file
@@ -0,0 +1,202 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class BeautyMMTravelWin : UIBase
{
    [SerializeField] Button rateTipBtn;
    [SerializeField] Transform rateTipRect;
    [SerializeField] Text[] rateNameText;
    [SerializeField] Text[] rateText;
    [SerializeField] Text horseRateText;
    [SerializeField] Image[] buildImgs;
    [SerializeField] GameObject girdsGo;
    [SerializeField] UIEffectPlayer boomRowEffect;
    [SerializeField] UIEffectPlayer boomColEffect;
    [SerializeField] Image processImg;
    [SerializeField] Text processText;
    [SerializeField] Text timeText;
    List<BeautyMMTravelCell> girds;
    [SerializeField] Button buildResultBtn;
    [SerializeField] UIEffectPlayer buildResultEffect;
    [SerializeField] Image[] whatImgs;
    [SerializeField] Image[] rightImgs;
    [SerializeField] Image[] wrongImgs;
    float gridWidth = 0;
    float gridHeight = 0;
    protected override void InitComponent()
    {
        girds = girdsGo.GetComponentsInChildren<BeautyMMTravelCell>().ToList();
        rateTipBtn.AddListener(() =>
        {
            rateTipRect.SetActive(true);
        });
        DisplyRate();
        buildResultBtn.AddListener(BuildLVUP);
    }
    protected override void OnPreOpen()
    {
        BeautyMMManager.Instance.OnTravelInfoUpdate += OnTravelInfoUpdate;
        BeautyMMManager.Instance.openChangeGridList.Clear();
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        rateTipRect.SetActive(false);
        Display();
        DisplayBuildResult();
    }
    protected override void OnPreClose()
    {
        BeautyMMManager.Instance.OnTravelInfoUpdate -= OnTravelInfoUpdate;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
    }
    void OnTravelInfoUpdate(int result)
    {
        //后端处理:0-无;1-常规;2-马车炸弹;3-传送门;4-景观;5-重置开始
        Display();
        if (result == 2)
        {
            //BeautyMMManager.Instance.clickGirdPos
            boomRowEffect.transform.localPosition = new Vector3(0,
            -((BeautyMMManager.Instance.clickGirdPos.x - 1) * gridHeight + gridHeight / 2), 0);
            boomRowEffect.Play();
            boomColEffect.transform.localPosition = new Vector3((BeautyMMManager.Instance.clickGirdPos.y - 1) * gridWidth + gridWidth / 2, boomColEffect.transform.localPosition.y, 0);
            boomColEffect.Play();
        }
        DisplayBuildResult();
    }
    void Display()
    {
        for (int i = 0; i < girds.Count; i++)
        {
            girds[i].Display(i);
        }
        var showIndex = -1;
        if (BeautyMMManager.Instance.m_SceneryType == 1)
        {
            showIndex = 0;
        }
        else if (BeautyMMManager.Instance.m_SceneryType == 4)
        {
            showIndex = 1;
        }
        else if (BeautyMMManager.Instance.m_SceneryType == 6)
        {
            showIndex = 2;
        }
        var hasDoor = BeautyMMManager.Instance.HasDoor();
        for (int i = 0; i < buildImgs.Length; i++)
        {
            if (i == showIndex && !hasDoor)
            {
                buildImgs[i].SetActive(true);
                //根据父组件的宽高,和格子坐标计算起点坐标
                if (gridWidth == 0 || gridHeight == 0)
                {
                    var parentRect = buildImgs[i].transform.parent.GetComponent<RectTransform>();
                    var parentWidth = parentRect.rect.width;
                    var parentHeight = parentRect.rect.height;
                    gridWidth = parentWidth / BeautyMMManager.Instance.travelRowCol[1];
                    gridHeight = parentHeight / BeautyMMManager.Instance.travelRowCol[0];
                }
                var x = (BeautyMMManager.Instance.m_SceneryCol - 1) * gridWidth + 2;
                var y = (BeautyMMManager.Instance.m_SceneryRow - 1) * gridHeight + 2;
                buildImgs[i].transform.localPosition = new Vector3(x, -y, 0);
            }
            else
            {
                buildImgs[i].SetActive(false);
            }
        }
    }
    void DisplyRate()
    {
        rateTipRect.SetActive(false);
        var keys = TravelEventConfig.GetKeys();
        var index = 0;
        for (int i = 0; i < keys.Count; i++)
        {
            var config = TravelEventConfig.Get(keys[i]);
            if (config.EventID < 200)
            {
                continue;
            }
            rateNameText[index].text = ItemConfig.Get(config.AwardItemID).ItemName + "x" + config.AwardItemCnt;
            rateText[index].text = config.ShowRate;
            index++;
        }
        horseRateText.text = TravelEventConfig.Get(101).ShowRate;
    }
    //建筑特效品质 1-1073 2-1078 3-1083
    Dictionary<int, int> buildEffectDic = new Dictionary<int, int>()
    {
        {1, 1073},
        {2, 1078},
        {3, 1083}
    };
    void DisplayBuildResult()
    {
        if (!IsShowBuildUpgradeUI())
        {
            buildResultBtn.SetActive(false);
            return;
        }
        buildResultBtn.SetActive(true);
    }
    void BuildLVUP()
    {
        var pack = new CB041_tagCSTravelSceneryUP();
        GameNetSystem.Instance.SendInfo(pack);
    }
    //是否显示建筑升级UI
    bool IsShowBuildUpgradeUI()
    {
        //重登后 m_Result 是0 ,依然要遍历判断
        //如果已经有门了
        if (BeautyMMManager.Instance.HasDoor())
        {
            return false;
        }
        //m_Result 只用于即时判断
        if (BeautyMMManager.Instance.m_SceneryLVInfo == 0 && BeautyMMManager.Instance.m_Result != 4)
        {
            return false;
        }
        return true;
    }
    void OnCloseWindow(UIBase ui)
    {
        if (ui is CommonGetItemWin)
        {
            var gird = BeautyMMManager.Instance.GetGrid(BeautyMMManager.Instance.clickGirdPos);
            if (gird != null && gird.EventID == (int)GirdEventType.Door)
            {
                //默认请求下一局
                var pack = new CB040_tagCSTravelClick();
                pack.Row = (byte)BeautyMMManager.Instance.clickGirdPos.x;
                pack.Col = (byte)BeautyMMManager.Instance.clickGirdPos.y;
                GameNetSystem.Instance.SendInfo(pack);
            }
        }
    }
}
Main/System/BeautyMM/BeautyMMTravelWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35624c157a4b5364f902d10f570bef5a
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/BoneField/AdsManager.cs
@@ -52,6 +52,7 @@
                SendGetReward(ADID);
                break;
            case 4:
            case 6:
                SendGetReward(ADID);
                break;
        }
Main/System/Equip/EquipModel.cs
@@ -186,18 +186,29 @@
        }
    }
    bool needMoreDrop = false; //由于掉落挤压导致,满掉落掉落背包的时候处理后再主动请求掉落
    //处理所有掉落的物品
    public void CalcAllFloorItems()
    {
        if (PackManager.Instance.GetSinglePack(PackType.DropItem).GetItems().Count == 0)
        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;
        }
    }
@@ -279,8 +290,11 @@
        // NoteFloorEquip(itemIndexList, opType);
        var pack = new CB415_tagCSMainDropItemOP();
        pack.Count = (byte)itemIndexList.Length;
        pack.IndexList = itemIndexList;
        if (itemIndexList != null)
        {
            pack.Count = (byte)itemIndexList.Length;
            pack.IndexList = itemIndexList;
        }
        pack.OPType = opType;
        pack.OPValue = (byte)(autoDecompose ? 1 : 0); // 替换后是否自动分解原装备:0否1是
@@ -291,6 +305,7 @@
            Debug.LogWarning("穿戴装备,向服务器请求");
        }
        GameNetSystem.Instance.SendInfo(pack);
    }
    /// <summary>
Main/System/InternalAffairs/AffairFuncCell.cs
@@ -47,6 +47,10 @@
        {
            UIManager.Instance.OpenWindow<PhantasmPavilionWin>();
        }
        else if (funcID == 7)
        {
            UIManager.Instance.OpenWindow<BeautyMMBaseWin>();
        }
    }
Main/System/KnapSack/PackManager.cs
@@ -412,6 +412,11 @@
        if (serverItem.socketType == ServerType.Main && serverItem.PackType == (int)PackType.DropItem)
        {
            EquipModel.Instance.CalcFloorEquip(serverItem.ItemPlace);
            if (serverItem.ItemPlace == 19)
            {
                //再快速处理一次
                EquipModel.Instance.SendEquipOP(null, 3);
            }
        }
    }
Main/System/Redpoint/MainRedDot.cs
@@ -76,7 +76,8 @@
    Redpoint osGalaRedpoint = new Redpoint(RedPoint_OSGala);
    public const int RedPoint_Download = 116;
    //红颜
    public const int Redpoint_BeautyMM = 117;
    //武将卡
    public const int HeroCardRedpoint = 200;
    public Redpoint HeroListRedpoint = new Redpoint(MainHerosRedpoint, HeroCardRedpoint);
Main/Utility/EnumHelper.cs
@@ -823,6 +823,7 @@
    Hero = 1,//武将
    Challenge = 2,//挑战
    Official = 3,//内政
    BeautyMM = 7,//红颜
    GoldRush = 8, //淘金
    Realm = 10, //境界 官职
    Guild = 11,// 公会