Main/Config/ConfigManager.cs
@@ -54,6 +54,8 @@ typeof(GoldRushCampConfig), typeof(GoldRushItemConfig), typeof(GoldRushWorkerConfig), typeof(HeroFatesConfig), typeof(HeroFatesQualityLVConfig), typeof(HeroLineupHaloConfig), typeof(HeroQualityLVConfig), typeof(HorseClassConfig), @@ -266,6 +268,10 @@ ClearConfigDictionary<GoldRushItemConfig>(); // 清空 GoldRushWorkerConfig 字典 ClearConfigDictionary<GoldRushWorkerConfig>(); // 清空 HeroFatesConfig 字典 ClearConfigDictionary<HeroFatesConfig>(); // 清空 HeroFatesQualityLVConfig 字典 ClearConfigDictionary<HeroFatesQualityLVConfig>(); // 清空 HeroLineupHaloConfig 字典 ClearConfigDictionary<HeroLineupHaloConfig>(); // 清空 HeroQualityLVConfig 字典 Main/Config/Configs/HeroFatesConfig.cs
New file @@ -0,0 +1,92 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2025年12月10日 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class HeroFatesConfig : ConfigBase<int, HeroFatesConfig> { static HeroFatesConfig() { // 访问过静态构造函数 visit = true; } public int FatesID; public string FatesName; public int FatesQuality; public int[] HeroIDList; public int[][] AwardItemList; public int[] AttrIDList; public int[] LVAttrValueList; 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 FatesID); FatesName = tables[1]; int.TryParse(tables[2],out FatesQuality); if (tables[3].Contains("[")) { HeroIDList = JsonMapper.ToObject<int[]>(tables[3]); } else { string[] HeroIDListStringArray = tables[3].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); HeroIDList = new int[HeroIDListStringArray.Length]; for (int i=0;i<HeroIDListStringArray.Length;i++) { int.TryParse(HeroIDListStringArray[i],out HeroIDList[i]); } } AwardItemList = JsonMapper.ToObject<int[][]>(tables[4].Replace("(", "[").Replace(")", "]")); if (tables[5].Contains("[")) { AttrIDList = JsonMapper.ToObject<int[]>(tables[5]); } else { string[] AttrIDListStringArray = tables[5].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[6].Contains("[")) { LVAttrValueList = JsonMapper.ToObject<int[]>(tables[6]); } else { string[] LVAttrValueListStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); LVAttrValueList = new int[LVAttrValueListStringArray.Length]; for (int i=0;i<LVAttrValueListStringArray.Length;i++) { int.TryParse(LVAttrValueListStringArray[i],out LVAttrValueList[i]); } } } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/HeroFatesConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: de1bf25d84fa4414a9c579dfa3b636fc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/Configs/HeroFatesQualityLVConfig.cs
New file @@ -0,0 +1,50 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2025年12月10日 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class HeroFatesQualityLVConfig : ConfigBase<int, HeroFatesQualityLVConfig> { static HeroFatesQualityLVConfig() { // 访问过静态构造函数 visit = true; } public int Id; public int FatesQuality; public int FatesLV; public int NeedStarTotal; public int NeedHeroCnt; 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 FatesQuality); int.TryParse(tables[2],out FatesLV); int.TryParse(tables[3],out NeedStarTotal); int.TryParse(tables[4],out NeedHeroCnt); } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/HeroFatesQualityLVConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 04ded98ba28951c4db9c8281c43ae86b MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/PartialConfigs/HeroFatesQualityLVConfig.cs
New file @@ -0,0 +1,35 @@ using System.Collections.Generic; public partial class HeroFatesQualityLVConfig : ConfigBase<int, HeroFatesQualityLVConfig> { // <宿缘品质,<宿缘等级,唯一ID> static Dictionary<int, Dictionary<int, int>> idDict = new Dictionary<int, Dictionary<int, int>>(); protected override void OnConfigParseCompleted() { if (!idDict.ContainsKey(FatesQuality)) { idDict[FatesQuality] = new Dictionary<int, int>(); } idDict[FatesQuality][FatesLV] = Id; } public static bool TryGetDictByFatesQuality(int fatesQuality, out Dictionary<int, int> dict) { return idDict.TryGetValue(fatesQuality, out dict); } public static bool TryGetId(int fatesQuality, int fatesLV, out int id) { id = 0; return idDict.TryGetValue(fatesQuality, out var dict) && dict.TryGetValue(fatesLV, out id); } public static bool TryGetHeroFatesQualityLVConfig(int fatesQuality, int fatesLV, out HeroFatesQualityLVConfig config) { config = null; if (!TryGetId(fatesQuality, fatesLV, out int id) || !HasKey(id)) return false; config = Get(id); return true; } } Main/Config/PartialConfigs/HeroFatesQualityLVConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 892ed1407bdeb8a42b61f323ff60f3a6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB241_tagCSHeroFates.cs
New file @@ -0,0 +1,24 @@ using UnityEngine; using System.Collections; // B2 41 武将宿缘 #tagCSHeroFates public class CB241_tagCSHeroFates : GameNetPackBasic { public byte FatesID; // 宿缘ID public byte OPType; // 0-激活领奖;1-升级 public byte IndexCnt; public ushort[] ItemIndexList; // 升级时消耗的材料卡在武将背包索引列表,升级时才发 public CB241_tagCSHeroFates () { combineCmd = (ushort)0x03FE; _cmd = (ushort)0xB241; } public override void WriteToBytes () { WriteBytes (FatesID, NetDataType.BYTE); WriteBytes (OPType, NetDataType.BYTE); WriteBytes (IndexCnt, NetDataType.BYTE); WriteBytes (ItemIndexList, NetDataType.WORD, IndexCnt); } } Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB241_tagCSHeroFates.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 109782f5f047e6b40aa4acf5bee3caa3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB131_tagSCHeroFatesInfo.cs
New file @@ -0,0 +1,12 @@ using UnityEngine; using System.Collections; // B1 31 宿缘信息 #tagSCHeroFatesInfo public class DTCB131_tagSCHeroFatesInfo : DtcBasic { public override void Done(GameNetPackBasic vNetPack) { base.Done(vNetPack); HB131_tagSCHeroFatesInfo vNetData = vNetPack as HB131_tagSCHeroFatesInfo; HeroFatesManager.Instance.OnUpdateHeroFatesInfo(vNetData); } } Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB131_tagSCHeroFatesInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f32287c05ce489141b839fa73fb39327 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -135,6 +135,7 @@ Register(typeof(HA319_tagMCPackDownloadRecord), typeof(DTCA319_tagMCPackDownloadRecord)); Register(typeof(HB129_tagSCLineupRecommendInfo), typeof(DTCB129_tagSCLineupRecommendInfo)); Register(typeof(HAB05_tagSCOSACelebrationInfo), typeof(DTCAB05_tagSCOSACelebrationInfo)); Register(typeof(HB131_tagSCHeroFatesInfo), typeof(DTCB131_tagSCHeroFatesInfo)); } //主工程注册封包 Main/Core/NetworkPackage/ServerPack/HB1_Role/HB131_tagSCHeroFatesInfo.cs
New file @@ -0,0 +1,31 @@ using UnityEngine; using System.Collections; // B1 31 宿缘信息 #tagSCHeroFatesInfo public class HB131_tagSCHeroFatesInfo : GameNetPackBasic { public byte Count; public tagSCHeroFates[] FatesList; public HB131_tagSCHeroFatesInfo () { _cmd = (ushort)0xB131; } public override void ReadFromBytes (byte[] vBytes) { TransBytes (out Count, vBytes, NetDataType.BYTE); FatesList = new tagSCHeroFates[Count]; for (int i = 0; i < Count; i ++) { FatesList[i] = new tagSCHeroFates(); TransBytes (out FatesList[i].FatesID, vBytes, NetDataType.BYTE); TransBytes (out FatesList[i].State, vBytes, NetDataType.BYTE); TransBytes (out FatesList[i].FatesLV, vBytes, NetDataType.BYTE); } } public class tagSCHeroFates { public byte FatesID; // 宿缘ID public byte State; // 宿缘状态:0-未激活;1-已激活已领奖 public byte FatesLV; // 宿缘等级,激活时为0级,升级后有升级属性 } } Main/Core/NetworkPackage/ServerPack/HB1_Role/HB131_tagSCHeroFatesInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f9ee46f7d4246af45a7fcdca58ae94db MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Main.cs
@@ -94,7 +94,7 @@ managers.Add(GuildBossManager.Instance); managers.Add(LineupRecommendManager.Instance); managers.Add(OSActivityManager.Instance); managers.Add(HeroFatesManager.Instance); foreach (var manager in managers) { manager.Init(); Main/System/Hero/UIHeroController.cs
@@ -22,6 +22,7 @@ if (skeletonGraphic != null) { SetMaterialNone(); if (isLh) { var skinConfigTmp = HeroSkinConfig.Get(skinID); @@ -128,6 +129,7 @@ skeletonGraphic.Initialize(true); skeletonGraphic.enabled = true; SetMaterialNone(); spineAnimationState = skeletonGraphic.AnimationState; spineAnimationState.Data.DefaultMix = 0f; if (motionName == "") @@ -158,7 +160,7 @@ /// <param name="motionName">动作名</param> /// <param name="loop">循环</param> /// <param name="replay">如果相同动作是否再次重播,比如跑步重播就会跳帧不顺滑</param> public virtual void PlayAnimation(string motionName, bool loop = false, bool replay=true) public virtual void PlayAnimation(string motionName, bool loop = false, bool replay = true) { if (spineAnimationState == null) return; @@ -214,11 +216,20 @@ } public void SetEnabled(bool isEnable) { { if (skeletonGraphic == null) { return; } skeletonGraphic.enabled = isEnable; } public void SetGray() { skeletonGraphic.material = MaterialUtility.GetDefaultSpriteGrayMaterial(); } public void SetMaterialNone() { skeletonGraphic.material = null; } } Main/System/HeroFates.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 87b403c587f7df14899f863d5427edac folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesCell.cs
New file @@ -0,0 +1,175 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HeroFatesCell : MonoBehaviour { [SerializeField] ImageEx imgBG; [SerializeField] TextEx txtFateName; [SerializeField] OutlineEx outlineFateName; [SerializeField] TextEx txtFateLV; [SerializeField] TextEx txtFateNeedHeroHasCnt; [SerializeField] TextEx txtHasHeroTotalStar; [SerializeField] ItemCell itemCell; [SerializeField] ButtonEx btnHave; [SerializeField] ImageEx imgHave; [SerializeField] Image imgHaveRed; [SerializeField] ButtonEx btnUpgrade; [SerializeField] TextEx txtUpgrade; [SerializeField] ImageEx imgUpgrade; [SerializeField] Image imgUpgradeRed; [SerializeField] HorizontalLayoutGroup horizontalLayoutGroup; [SerializeField] List<HeroFatesIHItem> heroFatesIHItems; int[] spacingArr = new int[5] { 150, 150, 99, 68, 37 }; [SerializeField] Transform transAttr; [SerializeField] List<TextEx> attrs; [SerializeField] Transform transItems; [SerializeField] List<ItemCell> items; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(int index, List<int> showList) { if (showList.IsNullOrEmpty() || index >= showList.Count || index < 0) { return; } int fatesId = showList[index]; if (!manager.TryGetHeroFatesConfig(fatesId, out HeroFatesConfig config) || config.HeroIDList.IsNullOrEmpty()) { return; } HeroFatesState state = manager.GetHeroFatesState(fatesId); bool isNoActive = state == HeroFatesState.Locked || state == HeroFatesState.Activatable; txtFateLV.SetActive(!isNoActive); txtFateNeedHeroHasCnt.SetActive(isNoActive); txtHasHeroTotalStar.SetActive(state == HeroFatesState.ActiveNotUpgradable || state == HeroFatesState.ActiveUpgradable); btnHave.SetActive(isNoActive); btnHave.interactable = state == HeroFatesState.Activatable; imgHave.gray = state == HeroFatesState.Locked; imgHaveRed.SetActive(state == HeroFatesState.Activatable); btnUpgrade.SetActive(!isNoActive); btnUpgrade.interactable = state != HeroFatesState.MaxLevel; imgUpgrade.gray = state == HeroFatesState.MaxLevel; txtUpgrade.text = Language.Get(state == HeroFatesState.MaxLevel ? "L1110" : "L1109"); imgUpgradeRed.SetActive(state == HeroFatesState.ActiveUpgradable); imgBG.SetSprite(manager.GetCellBgByFatesQuality(config.FatesQuality)); txtFateName.text = config.FatesName; txtFateName.color = UIHelper.GetUIColorByFunc(config.FatesQuality); outlineFateName.OutlineColor = UIHelper.GetUIOutlineColor(config.FatesQuality); int needHeroHasCnt = manager.GetFateNeedHeroHasCnt(fatesId); int needHeroCnt = config.HeroIDList.Length; txtFateNeedHeroHasCnt.text = Language.Get("BoneField09", needHeroHasCnt, needHeroCnt); bool hasNowLVAndNextLVConfig = manager.TryGetNowLVAndNextLVConfig(fatesId, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig); if (hasNowLVAndNextLVConfig) { int fatesNowStarCnt = manager.GetFatesNowStarCnt(fatesId); int nextNeedStarCnt = nextLVConfig.NeedStarTotal; txtHasHeroTotalStar.text = StringUtility.Concat(Language.Get("HeroFates05"), UIHelper.AppendColor(nextNeedStarCnt <= fatesNowStarCnt ? TextColType.LightGreen : TextColType.Red, Language.Get("HeroFates11", fatesNowStarCnt, nextNeedStarCnt))); } DisplayLH(config); transAttr.SetActive(!isNoActive); DisplayAttrs(fatesId); transItems.SetActive(!config.AwardItemList.IsNullOrEmpty() && isNoActive); DisplayAwardItems(config); bool hasInfo = manager.TryGetHeroFates(fatesId, out HeroFates info); txtFateLV.text = Language.Get("L1113", hasInfo ? info.FatesLV : 0); btnHave.SetListener(() => manager.SendHeroFates(fatesId, 0)); btnUpgrade.SetListener(() => { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HeroFatesUpgrade, true)) return; manager.chooseHeroFatesId = fatesId; manager.chooseHeroFatesQuality = config.FatesQuality; UIManager.Instance.OpenWindow<HeroFatesUpgradeWin>(); }); } void DisplayLH(HeroFatesConfig config) { if (manager.TryGetNowMaxStarHeroDict(out Dictionary<int, HeroInfo> nowMaxStarHeroDict) || !nowMaxStarHeroDict.IsNullOrEmpty()) { for (int i = 0; i < heroFatesIHItems.Count; i++) { if (i < config.HeroIDList.Length) { int heroID = config.HeroIDList[i]; heroFatesIHItems[i].SetActive(true); heroFatesIHItems[i].Display(config.HeroIDList, i, nowMaxStarHeroDict); } else { heroFatesIHItems[i].SetActive(false); } } int index = Mathf.Max(config.HeroIDList.Length - 1, 0); if (index >= spacingArr.Length) { index = spacingArr.Length - 1; } int spacing = spacingArr[index]; horizontalLayoutGroup.spacing = spacing; } } void DisplayAttrs(int fatesId) { if (attrs.IsNullOrEmpty()) return; bool hasConfig = manager.TryGetAttrIDListAndLVAttrValueList(fatesId, out int[] attrIDList, out int[] lvAttrValueList); if (!hasConfig) return; for (int i = 0; i < attrs.Count; i++) { if (i < attrIDList.Length) { int attrID = attrIDList[i]; int attrValue = manager.GetNowAttrValue(fatesId, i); attrs[i].text = PlayerPropertyConfig.GetFullDescription(attrID, attrValue); attrs[i].SetActive(true); } else { attrs[i].SetActive(false); } } } void DisplayAwardItems(HeroFatesConfig config) { if (items.IsNullOrEmpty() || config.AwardItemList.IsNullOrEmpty()) return; for (int i = 0; i < items.Count; i++) { if (i < config.AwardItemList.Length) { int itemID = config.AwardItemList[i][0]; int count = config.AwardItemList[i][1]; items[i].Init(new ItemCellModel(itemID, false, count)); items[i].button.SetListener(() => ItemTipUtility.Show(itemID)); items[i].SetActive(true); } else { items[i].SetActive(false); } } } } Main/System/HeroFates/HeroFatesCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: a00cea9f743c4124381d8ae7426329d5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesFastPutPreviewCell.cs
New file @@ -0,0 +1,31 @@ using System.Collections.Generic; using UnityEngine; public class HeroFatesFastPutPreviewCell : MonoBehaviour { [SerializeField] List<HeroFatesUpgradeHeadCell> headCells; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(int rowIndex, List<HeroInfo> list) { if (list.IsNullOrEmpty()) { return; } for (int i = 0; i < headCells.Count; i++) { int index = rowIndex * manager.rowCountMax + i; if (index < list.Count) { headCells[i].SetActive(true); headCells[i].Display(list[index]); } else { headCells[i].SetActive(false); } } } } Main/System/HeroFates/HeroFatesFastPutPreviewCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: cb39d470ad837b74fba100a954f52ce7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesFastPutPreviewWin.cs
New file @@ -0,0 +1,65 @@ using System.Collections.Generic; using UnityEngine; public class HeroFatesFastPutPreviewWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx btnClose; [SerializeField] ButtonEx btnOk; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } protected override void InitComponent() { btnClose.SetListener(CloseWindow); btnOk.SetListener(() => { manager.FastAddList(putPreviewHeroList); CloseWindow(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent += OnUpdateHeroFatesInfo; CreateScoller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent -= OnUpdateHeroFatesInfo; } private void OnUpdateHeroFatesInfo() { RefeshScoller(); } List<HeroInfo> putPreviewHeroList = new List<HeroInfo>(); private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroFatesFastPutPreviewCell>(); _cell?.Display(cell.index, putPreviewHeroList); } void CreateScoller() { scroller.Refresh(); putPreviewHeroList = manager.GetPutPreviewHeroList(manager.chooseHeroFatesId); if (!putPreviewHeroList.IsNullOrEmpty()) { int rowCount = Mathf.CeilToInt((float)putPreviewHeroList.Count / manager.rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } scroller.Restart(); } void RefeshScoller() { scroller.m_Scorller.RefreshActiveCellViews(); } } Main/System/HeroFates/HeroFatesFastPutPreviewWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 9641203a901f43a4d9ca3110fa8fec3c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesIHItem.cs
New file @@ -0,0 +1,41 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HeroFatesIHItem : MonoBehaviour { [SerializeField] UIHeroController uiHeroController; [SerializeField] List<Image> starImgList; [SerializeField] ImageEx imgHeroNameBg; [SerializeField] TextEx txtHeroName; [SerializeField] float lhSize = 0.8f; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(int[] heroIDList, int index, Dictionary<int, HeroInfo> nowMaxStarHeroDict) { if (heroIDList.IsNullOrEmpty() || index >= heroIDList.Length || index < 0) return; int heroId = heroIDList[index]; if (!manager.TryGetHeroAndSkinConfigByHeroID(heroId, out HeroConfig heroConfig, out HeroSkinConfig heroSkinConfig)) return; uiHeroController.Create(heroSkinConfig.SkinID, lhSize); bool isHasHero = HeroManager.Instance.HasHero(heroId); if (isHasHero) { uiHeroController.SetMaterialNone(); int starCnt = !nowMaxStarHeroDict.IsNullOrEmpty() && nowMaxStarHeroDict.ContainsKey(heroId) ? nowMaxStarHeroDict[heroId].heroStar : 0; manager.DisplayStars(starImgList, starCnt); } else { uiHeroController.SetGray(); manager.DisplayStars(starImgList, -1); } imgHeroNameBg.SetSprite(manager.GetHeroFatesNameBGByFatesQuality(heroConfig.Quality)); txtHeroName.text = heroConfig.Name; } } Main/System/HeroFates/HeroFatesIHItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 35905f3d0d176724a91c3188027ed5fb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesManager.cs
New file @@ -0,0 +1,732 @@ using System; using System.Collections.Generic; using System.Linq; using UnityEngine.UI; public class HeroFatesManager : GameSystemManager<HeroFatesManager> { public readonly int rowCountMax = 5; public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; HeroUIManager.Instance.OnHeroCollectEvent += OnHeroCollectEvent; HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk; HeroUIManager.Instance.OnHeroCollectEvent -= OnHeroCollectEvent; HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; } private void OnFuncStateChangeEvent(int obj) { if (obj == (int)FuncOpenEnum.Hero || obj == (int)FuncOpenEnum.HeroFatesUpgrade) { UpdateRedpoint(); } } private void OnBeforePlayerDataInitializeEventOnRelogin() { heroFatesInfos.Clear(); } private void OnPlayerLoginOk() { UpdateRedpoint(); RefreshAttr(); } private void OnHeroCollectEvent() { UpdateRedpoint(); } private void OnHeroChangeEvent(HeroInfo info) { UpdateRedpoint(); } List<int> allFatesHeroID = new List<int>(); public List<int> GetAllFatesHeroID() { if (allFatesHeroID.IsNullOrEmpty()) { foreach (var info in HeroFatesConfig.GetValues()) { if (info.HeroIDList.IsNullOrEmpty()) { continue; } foreach (var HeroID in info.HeroIDList) { if (!allFatesHeroID.Contains(HeroID)) { allFatesHeroID.Add(HeroID); } } } } return allFatesHeroID; } Redpoint redpoint = new Redpoint(MainRedDot.MainHerosRedpoint, MainRedDot.HeroFatesRepoint); public void UpdateRedpoint() { redpoint.state = RedPointState.None; //武将没开不刷红点 if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero)) return; bool hasShowRedDotFates = HasShowRedDotFates(out int firstIndex); if (hasShowRedDotFates) { redpoint.state = RedPointState.Simple; } } //<宿缘ID,宿缘信息> public Dictionary<int, HeroFates> heroFatesInfos = new Dictionary<int, HeroFates>(); public bool TryGetHeroFates(int fatesID, out HeroFates info) { return heroFatesInfos.TryGetValue(fatesID, out info); } public event Action OnUpdateHeroFatesInfoEvent; public event Action OnUpgradeHeroFatesEvent; public void OnUpdateHeroFatesInfo(HB131_tagSCHeroFatesInfo vNetData) { if (vNetData == null || vNetData.FatesList.IsNullOrEmpty()) { return; } bool isUpgrade = false; foreach (var vInfo in vNetData.FatesList) { if (!heroFatesInfos.ContainsKey(vInfo.FatesID)) { heroFatesInfos[vInfo.FatesID] = new HeroFates(); } heroFatesInfos[vInfo.FatesID].FatesID = vInfo.FatesID; heroFatesInfos[vInfo.FatesID].State = vInfo.State; if (heroFatesInfos[vInfo.FatesID].FatesLV != vInfo.FatesLV) { isUpgrade = true; } heroFatesInfos[vInfo.FatesID].FatesLV = vInfo.FatesLV; } RefreshAttr(); UpdateRedpoint(); OnUpdateHeroFatesInfoEvent?.Invoke(); if (isUpgrade) { OnUpgradeHeroFatesEvent?.Invoke(); } } public ushort[] GetItemIndexList(List<HeroInfo> heroInfos) { return heroInfos.Select(heroInfo => (ushort)heroInfo.itemHero.gridIndex).ToArray(); } public void SendHeroFates(int fatesID, int opType, ushort[] itemIndexList = null) { CB241_tagCSHeroFates pack = new CB241_tagCSHeroFates(); pack.FatesID = (byte)fatesID; // 宿缘ID pack.OPType = (byte)opType; // 0-激活领奖;1-升级 // 升级时消耗的材料卡在武将背包索引列表,升级时才发 bool isNullOrEmpty = itemIndexList.IsNullOrEmpty(); pack.ItemIndexList = isNullOrEmpty ? null : itemIndexList; pack.IndexCnt = isNullOrEmpty ? (byte)0 : (byte)itemIndexList.Length; GameNetSystem.Instance.SendInfo(pack); } public HeroFatesState GetHeroFatesState(int fatesID) { //没有封包 if (!TryGetHeroFates(fatesID, out HeroFates info)) { return IsHeroIDListAllActive(fatesID) ? HeroFatesState.Activatable : HeroFatesState.Locked; } // 封包宿缘状态:0-未激活;1-已激活已领奖 if (info.State == 0) { //武将ID组合列表中的武将的图鉴有没解锁的?- 未解锁 return IsHeroIDListAllActive(fatesID) ? HeroFatesState.Activatable : HeroFatesState.Locked; } else if (info.State == 1) { // 宿缘升级功能没开时视为不可升级 if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HeroFatesUpgrade)) { return HeroFatesState.ActiveNotUpgradable; } if (IsHeroFatesStarMax(fatesID)) { return HeroFatesState.MaxLevel; } return IsHeroFatesCanUp(fatesID, out int fromFatesLv, out int toFatesLv) ? HeroFatesState.ActiveUpgradable : HeroFatesState.ActiveNotUpgradable; } return HeroFatesState.Locked; } public bool IsHeroFatesCanUp(int fatesID, out int fromFatesLv, out int toFatesLv) { fromFatesLv = 0; toFatesLv = 0; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) { return false; } if (!TryGetHeroFates(fatesID, out HeroFates info)) { return false; } fromFatesLv = info.FatesLV; toFatesLv = info.FatesLV + 1; int fatesQuality = config.FatesQuality; if (!HeroFatesQualityLVConfig.TryGetHeroFatesQualityLVConfig(fatesQuality, toFatesLv, out HeroFatesQualityLVConfig heroFatesQualityLVConfig)) { return false; } // 武将总星级是否满足升级需求 int needStarCnt = heroFatesQualityLVConfig.NeedStarTotal; int hasStarCnt = GetFatesNowStarCnt(fatesID); if (hasStarCnt < needStarCnt) { return false; } // 消耗武将数量是否满足需求 List<HeroInfo> consumableHeroInfos = GetConsumableHeroInfoList(heroFatesQualityLVConfig.FatesQuality); int hasHeroCnt = consumableHeroInfos == null ? 0 : consumableHeroInfos.Count; int needHeroCnt = heroFatesQualityLVConfig.NeedHeroCnt; if (hasHeroCnt < needHeroCnt) { return false; } return true; } // 获得背包中的所有指定品质的可消耗武将 宿缘品质就是武将品质 public List<HeroInfo> GetConsumableHeroInfoList(int fatesQuality) { List<HeroInfo> result = new List<HeroInfo>(); List<HeroInfo> allHeroesInBag = HeroManager.Instance.GetHeroList(); foreach (var item in allHeroesInBag) { if (item == null) continue; //不是所需品质 if (item.Quality != fatesQuality) continue; // 生效中的武将 if (item.isAttrActive) continue; // 在任何阵容中上阵 bool isInAnyTeam = item.IsInAnyTeam(); if (isInAnyTeam) continue; // 锁定中 if (item.isLock) continue; // 升级过 if (item.heroLevel > 1) continue; // 生星过 if (item.heroStar > 0) continue; // 觉醒过 if (item.awakeLevel > 0) continue; result.Add(item); } result.Sort((a, b) => a.heroId.CompareTo(b.heroId)); return result; } // 当前宿缘的当前最高总星级是否已满级 public bool IsHeroFatesStarMax(int fatesID) { if (!TryGetHeroFates(fatesID, out HeroFates info)) return false; if (!TryGetMaxFatesLVConfigByFatesID(fatesID, out HeroFatesQualityLVConfig heroFatesQualityLVConfig)) return false; int maxLv = heroFatesQualityLVConfig.FatesLV; int nowLv = info.FatesLV; return nowLv >= maxLv; } // 武将ID组合列表中的武将的图鉴都解锁了? public bool IsHeroIDListAllActive(int fatesID) { if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config) || config.HeroIDList.IsNullOrEmpty()) return false; int activeHeroCnt = GetFateNeedHeroHasCnt(fatesID); return config.HeroIDList.Length <= activeHeroCnt; } public int GetFateNeedHeroHasCnt(int fatesID) { int res = 0; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config) || config.HeroIDList.IsNullOrEmpty()) return 0; foreach (var heroID in config.HeroIDList) { if (!TryGetHeroConfig(heroID, out HeroConfig heroConfig)) continue; // heroBookState: 0未获得、1可激活、2常规、3突破升级、4星升级、5已满级 int heroBookState = HeroUIManager.Instance.GetHeroBookState(heroID, heroConfig.Quality); if (heroBookState > 0) res += 1; } return res; } public bool TryGetNowMaxStarHeroDict(out Dictionary<int, HeroInfo> nowMaxStarHeroDict) { nowMaxStarHeroDict = new Dictionary<int, HeroInfo>(); List<HeroInfo> allHeroesInBag = HeroManager.Instance.GetHeroList(); if (allHeroesInBag.IsNullOrEmpty()) return false; foreach (var item in allHeroesInBag) { if (item == null) continue; if (!nowMaxStarHeroDict.TryGetValue(item.heroId, out HeroInfo heroInfo)) { nowMaxStarHeroDict[item.heroId] = item; } else { if (item.heroStar > heroInfo.heroStar) nowMaxStarHeroDict[item.heroId] = item; } } return true; } public Dictionary<int, HeroInfo> GetFatesNowStarHeroInfoDict(int fatesID) { if (!IsHeroIDListAllActive(fatesID)) return null; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config) || config.HeroIDList.IsNullOrEmpty()) return null; if (!TryGetNowMaxStarHeroDict(out Dictionary<int, HeroInfo> nowMaxStarHeroDict) || nowMaxStarHeroDict.IsNullOrEmpty()) return null; Dictionary<int, HeroInfo> heroInfoDict = new Dictionary<int, HeroInfo>(); foreach (var heroID in config.HeroIDList) { if (nowMaxStarHeroDict.ContainsKey(heroID)) { heroInfoDict[heroID] = nowMaxStarHeroDict[heroID]; } } return heroInfoDict; } // 获取当前宿缘的当前最高总星级 public int GetFatesNowStarCnt(int fatesID) { Dictionary<int, HeroInfo> dict = GetFatesNowStarHeroInfoDict(fatesID); if (dict.IsNullOrEmpty()) return 0; // 遍历宿缘配置中所需的武将ID,从maxStarsInBag中获取最高星级并累加 int res = 0; foreach (var item in dict.Values) { res += item.heroStar; } return res; } public void DisplayStars(List<Image> starImgList, int starCnt) { for (int i = 0; i < starImgList.Count; i++) { //不显示星级 if (starCnt == -1) { starImgList[i].SetActive(false); } else if (starCnt == 0 && i == 0) { // 无星级 特殊处理 starImgList[i].SetActive(true); starImgList[i].SetSprite("herostar" + starCnt); } else if ((starCnt - 1) % starImgList.Count >= i) { starImgList[i].SetActive(true); starImgList[i].SetSprite("herostar" + (((starCnt - 1) / starImgList.Count) + 1) * starImgList.Count); } else { starImgList[i].SetActive(false); } } } public bool IsShowRedDot(int fatesID) { HeroFatesState state = GetHeroFatesState(fatesID); return state == HeroFatesState.Activatable || state == HeroFatesState.ActiveUpgradable; } public bool HasShowRedDotFates(out int firstIndex) { firstIndex = 0; List<int> list = GetFatesIDList(); if (list.IsNullOrEmpty()) return false; for (int i = 0; i < list.Count; i++) { int fatesID = list[i]; if (IsShowRedDot(fatesID)) { firstIndex = i; return true; } } return false; } public List<HeroInfo> GetPutPreviewHeroList(int fatesID) { if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) { return null; } int fatesQuality = config.FatesQuality; if (!TryGetNowLVAndNextLVConfig(fatesID, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig)) { return null; } int needHeroCnt = nextLVConfig.NeedHeroCnt; List<HeroInfo> consumableHeroInfoList = GetConsumableHeroInfoList(fatesQuality); if (consumableHeroInfoList.IsNullOrEmpty()) { return null; } List<HeroInfo> putPreviewHeroList = new List<HeroInfo>(); int count = Math.Min(needHeroCnt, consumableHeroInfoList.Count); for (int i = 0; i < count; i++) { putPreviewHeroList.Add(consumableHeroInfoList[i]); } return putPreviewHeroList; } #region 玩家选中内容 public int chooseHeroFatesId = 0; public int chooseHeroFatesQuality = 0; public HeroInfo chooseHeroInfo = null; // 给玩家操作选中的列表 public List<HeroInfo> chooseCostHeroInfos = new List<HeroInfo>(); // 玩家实际选中的列表 public List<HeroInfo> realCostHeroInfos = new List<HeroInfo>(); public event Action OnRealChooseChangeEvent; public event Action OnChooseChangeEvent; public void InitChooseList() { chooseCostHeroInfos.Clear(); foreach (var heroInfo in realCostHeroInfos) { chooseCostHeroInfos.Add(heroInfo); } chooseHeroInfo = null; } public void ChooseAdd(HeroInfo heroInfo) { if (chooseCostHeroInfos.Contains(heroInfo)) { chooseCostHeroInfos.Remove(heroInfo); chooseHeroInfo = null; } else { chooseCostHeroInfos.Add(heroInfo); chooseHeroInfo = heroInfo; } OnChooseChangeEvent?.Invoke(); } public void ClearAllList() { chooseCostHeroInfos.Clear(); realCostHeroInfos.Clear(); chooseHeroInfo = null; OnRealChooseChangeEvent?.Invoke(); } public void PutList() { realCostHeroInfos.Clear(); foreach (var heroInfo in chooseCostHeroInfos) { realCostHeroInfos.Add(heroInfo); } OnRealChooseChangeEvent?.Invoke(); } public void FastAddList(List<HeroInfo> heroInfos) { if (heroInfos.IsNullOrEmpty()) return; chooseCostHeroInfos.Clear(); realCostHeroInfos.Clear(); foreach (var heroInfo in heroInfos) { chooseCostHeroInfos.Add(heroInfo); realCostHeroInfos.Add(heroInfo); } OnRealChooseChangeEvent?.Invoke(); } #endregion #region 属性计算 public Dictionary<int, long> attrDic = new Dictionary<int, long>(); public Dictionary<int, long> GetTotalAttr() { return attrDic; } public long GetAttrValue(int attrID) { attrDic.TryGetValue(attrID, out long value); return value; } public int GetAttrPer(int attrID) { if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrID)) { var pertype = PlayerPropertyConfig.baseAttr2perDict[attrID]; attrDic.TryGetValue(pertype, out long value); return (int)(value); } return 0; } public void RefreshAttr() { attrDic.Clear(); List<int> allIds = HeroFatesConfig.GetKeys(); foreach (var fatesID in allIds) { HeroFatesState state = GetHeroFatesState(fatesID); if (!TryGetAttrIDListAndLVAttrValueList(fatesID, out int[] attrIDList, out int[] lvAttrValueList)) continue; for (int i = 0; i < attrIDList.Length; i++) { if (!attrDic.ContainsKey(attrIDList[i])) { attrDic[attrIDList[i]] = 0; } if (state == HeroFatesState.Locked || state == HeroFatesState.Activatable) continue; int value = GetNowAttrValue(fatesID, i); attrDic[attrIDList[i]] += value; } } } //最终属性 = 等级 * 每级属性值 public int GetNowAttrValue(int fatesID, int attrIndex) { if (!TryGetAttrIDListAndLVAttrValueList(fatesID, out int[] attrIDList, out int[] lvAttrValueList)) return 0; if (attrIndex < 0 || attrIndex > attrIDList.Length) return 0; if (!TryGetHeroFates(fatesID, out HeroFates info)) return 0; int lv = info.FatesLV; return lv * lvAttrValueList[attrIndex]; } //下一级属性 = (等级 + 1) * 每级属性值 public int GetNextAttrValue(int fatesID, int attrIndex) { if (!TryGetAttrIDListAndLVAttrValueList(fatesID, out int[] attrIDList, out int[] lvAttrValueList)) return 0; if (attrIndex < 0 || attrIndex > attrIDList.Length) return 0; if (!TryGetHeroFates(fatesID, out HeroFates info)) return 0; int lv = info.FatesLV + 1; return lv * lvAttrValueList[attrIndex]; } #endregion #region 读表 // 0级时,不返回nowLVConfig,只返回nowLVConfig public bool TryGetNowLVAndNextLVConfig(int fatesID, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig) { nowLv = 0; nowLVConfig = null; nextLVConfig = null; if (!TryGetHeroFates(fatesID, out HeroFates info)) return false; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) return false; int quality = config.FatesQuality; nowLv = info.FatesLV; if (nowLv != 0) { if (!HeroFatesQualityLVConfig.TryGetHeroFatesQualityLVConfig(quality, nowLv, out nowLVConfig)) return false; } int nextLv = nowLv + 1; return HeroFatesQualityLVConfig.TryGetHeroFatesQualityLVConfig(quality, nextLv, out nextLVConfig); } public bool TryGetMaxFatesLVConfigByFatesID(int fatesID, out HeroFatesQualityLVConfig heroFatesQualityLVConfig) { heroFatesQualityLVConfig = null; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) return false; int fatesQuality = config.FatesQuality; if (!HeroFatesQualityLVConfig.TryGetDictByFatesQuality(fatesQuality, out Dictionary<int, int> dict) || dict.IsNullOrEmpty()) return false; int maxFatesLV = dict.Keys.Max(); if (!HeroFatesQualityLVConfig.TryGetHeroFatesQualityLVConfig(fatesQuality, maxFatesLV, out heroFatesQualityLVConfig)) return false; return true; } public bool TryGetHeroFatesConfig(int fatesID, out HeroFatesConfig config) { config = null; if (!HeroFatesConfig.HasKey(fatesID)) return false; config = HeroFatesConfig.Get(fatesID); return true; } public bool TryGetAttrIDListAndLVAttrValueList(int fatesID, out int[] attrIDList, out int[] lvAttrValueList) { attrIDList = null; lvAttrValueList = null; if (!TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) return false; attrIDList = config.AttrIDList; lvAttrValueList = config.LVAttrValueList; if (attrIDList.IsNullOrEmpty() || lvAttrValueList.IsNullOrEmpty()) return false; return attrIDList.Length == lvAttrValueList.Length; } public bool TryGetHeroConfig(int heroID, out HeroConfig config) { config = null; if (!HeroConfig.HasKey(heroID)) return false; config = HeroConfig.Get(heroID); return true; } public bool TryGetHeroAndSkinConfigByHeroID(int heroID, out HeroConfig heroConfig, out HeroSkinConfig heroSkinConfig) { heroConfig = null; heroSkinConfig = null; if (!HeroConfig.HasKey(heroID)) return false; heroConfig = HeroConfig.Get(heroID); int[] skinIDList = heroConfig.SkinIDList; if (skinIDList.IsNullOrEmpty()) return false; int skinID = skinIDList[0]; if (!HeroSkinConfig.HasKey(skinID)) return false; heroSkinConfig = HeroSkinConfig.Get(skinID); return true; } List<int> fatesIDList = null; public List<int> GetFatesIDList() { if (fatesIDList.IsNullOrEmpty()) { fatesIDList = HeroFatesConfig.GetKeys(); // 按品质升序排序,相同品质按ID升序排序 fatesIDList.Sort((id1, id2) => { if (!TryGetHeroFatesConfig(id1, out HeroFatesConfig config1) || !TryGetHeroFatesConfig(id2, out HeroFatesConfig config2)) { return id1.CompareTo(id2); // 如果获取配置失败,按ID排序 } // 先比较品质 int qualityCompare = config1.FatesQuality.CompareTo(config2.FatesQuality); if (qualityCompare != 0) { return qualityCompare; // 品质不同,按品质排序 } // 品质相同,按ID排序 return id1.CompareTo(id2); }); } return fatesIDList; } public string GetCellBgByFatesQuality(int fatesQuality) { return StringUtility.Concat("HeroFatesQualityBG", fatesQuality.ToString()); } public string GetHeroFatesNameBGByFatesQuality(int fatesQuality) { return StringUtility.Concat("HeroFatesNameBG", fatesQuality.ToString()); } #endregion } public enum HeroFatesState { Locked, // 未激活 Activatable, // 可激活 (未激活但材料足够) ActiveNotUpgradable,// 已激活但不可升级 (材料不足或配置不支持) ActiveUpgradable, // 已激活且可升级 (材料足够升级下一档) MaxLevel, // 已升到满级 } public class HeroFates { public int FatesID; // 宿缘ID public int State; // 宿缘状态:0-未激活;1-已激活已领奖 public int FatesLV; // 宿缘等级,激活时为0级,升级后有升级属性 } Main/System/HeroFates/HeroFatesManager.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 43d2eef891a1efc45b86bf65cbc5a010 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesPutCell.cs
New file @@ -0,0 +1,31 @@ using System.Collections.Generic; using UnityEngine; public class HeroFatesPutCell : MonoBehaviour { [SerializeField] List<HeroFatesPutItem> items = new List<HeroFatesPutItem>(); HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(int rowIndex, List<HeroInfo> list) { if (list.IsNullOrEmpty()) { return; } for (int i = 0; i < items.Count; i++) { int index = rowIndex * manager.rowCountMax + i; if (index < list.Count) { items[i].SetActive(true); items[i].Display(list[index]); } else { items[i].SetActive(false); } } } } Main/System/HeroFates/HeroFatesPutCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: c9f56162b0d350048812d05a806629f4 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesPutItem.cs
New file @@ -0,0 +1,42 @@ using UnityEngine; using UnityEngine.UI; public class HeroFatesPutItem : MonoBehaviour { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] Image jobImg; [SerializeField] Text nameText; [SerializeField] Transform select; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } HeroInfo hero; public void Display(HeroInfo hero) { this.hero = hero; heroHeadBaseCell.Init(hero.heroId, hero.SkinID, hero.heroStar, hero.awakeLevel, hero.heroLevel, OnClick); nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel); jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class)); bool isChoose = manager.chooseCostHeroInfos.Contains(hero); select?.SetActive(isChoose); } public void OnClick() { if (!manager.TryGetNowLVAndNextLVConfig(manager.chooseHeroFatesId, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig)) { return; } bool isChoose = manager.chooseCostHeroInfos.Contains(hero); if (!isChoose) { int nextCnt = manager.chooseCostHeroInfos.Count + 1; // 当前选中武将已达上限 if (nextCnt > nextLVConfig.NeedHeroCnt) { SysNotifyMgr.Instance.ShowTip("HeroFates03"); return; } } manager.ChooseAdd(hero); } } Main/System/HeroFates/HeroFatesPutItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 549bc7cdfe32a6648a40368a19551861 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesPutWin.cs
New file @@ -0,0 +1,100 @@ using System.Collections.Generic; using UnityEngine; public class HeroFatesPutWin : UIBase { [SerializeField] Transform transChooseHero; [SerializeField] HeroFatesPutItem chooseHero; [SerializeField] GiftBaseCell[] giftBaseCells; [SerializeField] Transform transNoChooseHero; [SerializeField] ScrollerController scroller; [SerializeField] Transform transNoCanChooseHero; [SerializeField] ButtonEx btnPut; [SerializeField] TextEx txtChooseCnt; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } protected override void InitComponent() { btnPut.SetListener(() => { manager.PutList(); CloseWindow(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnChooseChangeEvent += OnChooseChangeEvent; CreateScoller(); DisplayChooseHero(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnChooseChangeEvent -= OnChooseChangeEvent; } private void OnChooseChangeEvent() { RefeshScoller(); DisplayChooseHero(); } List<HeroInfo> list = new List<HeroInfo>(); private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroFatesPutCell>(); _cell?.Display(cell.index, list); } void CreateScoller() { scroller.Refresh(); if (manager.TryGetHeroFatesConfig(manager.chooseHeroFatesId, out HeroFatesConfig config)) { int fatesQuality = config.FatesQuality; list = manager.GetConsumableHeroInfoList(fatesQuality); transNoCanChooseHero.SetActive(list.IsNullOrEmpty()); if (!list.IsNullOrEmpty()) { int rowCount = Mathf.CeilToInt((float)list.Count / manager.rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } } scroller.Restart(); } void RefeshScoller() { scroller.m_Scorller.RefreshActiveCellViews(); } void DisplayChooseHero() { HeroInfo heroInfo = manager.chooseHeroInfo; transNoChooseHero.SetActive(heroInfo == null); transChooseHero.SetActive(heroInfo != null); if (heroInfo != null) { chooseHero.Display(heroInfo); HeroUIManager.Instance.RefreshGiftCell(giftBaseCells, heroInfo); } if (!manager.TryGetNowLVAndNextLVConfig(manager.chooseHeroFatesId, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig)) { return; } int needCnt = nextLVConfig.NeedHeroCnt; int chooseCnt = manager.chooseCostHeroInfos.Count; txtChooseCnt.text = Language.Get("HeroFates04", UIHelper.AppendColor(chooseCnt >= needCnt ? TextColType.DarkGreen : TextColType.Red, Language.Get("BoneField09", chooseCnt, needCnt))); } } Main/System/HeroFates/HeroFatesPutWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e38b8e8bec1da9945b8ba306696a828a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesUpgradeAttrCell.cs
New file @@ -0,0 +1,43 @@ using UnityEngine; public class HeroFatesUpgradeAttrCell : MonoBehaviour { [SerializeField] TextEx txtAttrName; [SerializeField] TextEx txtAttrFromValue; [SerializeField] TextEx txtAttrToValue; [SerializeField] ImageEx imgAdd; [SerializeField] UIEffectPlayer uIEffectPlayer1; [SerializeField] UIEffectPlayer uIEffectPlayer2; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(int index, CellView cell, bool isPlayer = false) { uIEffectPlayer1.Stop(); uIEffectPlayer2.Stop(); int fatesID = cell.info.Value.infoInt1; if (!manager.TryGetAttrIDListAndLVAttrValueList(fatesID, out int[] attrIDList, out int[] lvAttrValueList)) return; if (index < 0 || index >= attrIDList.Length) return; int attrID = attrIDList[index]; long attrValue = lvAttrValueList[index]; if (!PlayerPropertyConfig.HasKey(attrID)) return; PlayerPropertyConfig config = PlayerPropertyConfig.Get(attrID); txtAttrName.text = config.ShowName; long fromValue = manager.GetNowAttrValue(fatesID, index); txtAttrFromValue.text = PlayerPropertyConfig.GetValueDescription(attrID, fromValue); long toValue = manager.GetNextAttrValue(fatesID, index); txtAttrToValue.text = PlayerPropertyConfig.GetValueDescription(attrID, toValue); imgAdd.SetActive(toValue > fromValue); if (isPlayer) { uIEffectPlayer1.Play(); uIEffectPlayer2.Play(); } } } Main/System/HeroFates/HeroFatesUpgradeAttrCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 3300269fab35f104bad377e0345e51ce MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesUpgradeHeadCell.cs
New file @@ -0,0 +1,19 @@ using UnityEngine; using UnityEngine.UI; public class HeroFatesUpgradeHeadCell : MonoBehaviour { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] Image jobImg; [SerializeField] Text nameText; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } public void Display(HeroInfo hero) { heroHeadBaseCell.Init(hero.heroId, hero.SkinID, hero.heroStar, hero.awakeLevel, hero.heroLevel); nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel); jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class)); } } Main/System/HeroFates/HeroFatesUpgradeHeadCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e3e4cfdc83ca8f2429a55b307166a0a2 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesUpgradeWin.cs
New file @@ -0,0 +1,252 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HeroFatesUpgradeWin : UIBase { [SerializeField] List<HeroFatesUpgradeHeadCell> headCells; [SerializeField] TextEx txtTotalStarCnt; [SerializeField] TextEx txtFromLv; [SerializeField] TextEx txtToLv; [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx btnFastPut; [SerializeField] ButtonEx btnUpdate; [SerializeField] ButtonEx btnPut; [SerializeField] ImageEx imgQualityHeroBg; [SerializeField] ImageEx imgQualityHeroIcon; [SerializeField] ImageEx imgQualityHeroNull; [SerializeField] Image imgPutRed; [SerializeField] ButtonEx btnQualityHeroClear; [SerializeField] TextEx txtQualityHeroName; [SerializeField] TextEx txtNeedQualityHeroCnt; int fatesID; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } protected override void InitComponent() { btnPut.SetListener(() => { manager.InitChooseList(); UIManager.Instance.OpenWindow<HeroFatesPutWin>(); }); btnQualityHeroClear.SetListener(() => { manager.ClearAllList(); DisplayChoose(fatesID); }); btnFastPut.SetListener(() => { var list = manager.GetPutPreviewHeroList(manager.chooseHeroFatesId); if (list.IsNullOrEmpty()) { //符合升级条件的武将不足 SysNotifyMgr.Instance.ShowTip("HeroFates02"); return; } UIManager.Instance.OpenWindow<HeroFatesFastPutPreviewWin>(); }); btnUpdate.SetListener(() => { if (!manager.TryGetNowLVAndNextLVConfig(fatesID, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig)) { return; } int fatesNowStarCnt = manager.GetFatesNowStarCnt(fatesID); int nextNeedStarCnt = nextLVConfig.NeedStarTotal; if (fatesNowStarCnt < nextNeedStarCnt) { //武将总星级不足 SysNotifyMgr.Instance.ShowTip("HeroFates01"); return; } ushort[] arr = manager.GetItemIndexList(manager.realCostHeroInfos); //放入的消耗武将数量不足 if (arr.IsNullOrEmpty() || nextLVConfig.NeedHeroCnt > manager.realCostHeroInfos.Count) { SysNotifyMgr.Instance.ShowTip("HeroFates04"); return; } manager.SendHeroFates(manager.chooseHeroFatesId, 1, arr); manager.ClearAllList(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent += OnUpdateHeroFatesInfo; manager.OnRealChooseChangeEvent += OnRealChooseChangeEvent; manager.ClearAllList(); fatesID = manager.chooseHeroFatesId; DisplayHeadCells(fatesID); DisplayTotalStarCnt(fatesID); CreateScoller(fatesID); DisplayLV(fatesID); DisplayChoose(fatesID); } void DisplayTotalStarCnt(int fatesID) { bool hasNowLVAndNextLVConfig = manager.TryGetNowLVAndNextLVConfig(fatesID, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig); if (hasNowLVAndNextLVConfig) { int fatesNowStarCnt = manager.GetFatesNowStarCnt(fatesID); int nextNeedStarCnt = nextLVConfig.NeedStarTotal; txtTotalStarCnt.text = UIHelper.AppendColor(nextNeedStarCnt <= fatesNowStarCnt ? TextColType.DarkGreen : TextColType.Red, StringUtility.Concat(Language.Get("HeroFates05"), Language.Get("HeroFates11", fatesNowStarCnt, nextNeedStarCnt))); } } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent -= OnUpdateHeroFatesInfo; manager.OnRealChooseChangeEvent -= OnRealChooseChangeEvent; } private void OnRealChooseChangeEvent() { RefreshAll(); } private void OnUpdateHeroFatesInfo() { if (manager.IsHeroFatesStarMax(manager.chooseHeroFatesId)) { SysNotifyMgr.Instance.ShowTip("HeroFates02"); CloseWindow(); return; } RefreshAll(); var smallList = scroller.m_Scorller.GetActiveCellViews(); // 修正拼写错误 for (int i = 0; i < smallList.Count; i++) { var item = smallList[i]; var cellView = item as CellView; if (cellView != null) { var _cell = cellView.GetComponent<HeroFatesUpgradeAttrCell>(); _cell?.Display(cellView.index, cellView, true); } } } void RefreshAll() { fatesID = manager.chooseHeroFatesId; DisplayHeadCells(fatesID); DisplayTotalStarCnt(fatesID); DisplayLV(fatesID); DisplayChoose(fatesID); RefeshScoller(); } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroFatesUpgradeAttrCell>(); _cell?.Display(cell.index, cell); } void CreateScoller(int fatesID) { scroller.Refresh(); if (manager.TryGetAttrIDListAndLVAttrValueList(fatesID, out var attrIDList, out var lvAttrValueList)) { for (int i = 0; i < attrIDList.Length; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoInt1 = fatesID; scroller.AddCell(ScrollerDataType.Header, i, cellInfo); } } scroller.Restart(); } void RefeshScoller() { scroller.m_Scorller.RefreshActiveCellViews(); } private void DisplayLV(int fatesID) { int fromLv = 0; int toLv = 0; if (manager.TryGetHeroFates(fatesID, out HeroFates info)) { fromLv = info.FatesLV; toLv = info.FatesLV + 1; } txtFromLv.text = Language.Get("L1113", fromLv); txtToLv.text = Language.Get("L1113", toLv); } public void DisplayHeadCells(int fatesID) { if (!HeroFatesConfig.HasKey(fatesID)) return; if (!manager.TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config) || config.HeroIDList.IsNullOrEmpty()) return; Dictionary<int, HeroInfo> dict = manager.GetFatesNowStarHeroInfoDict(fatesID); if (dict.IsNullOrEmpty()) return; for (int i = 0; i < headCells.Count; i++) { if (i < config.HeroIDList.Length) { int heroID = config.HeroIDList[i]; if (dict.TryGetValue(heroID, out HeroInfo info)) { headCells[i].Display(info); headCells[i].SetActive(true); } else { headCells[i].SetActive(false); } } else { headCells[i].SetActive(false); } } } public void DisplayChoose(int fatesID) { if (!manager.TryGetHeroFatesConfig(fatesID, out HeroFatesConfig config)) { return; } if (!manager.TryGetNowLVAndNextLVConfig(fatesID, out int nowLv, out HeroFatesQualityLVConfig nowLVConfig, out HeroFatesQualityLVConfig nextLVConfig)) { return; } int chooseCnt = manager.realCostHeroInfos.Count; bool isChoose = chooseCnt > 0; imgQualityHeroIcon.SetActive(isChoose); btnQualityHeroClear.SetActive(isChoose); imgQualityHeroNull.SetActive(!isChoose); imgQualityHeroBg.SetItemBackGround(config.FatesQuality); imgQualityHeroIcon.SetSprite(StringUtility.Concat("HeroFatesQualityHead", config.FatesQuality.ToString())); txtQualityHeroName.text = StringUtility.Concat(RichTextMsgReplaceConfig.GetRichReplace("HeroQuality", config.FatesQuality), Language.Get("herocard3")); txtQualityHeroName.color = UIHelper.GetUIColorByFunc(config.FatesQuality); int needCnt = nextLVConfig.NeedHeroCnt; txtNeedQualityHeroCnt.text = UIHelper.AppendColor(chooseCnt >= needCnt ? TextColType.DarkGreen : TextColType.Red, Language.Get("BoneField09", chooseCnt, needCnt)); bool isShowRed = manager.IsShowRedDot(fatesID); imgPutRed.SetActive(isShowRed && !isChoose); } } Main/System/HeroFates/HeroFatesUpgradeWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 36a41763eeea97f4284585b5e64c3fa8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroFates/HeroFatesWin.cs
New file @@ -0,0 +1,90 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; public class HeroFatesWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] List<TextEx> attrs; HeroFatesManager manager { get { return HeroFatesManager.Instance; } } protected override void InitComponent() { } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent += OnUpdateHeroFatesInfo; CreateScoller(); int firstIndex = 0; manager.HasShowRedDotFates(out firstIndex); scroller.JumpIndex(firstIndex); DisplayAttrs(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnUpdateHeroFatesInfoEvent -= OnUpdateHeroFatesInfo; } private void OnUpdateHeroFatesInfo() { RefeshScoller(); DisplayAttrs(); } List<int> fatesIDList = new List<int>(); private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroFatesCell>(); _cell?.Display(cell.index, fatesIDList); } void CreateScoller() { scroller.Refresh(); fatesIDList = manager.GetFatesIDList(); if (!fatesIDList.IsNullOrEmpty()) { for (int i = 0; i < fatesIDList.Count; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } scroller.Restart(); } void RefeshScoller() { scroller.m_Scorller.RefreshActiveCellViews(); } void DisplayAttrs() { Dictionary<int, long> totalAttrDict = manager.GetTotalAttr(); if (attrs.IsNullOrEmpty() || totalAttrDict.IsNullOrEmpty()) return; List<int> totalAttrIdList = totalAttrDict.Keys .OrderByDescending(attrID => totalAttrDict[attrID] > 0) // 属性值>0的排前面 .ThenBy(attrID => attrID) // 然后按attrID升序 .ToList(); for (int i = 0; i < attrs.Count; i++) { if (i < totalAttrDict.Count) { int attrID = totalAttrIdList[i]; long attrValue = totalAttrDict[attrID]; attrs[i].text = PlayerPropertyConfig.GetFullDescription(attrID, attrValue); attrs[i].SetActive(true); } else { attrs[i].SetActive(false); } } } } Main/System/HeroFates/HeroFatesWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 65869ccc1efcb1741ae8394076307030 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroUI/HeroBaseWin.cs
@@ -16,8 +16,8 @@ base.InitComponent(); //招募为另外一个界面,避免关闭时显示空白 callBtn.AddListener(()=> { callBtn.AddListener(() => { //打开招募界面 UIManager.Instance.OpenWindow<HeroCallWin>(); }); @@ -51,6 +51,7 @@ currentSubUI = UIManager.Instance.OpenWindow<HeroCollectionWin>(); break; case 2: currentSubUI = UIManager.Instance.OpenWindow<HeroFatesWin>(); break; default: Debug.LogWarning("未知的标签索引: " + functionOrder); Main/System/HeroUI/HeroHeadBaseCell.cs
@@ -140,7 +140,10 @@ public void Init(int heroID, int skinID, int star = 0, int awakelv = 0, int lv = 0, UnityAction onclick = null) { LoadPrefab(); //存在被卸载的可能,重新加载 clickBtn.AddListener(onclick); if (onclick != null) { clickBtn.AddListener(onclick); } var heroConfig = HeroConfig.Get(heroID); qualityBG.SetSprite("heroheadBG" + heroConfig.Quality); // int skinID = 0; @@ -186,7 +189,7 @@ } countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country)); lvText.text = lv == 0 ? "": Language.Get("L1094") + lv; lvText.text = lv == 0 ? "" : Language.Get("L1094") + lv; awakeLvRect.SetActive(awakelv > 0); awakeLvText.text = awakelv.ToString(); @@ -216,7 +219,7 @@ cellContainer.transform.SetAsFirstSibling(); } } //缩放到和父rect一样大 var scale = 1f; var rect = cellContainer.GetComponent<RectTransform>(); @@ -227,10 +230,10 @@ //外部控制了尺寸获取为0 GridLayoutGroup grid = GetComponentInParent<GridLayoutGroup>(); if (grid != null) { { width = grid.cellSize.x; } } scale = width / rect.sizeDelta.x; cellContainer.transform.localScale = cellContainer.transform.localScale * scale; Main/System/Main/FightPowerManager.cs
@@ -318,8 +318,8 @@ propertyVariables[HORSE_PER] = HorseManager.Instance.GetAttrPer(attrType) / 10000.0f; propertyVariables[BEAUTY_VALUE] = 0; propertyVariables[BEAUTY_PER] = 0; propertyVariables[FATES_VALUE] = 0; propertyVariables[FATES_PER] = 0; propertyVariables[FATES_VALUE] = HeroFatesManager.Instance.GetAttrValue(attrType); propertyVariables[FATES_PER] = HeroFatesManager.Instance.GetAttrPer(attrType) / 10000.0f; //全体卡牌加成 propertyVariables[HERO_CARDPER] = allHeroAddPer; Main/System/Redpoint/MainRedDot.cs
@@ -135,7 +135,8 @@ public const int TianziBillboradRepoint = 471; //天子的考验 public const int PhantasmPavilionRepoint = 472; //幻境阁 public const int LineupRecommendRepoint = 473; //阵容推荐 public const int FunctionPreviewRepoint = 474; //功能预告 public const int FunctionPreviewRepoint = 474; //功能预告 public const int HeroFatesRepoint = 475;//宿缘 public void Register() { Main/Utility/EnumHelper.cs
@@ -843,6 +843,7 @@ OSHeroCall = 46, //开服武将召唤榜活动 OSGala = 47, //开服盛典活动 FunctionPreview = 48, //功能预览 HeroFatesUpgrade = 49, //宿缘升级 }