Main/Component/UI/Common/LongPressButton.cs
@@ -75,6 +75,13 @@ { if (m_IsButtonDown) { if (!this.interactable || !this.IsActive() || !this.enabled) { // 如果按钮不可用,则取消长按状态 m_IsButtonDown = false; m_LongPress = false; return; } m_PressTime += Time.deltaTime; if (m_PressTime < m_LongPressCheckTime) { Main/Component/UI/Effect/UIEffectPlayer.cs
@@ -49,4 +49,13 @@ return effectPlayer; } public void SetEnabled(bool isEnable) { if (spineComp == null) { return; } spineComp.enabled = isEnable; } } Main/Manager/UIManager.cs
@@ -131,17 +131,22 @@ layerTransformCache.Add(UILayer.Loading, loadingTrans); } public Transform GetUIRoot() { return uiRoot; } #endregion #region 辅助方法 // 获取UI层级对应的基础排序顺序 public static int GetBaseSortingOrderForLayer(UILayer layer) { // 尝试从缓存中获取排序顺序 if (layerSortingOrderCache.TryGetValue(layer, out int order)) return order; // 如果缓存中没有,使用原来的方法计算并缓存结果 int result; switch (layer) @@ -165,7 +170,7 @@ result = BASE_SORTING_ORDER * 10; break; } // 将结果存入缓存 layerSortingOrderCache[layer] = result; return result; Main/System/Battle/BattleField/BattleField.cs
@@ -121,7 +121,14 @@ battleRootNode.SetBackground(ResManager.Instance.LoadAsset<Texture>("Texture/FullScreenBg", "mainui_img_277")); SetBattleStartState(); SetSpeedRatio(BattleManager.Instance.speedGear[BattleManager.Instance.speedIndex]); if (MapID == 1) { SetSpeedRatio(BattleManager.Instance.speedGear[AutoFightModel.Instance.fightSpeed - 1]); } else { SetSpeedRatio(BattleManager.Instance.speedGear[BattleManager.Instance.speedIndex]); } SetRootNodePosition(); } Main/System/Battle/BattleField/OperationAgent/HandModeOperationAgent.cs
@@ -5,6 +5,7 @@ public class HandModeOperationAgent : IOperationAgent { protected StoryBattleField storyBattleField; bool autoNext = false; //预存玩家的下一次攻击,让下一次自动执行,因为玩家点的时机不一定是刚好的可攻击状态 public HandModeOperationAgent(BattleField battleField) : base(battleField) { @@ -14,14 +15,24 @@ public override void Run() { base.Run(); if (autoNext) { if (storyBattleField.RequestFight()) { //直到成功为止 autoNext = false; } } } // 通过主界面的按钮推动(调用)DoNext public override void DoNext() { base.DoNext(); storyBattleField.RequestFight(); if (!storyBattleField.RequestFight()) { autoNext = true; } } Main/System/Battle/BattleField/StoryBattleField.cs
@@ -179,17 +179,19 @@ } //请求单次战斗 public void RequestFight() //请求单次战斗, 返回是否成功操作(预判下一次是可以继续的状态) public bool RequestFight() { if (IsPause) { //外部控制 IsPause //还需考虑其他不可战斗状况,主线的BOSS战斗也是另外一个场景且不能切出来 等跳过或者结束 return; return true; } if (BattleManager.Instance.isWaitServerStory) return; { return true; } // 当前没有在播放战斗录像 if (!recordPlayer.IsPlaying()) @@ -209,7 +211,7 @@ dropList.Add(item.gridIndex); } EquipModel.Instance.NotifyItemDrop(dropList, null); return; return false; } // 检查一下锤子的消耗 @@ -217,8 +219,10 @@ { //多次防范 if (GetBattleMode() != BattleMode.Stop) { HaveRest(); return; } return true; } // 请求下一个战斗包 或者检查战斗是否结束 @@ -245,7 +249,7 @@ else { BattleDebug.LogError("unknown battle state"); return; return true; } @@ -258,13 +262,21 @@ { BattleManager.Instance.MainFightRequest(4); } return true; } else { } } else { if (!AutoFightModel.Instance.isAutoAttack) { BattleDebug.LogError("action doesnt finish, wait a moment please"); } } return false; } protected override void SetRootNodePosition() Main/System/Equip/BlessLVManager.cs
@@ -117,12 +117,10 @@ if (PackManager.Instance.GetSinglePack(PackType.Item).HasItem(timeUpTreeItemID)) { redpointTreeItem.state = RedPointState.Simple; return; } if (m_FreeTimeCnt > 0 && GetFreeRemainTime() <= 0) if (m_FreeTimeCnt < dayFreeMaxTimes && GetFreeRemainTime() <= 0) { redpointTreeFree.state = RedPointState.Simple; return; } Main/System/Equip/BlessLVTimeUpWin.cs
@@ -24,6 +24,7 @@ protected override void OnPreOpen() { GlobalTimeEvent.Instance.secondEvent += OnTimeEvent; int count = (int)PackManager.Instance.GetItemCountByID(PackType.Item, BlessLVManager.Instance.timeUpTreeItemID); itemCell.Init(new ItemCellModel(BlessLVManager.Instance.timeUpTreeItemID, false, count)); itemCell.button.AddListener(() => @@ -36,6 +37,18 @@ showCount = Math.Min(count, needCount); RefreshCount(needCount, remainTime); RefreshBtn(showCount); } protected override void OnPreClose() { GlobalTimeEvent.Instance.secondEvent -= OnTimeEvent; } void OnTimeEvent() { var remainTime = BlessLVManager.Instance.GetLVUPRemainTime(); int needCount = (int)Math.Ceiling((float)remainTime / BlessLVManager.Instance.timeUpTreeItemSubTime); RefreshCount(needCount, remainTime); } int showCount; @@ -102,10 +115,18 @@ void OnSpeedUP() { CloseWindow(); int count = (int)PackManager.Instance.GetItemCountByID(PackType.Item, BlessLVManager.Instance.timeUpTreeItemID); if (count <= 0) { SysNotifyMgr.Instance.ShowTip("ItemNotEnoughCommon"); ItemTipUtility.Show(BlessLVManager.Instance.timeUpTreeItemID, true); return; } var pack = new CB224_tagCMUseTreeLVUPTimeItem(); pack.UseCount = (uint)showCount; GameNetSystem.Instance.SendInfo(pack); CloseWindow(); SysNotifyMgr.Instance.ShowTip("BlessLV1", TimeUtility.SecondsToShortDHMS(showCount * BlessLVManager.Instance.timeUpTreeItemSubTime)); } } Main/System/HeroUI/HeroPosWin.cs
@@ -116,7 +116,7 @@ HeroUIManager.Instance.OnTeamPosChangeEvent += TeamChangeEvent; TeamManager.Instance.OnTeamChange += OnTeamChange; CreateScroller(); Refresh(); Display(); } protected override void OnPreClose() @@ -129,7 +129,7 @@ } public override void Refresh() public void Display() { OnBattleTeamAttrPer(); RefreshOnTeamCountry(); @@ -217,11 +217,11 @@ var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); if (team != null) { for (int i = 0; i < team.serverHeroes.Length; i++) for (int i = 0; i < team.tempHeroes.Length; i++) { if (team.serverHeroes[i] == null) if (team.tempHeroes[i] == null) continue; var hero = HeroManager.Instance.GetHero(team.serverHeroes[i].guid); var hero = HeroManager.Instance.GetHero(team.tempHeroes[i].guid); if (hero != null) { valuePer += hero.GetOnBattleAddPer(); @@ -356,6 +356,7 @@ RefreshPosScale(); heroListScroller.m_Scorller.RefreshActiveCellViews(); RefreshOnTeamCountry(true); OnBattleTeamAttrPer(); //表现飞入,连续点击不同头像触发的话则重置 if (flyFrom > -1) Main/System/HeroUI/HeroTrainWin.cs
@@ -429,7 +429,7 @@ { lvupBtnText.text = Language.Get("L1110"); lvupBtn.SetInteractable(false); lvupMoneyIcon.SetActive(false); lvupMoneyText.SetActive(false); } } @@ -792,6 +792,7 @@ redpointLVUP.SetActive(true); return; } return; } } Main/System/HeroUI/HeroUIManager.cs
@@ -163,21 +163,22 @@ return hero.heroLevel >= GetMaxLV(hero.Quality); } //突破限制的最高等级; 存在突破等级可能更多的情况,不一定提供等级上限 //突破限制的最高等级; 如果存在突破等级后不能再升级是策划配置问题 public int GetMaxLVByBreakLV(int quality, int breakLevel) { for (int i = breakLevel; i >= 0; i--) { var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, i); if (config == null) { continue; } return config.LVMax; } return 0; // for (int i = breakLevel; i >= 0; i--) // { // var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, i); // if (config == null) // { // continue; // } // return config.LVMax; // } return HeroQualityBreakConfig.GetQualityBreakConfig(quality, breakLevel).LVMax; } //是否达到因突破限制的最高级 public bool IsLVMaxByBreakLevel(HeroInfo hero) { return hero.heroLevel == GetMaxLVByBreakLV(hero.Quality, hero.breakLevel); @@ -416,6 +417,7 @@ { return 3; } return 0; } } Main/System/InternalAffairs/AffairBaseWin.cs
@@ -47,9 +47,12 @@ GoldRushManager.Instance.OnAutoWorkingEvent += OnAutoWorkingEvent; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshEvent; GoldRushManager.Instance.ResumeAutoWorking(); Display(); GoldRushManager.Instance.GetAllAward(); if (GoldRushManager.Instance.openAutoGoldRush) { GoldRushManager.Instance.GetAllAward(); } } protected override void OnPreClose() @@ -60,6 +63,11 @@ PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshEvent; } protected override void OnOpen() { GoldRushManager.Instance.ResumeAutoWorking(); } void Display() { fullGoldRush.SetActive(GoldRushManager.Instance.GetFinishGoldRushCount() >= GoldRushManager.Instance.warehouseMaxCnt); Main/System/InternalAffairs/GoldRushManager.cs
@@ -85,7 +85,7 @@ public int[] refreshMoneyList; public Dictionary<int, int> itemIDUnLockFuncIDDict = new Dictionary<int, int>(); bool openAutoGoldRush public bool openAutoGoldRush { get { Main/System/InternalAffairs/GoldRushTentCell.cs
@@ -18,6 +18,7 @@ [SerializeField] GameObject lockMoneyGo; [SerializeField] Button unlockMoneyBtn; //货币解锁 [SerializeField] Image unlockMoneyIcon; [SerializeField] Image unlockMoneyRedpoint; [SerializeField] Text unlockMoneyText; [SerializeField] GameObject goldRushMissionWaitGo; //未发布任务 [SerializeField] GameObject goldRushMissionWorkingGo; //已发布任务 @@ -66,6 +67,7 @@ GoldRushManager.Instance.OnGoldRushInfoEvent += Display; GoldRushManager.Instance.OnRefreshItemEvent += OnRefreshItemEvent; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent; leaderCount = GoldRushManager.Instance.GetCampWorkerCnt(campID); Display(); @@ -79,6 +81,19 @@ GoldRushManager.Instance.OnGoldRushInfoEvent -= Display; GoldRushManager.Instance.OnRefreshItemEvent -= OnRefreshItemEvent; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent; } void OnPlayerDataRefreshEvent(PlayerDataType type) { if (type == GoldRushManager.Instance.unLockMoneyType) { if (GoldRushManager.Instance.GetCampLockState(campID) == 2) { var campConfig = GoldRushCampConfig.Get(campID); unlockMoneyRedpoint.SetActive(UIHelper.CheckMoneyCount(campConfig.MoneyUnlock[0], campConfig.MoneyUnlock[1], 0)); } } } void FixFollowWoker(int lockState) @@ -186,6 +201,7 @@ unLockBtn.SetActive(false); lockMoneyGo.SetActive(true); unlockMoneyRedpoint.SetActive(UIHelper.CheckMoneyCount(campConfig.MoneyUnlock[0], campConfig.MoneyUnlock[1], 0)); unlockMoneyIcon.SetIconWithMoneyType(campConfig.MoneyUnlock[0]); unlockMoneyText.text = campConfig.MoneyUnlock[1].ToString(); goldRushMissionWaitGo.SetActive(false); @@ -515,7 +531,7 @@ } } if (followBack) if (followBack&& GoldRushManager.Instance.GetCampWorkerCnt(campID) == 0) { StartMove(true); workState = 2; Main/System/InternalAffairs/GoldRushWorkerCell.cs
@@ -15,6 +15,7 @@ [SerializeField] Button lockMoneyBtn; [SerializeField] Text lockMoneyText; [SerializeField] Image lockMoneyIcon; [SerializeField] Image lockMoneyRedpoint; public void Display(int workerID) @@ -34,10 +35,12 @@ if (PlayerDatas.Instance.baseData.LV < lockLV) { lockLVRect.SetActive(true); unLockBtn.SetActive(false); lockLVText.text = Language.Get("L1037", lockLV); } else { { lockLVRect.SetActive(false); unLockBtn.SetActive(true); unLockBtn.AddListener(() => { @@ -56,6 +59,7 @@ lockLVRect.SetActive(false); unLockBtn.SetActive(false); lockMoneyBtn.SetActive(true); lockMoneyRedpoint.SetActive(UIHelper.CheckMoneyCount(config.MoneyUnlock[0], config.MoneyUnlock[1], 0)); lockMoneyIcon.SetIconWithMoneyType(config.MoneyUnlock[0]); lockMoneyText.text = config.MoneyUnlock[1].ToString(); lockMoneyBtn.AddListener(() => Main/System/InternalAffairs/GoldRushWorkerWin.cs
@@ -42,13 +42,14 @@ protected override void OnPreOpen() { CreateManagerScroller(); CreateWorkersScroller(); GoldRushManager.Instance.OnGoldRushCampEvent += OnGoldRushCampEvent; GoldRushManager.Instance.OnGoldRushInfoEvent += OnGoldRushInfoEvent; workMgrScroller.OnRefreshCell += OnRefreshWorkMgrCell; workersScroller.OnRefreshCell += OnRefreshWorkersCell; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent; if (functionOrder == 0) { @@ -68,6 +69,16 @@ workMgrScroller.OnRefreshCell -= OnRefreshWorkMgrCell; workersScroller.OnRefreshCell -= OnRefreshWorkersCell; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent; } void OnPlayerDataRefreshEvent(PlayerDataType type) { if (type == GoldRushManager.Instance.unLockMoneyType) { workersScroller.m_Scorller.RefreshActiveCellViews(); } } @@ -76,6 +87,7 @@ if (functionOrder == 0) { RefreshWorkingList(); CreateManagerScroller(); DispalyWorkMgr(); } else @@ -113,8 +125,11 @@ //派遣中的队列 + 完成的队列,动态变化的 void CreateManagerScroller() { if (workMgrScroller.GetNumberOfCells(workMgrScroller.m_Scorller) == goldRushMissionList.Count) return; workMgrScroller.Refresh(); for (int i = 0; i < GoldRushManager.Instance.warehouseMaxCnt; ++i) for (int i = 0; i < goldRushMissionList.Count; ++i) { workMgrScroller.AddCell(ScrollerDataType.Header, i); } Main/System/Mail/MailCell.cs
New file @@ -0,0 +1,52 @@ using System; using UnityEngine; using UnityEngine.UI; public class MailCell : CellView { [SerializeField] Button btnMail; [SerializeField] ImageEx imgMask; [SerializeField] ImageEx imgRed; [SerializeField] ImageEx imgHasAward; [SerializeField] TextEx txtTitle; [SerializeField] TextEx txtDate; MailManager model { get { return MailManager.Instance; } } string uuid = string.Empty; public void Display(int index, CellView cellView) { MailCategory mailCategory = (MailCategory)cellView.info.Value.infoInt1; var list = model.GetSortMailScrList(mailCategory); if (list == null || index < 0 || index >= list.Count) return; uuid = list[index]; if (!model.TryGetMailData(uuid, out var mailData) || mailData == null) return; //mailData.MailState 邮件状态: 0-未知;1-未读;2-已读;3-已领; imgRed.SetActive(mailData.MailState == 1); imgHasAward.SetActive(mailData.MailState != 3 && mailData.HasAward()); imgMask.SetActive(mailData.MailState == 2 || mailData.MailState == 3); if (mailData.IsTemplateMail() && MailConfig.HasKey(mailData.GetTemplateKey())) { txtTitle.text = MailConfig.Get(mailData.GetTemplateKey()).Title; } else { txtTitle.text = mailData.Title; } txtDate.text = model.FormatMailExpiryDays(mailData.CreateDateTime, mailData.LimitDays); btnMail.SetListener(OnClickButtonMail); } private void OnClickButtonMail() { model.nowUuid = uuid; if (!model.TryGetMailData(uuid, out var mailData) || mailData == null) return; if (mailData.MailState == 1) { model.ReadMail(uuid); } UIManager.Instance.OpenWindow<MailInfoWin>(); } } Main/System/Mail/MailCell.cs.metacopy from Main/System/Mail/MailGlobalCell.cs.meta copy to Main/System/Mail/MailCell.cs.meta
File was copied from Main/System/Mail/MailGlobalCell.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 guid: baaef1e2dac4e30499722be1d4c60bb4 guid: 540496bd35ab2f44fa3c043f3b748969 MonoImporter: externalObjects: {} serializedVersion: 2 Main/System/Mail/MailGlobalCell.cs
File was deleted Main/System/Mail/MailInfoAwardCell.cs
New file @@ -0,0 +1,26 @@ using System; using UnityEngine; using UnityEngine.UI; public class MailInfoAwardCell : CellView { [SerializeField] ItemCell itemCell; [SerializeField] ImageEx imgHave; [SerializeField] ImageEx imgMask; MailManager model { get { return MailManager.Instance; } } public void Display(int index, CellView cellView) { string uuid = cellView.info.Value.infoStr1; if (!model.TryGetMailData(uuid, out MailData mailData) || mailData == null || mailData.Items == null) return; if (index < 0 || index >= mailData.Items.Count) return; int mailState = mailData.MailState;//0-未知;1-未读;2-已读;3-已领; MailItemData data = mailData.Items[index]; itemCell.Init(new ItemCellModel((int)data.ItemID, true, data.Count)); itemCell.button.SetListener(() => ItemTipUtility.Show((int)data.ItemID, true)); float expiryDays = model.GetMailExpiryDays(mailData.CreateDateTime, mailData.LimitDays); imgHave.SetActive(mailState == 3); imgMask.SetActive(mailState == 3 || expiryDays <= 0); } } Main/System/Mail/MailInfoAwardCell.cs.meta
File was renamed from Main/System/Mail/MailGlobalCell.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 guid: baaef1e2dac4e30499722be1d4c60bb4 guid: c60bb6aac93423e46b3dfa2c1c457d0d MonoImporter: externalObjects: {} serializedVersion: 2 Main/System/Mail/MailInfoAwardItemCell.cs
File was deleted Main/System/Mail/MailInfoAwardItemCell.cs.meta
File was deleted Main/System/Mail/MailInfoWin.cs
@@ -1,4 +1,5 @@ using UnityEngine; using System; using UnityEngine; public class MailInfoWin : UIBase { [SerializeField] TextEx txtDate; @@ -7,8 +8,9 @@ [SerializeField] RichText txtNoAwardInfo; [SerializeField] Transform transAward; [SerializeField] RichText txtAwardInfo; [SerializeField] ScrollerController scrAwardItem; [SerializeField] ScrollerController scrAward; [SerializeField] TextEx txtExpiryDate; [SerializeField] ImageEx imgHasAward; [SerializeField] ButtonEx btnHave; [SerializeField] ButtonEx btnDelete; MailData nowMailData; @@ -24,23 +26,28 @@ protected override void OnPreOpen() { scrAwardItem.OnRefreshCell += OnRefreshLowRewardCell; base.OnPreOpen(); scrAward.OnRefreshCell += OnRefreshLowRewardCell; model.OnUpdateMailListEvent += OnUpdateMailListEvent; model.OnUpdateMailStateChangeEvent += OnUpdateMailStateChangeEvent; } protected override void OnOpen() { UpdateDataInfo(); GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; Display(); CreateScrAward(); } protected override void OnPreClose() { scrAwardItem.OnRefreshCell -= OnRefreshLowRewardCell; base.OnPreClose(); scrAward.OnRefreshCell -= OnRefreshLowRewardCell; model.OnUpdateMailListEvent -= OnUpdateMailListEvent; model.OnUpdateMailStateChangeEvent -= OnUpdateMailStateChangeEvent; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; } private void OnSecondEvent() { txtDate.text = model.FormatCreateMailTime(nowMailData.CreateDateTime); txtExpiryDate.text = model.FormatMailExpiryDays(nowMailData.CreateDateTime, nowMailData.LimitDays); txtExpiryDate.color = model.GetMailExpiryDays(nowMailData.CreateDateTime, nowMailData.LimitDays) >= 0 ? UIHelper.GetUIColor(TextColType.DarkGreen) : UIHelper.GetUIColor(TextColType.Red); } private void OnClickHaveButton() @@ -67,64 +74,66 @@ private void OnUpdateMailStateChangeEvent() { UpdateDataInfo(); Display(); CreateScrAward(); } private void OnUpdateMailListEvent() { UpdateDataInfo(); Display(); CreateScrAward(); } private void OnRefreshLowRewardCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<MailInfoAwardItemCell>(); var _cell = cell.GetComponent<MailInfoAwardCell>(); _cell?.Display(cell.index, cell); } private void CreateScrAward() { scrAwardItem.Refresh(); if (isHasAward) { for (int i = 0; i < nowMailData.Items.Count; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoInt1 = nowMailData.MailState; scrAwardItem.AddCell(ScrollerDataType.Header, i); } } scrAwardItem.Restart(); } private void Display() { if (nowMailData == null) if (!model.TryGetMailData(model.nowUuid, out nowMailData)) { UIManager.Instance.CloseWindow<MailInfoWin>(); return; } isHasAward = nowMailData != null && nowMailData.HasAward(); transNoAward.SetActive(!isHasAward); transAward.SetActive(isHasAward); btnHave.SetActive(isHasAward && nowMailData.MailState != 3); imgHasAward.SetActive(nowMailData.MailState != 3 && nowMailData.HasAward()); txtDate.text = model.FormatCreateMailTime(nowMailData.CreateDateTime); if (nowMailData.IsTemplateMail()) string key = nowMailData.GetTemplateKey(); if (nowMailData.IsTemplateMail() && MailConfig.HasKey(key)) { string key = nowMailData.GetTemplateKey(); if (MailConfig.HasKey(key)) MailConfig config = MailConfig.Get(key); var templateParams = nowMailData.GetTemplateParams(); // 打印出即将用于格式化的所有信息 // Debug.Log($"[邮件调试] GUID: {nowMailData.GUID}"); // Debug.Log($"[邮件调试] 原始参数JSON (nowMailData.Text): '{nowMailData.Text}'"); // Debug.Log($"[邮件调试] 解析后的参数数量: {templateParams.Count}"); // if (templateParams.Count > 0) // { // for(int i = 0; i < templateParams.Count; i++) // { // Debug.Log($"[邮件调试] 参数[{i}]: {templateParams[i]}"); // } // } try { MailConfig config = MailConfig.Get(key); var templateParams = nowMailData.GetTemplateParams(); string content = string.Format(config.Content, templateParams.ToArray()); txtTitle.text = config.Title; txtNoAwardInfo.text = content; txtAwardInfo.text = content; txtTitle.text = config.Title; } else catch (System.Exception ex) { txtTitle.text = nowMailData.Title; txtNoAwardInfo.text = nowMailData.Text; txtAwardInfo.text = nowMailData.Text; Debug.LogError($"MailInfoWin 解析邮件参数失败! GUID: {nowMailData.GUID}, " + $"原始参数JSON: '{nowMailData.Text}', 错误: {ex.Message}"); } } else @@ -133,19 +142,20 @@ txtNoAwardInfo.text = nowMailData.Text; txtAwardInfo.text = nowMailData.Text; } int expiryDays = model.GetMailExpiryDays(nowMailData.CreateDateTime, nowMailData.LimitDays); txtExpiryDate.text = expiryDays > 0 ? Language.Get("Mail07", expiryDays) : string.Empty; } private void UpdateDataInfo() { if (!model.TryGetMailData(model.nowUuid, out nowMailData)) txtExpiryDate.text = model.FormatMailExpiryDays(nowMailData.CreateDateTime, nowMailData.LimitDays); txtExpiryDate.color = model.GetMailExpiryDays(nowMailData.CreateDateTime, nowMailData.LimitDays) >= 0 ? UIHelper.GetUIColor(TextColType.DarkGreen) : UIHelper.GetUIColor(TextColType.Red); scrAward.Refresh(); if (isHasAward) { UIManager.Instance.CloseWindow<MailInfoWin>(); for (int i = 0; i < nowMailData.Items.Count; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoStr1 = nowMailData.GUID; scrAward.AddCell(ScrollerDataType.Header, i, cellInfo); } } isHasAward = nowMailData != null && nowMailData.Items != null; scrAward.Restart(); } } Main/System/Mail/MailManager.cs
@@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; using LitJson; public class MailManager : GameSystemManager<MailManager> { @@ -17,13 +19,15 @@ public Redpoint tabRedpoint1; public event Action OnUpdateMailListEvent;// 更新邮件列表数据 public event Action OnUpdateMailStateChangeEvent;// 更新邮件状态变更 public readonly string dateFormat = "yyyy-MM-dd"; public readonly string dateFormat = "yyyy.MM.dd"; public string nowUuid = string.Empty; public int personalMailMaxLimitCount; public override void Init() { tabRedpoint0 = new Redpoint(MainRedDot.MailRepoint, GetTabRedpointId(MailCategory.Personal)); tabRedpoint1 = new Redpoint(MainRedDot.MailRepoint, GetTabRedpointId(MailCategory.Global)); DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent; personalMailMaxLimitCount = int.Parse(FuncConfigConfig.Get("PersonalMail").Numerical1); } public override void Release() @@ -103,11 +107,50 @@ } } //返回有效期天数(正数=已过期天数,负数=剩余天数) public int GetMailExpiryDays(DateTime createDateTime, int limitDays) //返回有效期天数(正数=剩余天数,负数=已过期天数) public float GetMailExpiryDays(DateTime createDateTime, int limitDays) { DateTime expiryDate = createDateTime.AddDays(limitDays); return (int)(TimeUtility.ServerNow - expiryDate).TotalDays; TimeSpan remainingTime = expiryDate - TimeUtility.ServerNow; return (float)remainingTime.TotalDays; } public string FormatMailExpiryDays(DateTime createDateTime, int limitDays) { string result = string.Empty; float days = GetMailExpiryDays(createDateTime, limitDays); // 防护:处理因客户端与服务器时间戳的微小差异,导致剩余时间略大于有效期上限的情况。 // 将计算出的剩余天数限制在邮件的有效期天数之内。 if (days > limitDays) { days = limitDays; } if (days > 1.0f) { // 大于1天:按向上取整的天数显示。 // MathF.Ceiling(1.01f) -> 2.0f int daysRounded = (int)MathF.Ceiling(days); result = Language.Get("Mail07", (int)MathF.Ceiling(days)); } else if (days > 0.0f) { // 小于1天(但未过期):按精确的小时/分钟显示。 TimeSpan t = TimeSpan.FromDays(days); result = Language.Get("Mail12",StringUtility.Contact( " ", Language.Get("Mail13", t.Hours, t.Minutes))); } else { // (预留)已过期:按负数向下取整(向更小的负数取整,以获得已过期天数的整数绝对值) // MathF.Floor(-1.01f) -> -2.0f // MathF.Floor(-0.5f) -> -1.0f // float expiredDaysFloor = MathF.Floor(days); // int expiredDays = (int)expiredDaysFloor; //直接显示已过期 result = Language.Get("Mail11"); ; } return result; } @@ -123,6 +166,20 @@ } return result; } public int GetMailCount(MailCategory mailCategory) { var result = new List<string>(); foreach (var kvp in mailDataDict) { if (kvp.Value.Category == mailCategory) { result.Add(kvp.Key); } } return result.Count; } public List<string> GetSortMailScrList(MailCategory mailCategory) { @@ -161,6 +218,16 @@ IsBind = i.IsBind, UserData = i.UserData }).ToList(); if (!mailData.Items.IsNullOrEmpty()) { mailData.Items = mailData.Items .Where(item => ItemConfig.HasKey((int)item.ItemID)) // 防护,确保物品存在 .OrderByDescending(item => ItemConfig.Get((int)item.ItemID).ItemColor) // 按品质降序 .ThenBy(item => item.Count) // 品质相同按数量升序 .ToList(); } mailDataDict[mail.GUID] = mailData; } @@ -239,7 +306,7 @@ pack.ReqType = ReqType; GameNetSystem.Instance.SendInfo(pack); } //没有一个可领取的个人邮件 public bool IsCanHaveMail() { @@ -273,12 +340,17 @@ public string GUID; //邮件GUID public byte Type; //邮件类型,暂时默认0 public string CreateTime; //创建时间 public DateTime CreateDateTime; public DateTime CreateDateTime;//创建时间 public byte LimitDays; //有效天数 public string Title; //标题 public string Text; //内容 public byte MailState; //邮件状态: 0-未知;1-未读;2-已读;3-已领; public List<MailItemData> Items; //物品信息 public bool HasAward() { return Items != null && Items.Count > 0; } /// <summary> /// 判断是否为模板类型邮件 @@ -320,12 +392,15 @@ try { // 参数格式为JSON数组:[参数1, 参数2, ...] return JsonUtility.FromJson<List<string>>(Text); List<string> result = JsonMapper.ToObject<List<string>>(Text); // 如果解析结果为null(例如Text的内容是 "null" 字符串),则返回一个空列表以防后续出错 return result ?? new List<string>(); } catch catch (Exception ex) { Debug.LogError($"使用 LitJson 解析邮件参数失败。 Text: {Text}, 错误: {ex.Message}"); return new List<string>(); } } } Main/System/Mail/MailPersonalCell.cs
File was deleted Main/System/Mail/MailPersonalCell.cs.meta
File was deleted Main/System/Mail/MailWin.cs
@@ -1,89 +1,87 @@ using System; using UnityEngine; public class MailWin : UIBase public class MailWin : FunctionsBaseWin { [SerializeField] Transform transPersonal; [SerializeField] Transform transGlobal; [SerializeField] ScrollerController scrPersonal; [SerializeField] ScrollerController scrGlobal; [SerializeField] ButtonEx btnDeleteRead; [SerializeField] ScrollerController scrMail; [SerializeField] ButtonEx btnDeleteAllRead; [SerializeField] ButtonEx btnClaimAll; [SerializeField] ToggleEx togTab0; [SerializeField] RedpointBehaviour rpTab0; [SerializeField] ToggleEx togTab1; [SerializeField] RedpointBehaviour rpTab1; [SerializeField] Transform transNoMail; [SerializeField] Transform transCurrentMailCount; [SerializeField] TextEx txtCurrentMailCount; MailManager model { get { return MailManager.Instance; } } protected override void InitComponent() { base.InitComponent(); btnDeleteRead.SetListener(OnDeleteRead); btnDeleteAllRead.SetListener(OnDeleteRead); btnClaimAll.SetListener(OnClaimAll); togTab0.SetListener(OnTab0); togTab1.SetListener(OnTab1); } protected override void OnPreOpen() { model.OnUpdateMailListEvent += OnUpdateMailListEvent; model.OnUpdateMailStateChangeEvent += OnUpdateMailStateChangeEvent; scrPersonal.OnRefreshCell += OnRefreshPersonalCell; scrGlobal.OnRefreshCell += OnRefreshGlobalCell; base.OnPreOpen(); tabButtons[functionOrder].SelectBtn(true); model.nowMailCategory = MailCategory.Personal; rpTab0.redpointId = model.GetTabRedpointId(MailCategory.Personal); rpTab1.redpointId = model.GetTabRedpointId(MailCategory.Global); transNoMail.SetActive(false); transNoMail.SetActive(true); btnDeleteAllRead.SetActive(true); btnClaimAll.SetActive(true); transCurrentMailCount.SetActive(true); model.OnUpdateMailListEvent += OnUpdateMailListEvent; model.OnUpdateMailStateChangeEvent += OnUpdateMailStateChangeEvent; scrMail.OnRefreshCell += OnRefreshCell; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; DisPlay(); } protected override void OnPreClose() { base.OnPreClose(); model.OnUpdateMailListEvent -= OnUpdateMailListEvent; model.OnUpdateMailStateChangeEvent -= OnUpdateMailStateChangeEvent; scrPersonal.OnRefreshCell -= OnRefreshPersonalCell; scrGlobal.OnRefreshCell -= OnRefreshGlobalCell; scrMail.OnRefreshCell -= OnRefreshCell; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; } private void OnTab0(bool value) private void OnSecondEvent() { if (value) scrMail.m_Scorller.RefreshActiveCellViews(); int personalMailCount = MailManager.Instance.GetMailCount(MailCategory.Personal); txtCurrentMailCount.text = StringUtility.Contact(personalMailCount, "/", MailManager.Instance.personalMailMaxLimitCount); } protected override void OpenSubUIByTabIndex() { switch (functionOrder) { transPersonal.SetActive(true); transGlobal.SetActive(false); model.nowMailCategory = MailCategory.Personal; CreatePersonalScr(model.nowMailCategory); case 0: model.nowMailCategory = MailCategory.Personal; btnDeleteAllRead.SetActive(true); btnClaimAll.SetActive(true); transCurrentMailCount.SetActive(true); int personalMailCount = MailManager.Instance.GetMailCount(MailCategory.Personal); txtCurrentMailCount.text = StringUtility.Contact(personalMailCount, "/", MailManager.Instance.personalMailMaxLimitCount); DisPlay(); break; case 1: model.nowMailCategory = MailCategory.Global; btnDeleteAllRead.SetActive(false); btnClaimAll.SetActive(false); transCurrentMailCount.SetActive(false); DisPlay(); break; default: Debug.LogWarning("未知的标签索引: " + functionOrder); break; } } private void OnTab1(bool value) private void OnRefreshCell(ScrollerDataType type, CellView cell) { if (value) { transPersonal.SetActive(false); transGlobal.SetActive(true); model.nowMailCategory = MailCategory.Global; CreateGlobalScr(model.nowMailCategory); } } protected override void OnOpen() { togTab0.isOn = true; togTab1.isOn = false; model.nowMailCategory = MailCategory.Personal; CreatePersonalScr(model.nowMailCategory); } private void OnRefreshPersonalCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<MailPersonalCell>(); _cell?.Display(cell.index, cell); } private void OnRefreshGlobalCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<MailGlobalCell>(); var _cell = cell.GetComponent<MailCell>(); _cell?.Display(cell.index, cell); } @@ -113,50 +111,24 @@ model.ClaimMail(); } public void CreatePersonalScr(MailCategory mailCategory) { scrPersonal.Refresh(); var list = model.GetSortMailScrList(mailCategory); if (list != null) { for (int i = 0; i < list.Count; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoInt1 = (int)mailCategory; scrPersonal.AddCell(ScrollerDataType.Header, i, cellInfo); } } scrPersonal.Restart(); } public void CreateGlobalScr(MailCategory mailCategory) { scrGlobal.Refresh(); var list = model.GetSortMailScrList(mailCategory); if (list != null) { for (int i = 0; i < list.Count; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoInt1 = (int)mailCategory; scrGlobal.AddCell(ScrollerDataType.Header, i, cellInfo); } } scrGlobal.Restart(); } private void OnUpdateMailStateChangeEvent() { RefreshScr(); DisPlay(); } private void OnUpdateMailListEvent() { RefreshScr(); DisPlay(); } private void RefreshScr() { var list = model.GetSortMailScrList(model.nowMailCategory); private void DisPlay() { scrMail.Refresh(); scrMail.Restart(); MailCategory mailCategory = model.nowMailCategory; var list = model.GetSortMailScrList(mailCategory); if (list.IsNullOrEmpty()) { transNoMail.SetActive(true); @@ -164,9 +136,20 @@ else { transNoMail.SetActive(false); scrPersonal.m_Scorller.RefreshActiveCellViews(); scrGlobal.m_Scorller.RefreshActiveCellViews(); scrMail.Refresh(); for (int i = 0; i < list.Count; i++) { CellInfo cellInfo = new CellInfo(); cellInfo.infoInt1 = (int)mailCategory; scrMail.AddCell(ScrollerDataType.Header, i, cellInfo); } scrMail.Restart(); } int personalMailCount = MailManager.Instance.GetMailCount(MailCategory.Personal); txtCurrentMailCount.text = StringUtility.Contact(personalMailCount, "/", MailManager.Instance.personalMailMaxLimitCount); } } Main/System/Main/HomeWin.cs
@@ -49,6 +49,7 @@ [SerializeField] UIEffectPlayer autoOpenEffect; [SerializeField] Button blessLVBtn; [SerializeField] Text blessLVText; [SerializeField] Button mailBtn; //其他功能入口 [SerializeField] Button monthCardBtn; @@ -87,6 +88,11 @@ UIManager.Instance.OpenWindow<BlessLVWin>(); }); mailBtn.AddListener(() => { UIManager.Instance.OpenWindow<MailWin>(); }); officialUpBtn.AddListener(() => { if (RealmConfig.GetKeys().Count <= PlayerDatas.Instance.baseData.realmLevel) Main/System/Main/MainWin.cs
@@ -24,9 +24,10 @@ [SerializeField] Image fightHeroImg; //战斗显示英雄 [SerializeField] ScaleTween fightHeroScale; //战斗显示英雄缩放 [SerializeField] UIEffectPlayer fightEffect; [SerializeField] UIEffectPlayer openCloseAnim; [SerializeField] FillTween cdTween; public bool isFirstOpen = true; //首次打开 public Text hammerText; protected override void InitComponent() @@ -77,6 +78,7 @@ return; } ClickAnimation(index); // 更新当前选中的标签索引 functionOrder = index; @@ -87,6 +89,27 @@ OpenSubUIByTabIndex(); } void ClickAnimation(int index) { if (isFirstOpen || (functionOrder != 0 && index == 0)) { openCloseAnim.onComplete = () => { openCloseAnim.SetEnabled(true); }; openCloseAnim.PlayByArrIndex(1); isFirstOpen = false; } else if (functionOrder == 0 && index != 0) { openCloseAnim.onComplete = () => { openCloseAnim.SetEnabled(true); }; openCloseAnim.PlayByArrIndex(0); } } /// <summary> @@ -224,6 +247,7 @@ { //主城界面 fightOtherWinBG.SetActive(false); fightOtherWinWarnImg.SetActive(false); fightBG.SetActive(true); @@ -259,6 +283,7 @@ } void RefreshFightIng(bool isfighting = false) { if (isfighting) Main/Utility/JaceCalculator.cs
@@ -35,7 +35,8 @@ } public static void Init() { { Engine.AddFunction("int", (Func<double, double>)(x => (int)x)); Engine.AddFunction("long", (Func<double, double>)(x => (long)x)); } }