Main/Config/ConfigManager.cs
@@ -38,6 +38,14 @@ // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 // 加载配置文件 HashSet<Type> configTypes = new HashSet<Type>() { typeof(ActBillboardAwardConfig), typeof(ActHeroAppearArtConfig), @@ -50,10 +58,13 @@ typeof(ActSpecialSaleConfig), typeof(ActTaskConfig), typeof(ActTaskTempConfig), typeof(ActTimeConfig), typeof(ActTimeFlowConfig), typeof(ActTotalRechargeConfig), typeof(ActTotalRechargeTempConfig), typeof(ActTotDayRechargeConfig), typeof(ActTotDayRechargeTempConfig), typeof(ActTypeConfig), typeof(ADAwardConfig), typeof(BattleMapConfig), typeof(BeautyConfig), @@ -306,6 +317,10 @@ ClearConfigDictionary<ActTaskConfig>(); // 清空 ActTaskTempConfig 字典 ClearConfigDictionary<ActTaskTempConfig>(); // 清空 ActTimeConfig 字典 ClearConfigDictionary<ActTimeConfig>(); // 清空 ActTimeFlowConfig 字典 ClearConfigDictionary<ActTimeFlowConfig>(); // 清空 ActTotalRechargeConfig 字典 ClearConfigDictionary<ActTotalRechargeConfig>(); // 清空 ActTotalRechargeTempConfig 字典 @@ -314,6 +329,8 @@ ClearConfigDictionary<ActTotDayRechargeConfig>(); // 清空 ActTotDayRechargeTempConfig 字典 ClearConfigDictionary<ActTotDayRechargeTempConfig>(); // 清空 ActTypeConfig 字典 ClearConfigDictionary<ActTypeConfig>(); // 清空 ADAwardConfig 字典 ClearConfigDictionary<ADAwardConfig>(); // 清空 BattleMapConfig 字典 Main/Config/Configs/ActTimeConfig.cs
New file @@ -0,0 +1,50 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: Thursday, July 2, 2026 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class ActTimeConfig : ConfigBase<int, ActTimeConfig> { static ActTimeConfig() { // 访问过静态构造函数 visit = true; } public int CfgID; public int ActNum; public string ActFlow; public int ActFuncType; public int ActTempID; 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 CfgID); int.TryParse(tables[1],out ActNum); ActFlow = tables[2]; int.TryParse(tables[3],out ActFuncType); int.TryParse(tables[4],out ActTempID); } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/ActTimeConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 6fcca7d3328b986479acbe95affd4556 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/Configs/ActTimeFlowConfig.cs
New file @@ -0,0 +1,62 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2026年7月2日 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class ActTimeFlowConfig : ConfigBase<int, ActTimeFlowConfig> { static ActTimeFlowConfig() { // 访问过静态构造函数 visit = true; } public int ID; public string ActFlow; public int StartDay; public int StartHour; public int StartMinute; public int EndDay; public int EndHour; public int EndMinute; public int StateValue; 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); ActFlow = tables[1]; int.TryParse(tables[2],out StartDay); int.TryParse(tables[3],out StartHour); int.TryParse(tables[4],out StartMinute); int.TryParse(tables[5],out EndDay); int.TryParse(tables[6],out EndHour); int.TryParse(tables[7],out EndMinute); int.TryParse(tables[8],out StateValue); } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/ActTimeFlowConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 47860d5770f7897429c9ae853fc82e59 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/Configs/ActTypeConfig.cs
New file @@ -0,0 +1,80 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2026年7月2日 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class ActTypeConfig : ConfigBase<int, ActTypeConfig> { static ActTypeConfig() { // 访问过静态构造函数 visit = true; } public int CfgID; public int ActFuncType; public int ActTempID; public int JoinFamilyCnt; public int ActShopType; public int ADID; public int[] CTGIDList; public int CTGAssistTempID; public int GuessTempID; public int PersonalTempID; public int FamilyTemplID; 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 CfgID); int.TryParse(tables[1],out ActFuncType); int.TryParse(tables[2],out ActTempID); int.TryParse(tables[3],out JoinFamilyCnt); int.TryParse(tables[4],out ActShopType); int.TryParse(tables[5],out ADID); if (tables[6].Contains("[")) { CTGIDList = JsonMapper.ToObject<int[]>(tables[6]); } else { string[] CTGIDListStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); CTGIDList = new int[CTGIDListStringArray.Length]; for (int i=0;i<CTGIDListStringArray.Length;i++) { int.TryParse(CTGIDListStringArray[i],out CTGIDList[i]); } } int.TryParse(tables[7],out CTGAssistTempID); int.TryParse(tables[8],out GuessTempID); int.TryParse(tables[9],out PersonalTempID); int.TryParse(tables[10],out FamilyTemplID); } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/ActTypeConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 4eb6bc33c43c6d248a6cc06bf0928533 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/PartialConfigs/ActTimeFlowConfig.cs
New file @@ -0,0 +1,29 @@ using System.Collections.Generic; public partial class ActTimeFlowConfig : ConfigBase<int, ActTimeFlowConfig> { static Dictionary<string, List<ActTimeFlowConfig>> flowDict = new Dictionary<string, List<ActTimeFlowConfig>>(); protected override void OnConfigParseCompleted() { if (!flowDict.ContainsKey(ActFlow)) flowDict[ActFlow] = new List<ActTimeFlowConfig>(); flowDict[ActFlow].Add(this); } public static List<ActTimeFlowConfig> GetByActFlow(string actFlow) { if (!flowDict.TryGetValue(actFlow, out var list) || list == null) return new List<ActTimeFlowConfig>(); var sorted = new List<ActTimeFlowConfig>(list); sorted.Sort((a, b) => { int c = a.StartDay.CompareTo(b.StartDay); if (c != 0) return c; c = a.StartHour.CompareTo(b.StartHour); if (c != 0) return c; return a.StartMinute.CompareTo(b.StartMinute); }); return sorted; } } Main/Config/PartialConfigs/ActTimeFlowConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 447d8b9a08c6a22479478123eac98628 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/PartialConfigs/ActTypeConfig.cs
New file @@ -0,0 +1,71 @@ using System.Collections.Generic; using UnityEngine; public partial class ActTypeConfig : ConfigBase<int, ActTypeConfig> { // 注:CfgID 从 1 开始,0 用作 GetCfgID/TryGetCfgID 的"未命中"占位返回值 //<功能类型,<模板ID,配置ID>> static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>(); // 配置行解析完成回调:建立 ActFuncType → ActTempID → CfgID 二级索引,重复组合会告警 protected override void OnConfigParseCompleted() { if (!infoDict.ContainsKey(ActFuncType)) infoDict[ActFuncType] = new Dictionary<int, int>(); if (infoDict[ActFuncType].ContainsKey(ActTempID)) { Debug.LogError(typeof(ActTypeConfig).Name + " 重复的 ActFuncType " + ActFuncType + " ActTempID " + ActTempID + " 旧CfgID " + infoDict[ActFuncType][ActTempID] + " 新CfgID " + CfgID); } infoDict[ActFuncType][ActTempID] = CfgID; } // 通过活动功能类型和模板ID查询配置ID,未命中返回 0 public static int GetCfgID(int actFuncType, int actTempID) { return infoDict.TryGetValue(actFuncType, out var info) && info.TryGetValue(actTempID, out var cfgID) ? cfgID : 0; } // 尝试通过活动功能类型和模板ID查询配置ID,命中返回 true public static bool TryGetCfgID(int actFuncType, int actTempID, out int cfgID) { cfgID = 0; return infoDict != null && infoDict.TryGetValue(actFuncType, out var info) && info.TryGetValue(actTempID, out cfgID); } // 通过活动功能类型和模板ID获取配置,未命中返回 null public static ActTypeConfig GetConfig(int actFuncType, int actTempID) { int cfgID = GetCfgID(actFuncType, actTempID); return cfgID == 0 ? null : Get(cfgID); } // 通过配置ID获取配置,未命中返回 false public static bool TryGetConfig(int cfgID, out ActTypeConfig config) { config = null; if (!HasKey(cfgID)) return false; config = Get(cfgID); return true; } // 通过活动功能类型和模板ID获取配置,未命中返回 false public static bool TryGetConfig(int actFuncType, int actTempID, out ActTypeConfig config) { config = null; if (!TryGetCfgID(actFuncType, actTempID, out int cfgID)) return false; return TryGetConfig(cfgID, out config); } // 获取指定活动功能类型下的全部配置ID public static List<int> GetCfgIDsByFuncType(int actFuncType) { List<int> result = new List<int>(); if (infoDict.TryGetValue(actFuncType, out var info)) { result.AddRange(info.Values); } return result; } } Main/Config/PartialConfigs/ActTypeConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: ad332adb5561d3d4e96d0d7278e81601 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA25_tagCSActLianqiOP.cs
New file @@ -0,0 +1,24 @@ using UnityEngine; using System.Collections; // AA 25 炼器操作 #tagCSActLianqiOP public class CAA25_tagCSActLianqiOP : GameNetPackBasic { public byte OPType; // 1-移动;2-使用道具;3-重新开始;4-领取等级奖励;5-领取榜单奖励 public uint OPValue; // 移动时-发1上2下3左4右;使用道具时-发使用个数*10+道具ID所在配置索引;等级奖励时-发领取的奖励等级 public uint OPValue2; // 使用道具时-发选中格子A的行列值 行*10+列 public uint OPValue3; // 使用道具时-发选中格子B的行列值 行*10+列 public CAA25_tagCSActLianqiOP () { combineCmd = (ushort)0x03FE; _cmd = (ushort)0xAA25; } public override void WriteToBytes () { WriteBytes (OPType, NetDataType.BYTE); WriteBytes (OPValue, NetDataType.DWORD); WriteBytes (OPValue2, NetDataType.DWORD); WriteBytes (OPValue3, NetDataType.DWORD); } } Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA25_tagCSActLianqiOP.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: bad8f07ed5cf8724e80d5f737617f8dd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA90_tagSCActLianqiInfo.cs
New file @@ -0,0 +1,13 @@ using UnityEngine; using System.Collections; // AA 90 炼器跨服活动信息 #tagSCActLianqiInfo public class DTCAA90_tagSCActLianqiInfo : DtcBasic { public override void Done(GameNetPackBasic vNetPack) { base.Done(vNetPack); HAA90_tagSCActLianqiInfo vNetData = vNetPack as HAA90_tagSCActLianqiInfo; OperationTimeHepler.Instance.UpdateCrossActLianqiInfo(vNetData); } } Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA90_tagSCActLianqiInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 9a99e20beaa9ab143bb352ee87bdd090 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA91_tagSCActLianqiPlayerInfo.cs
New file @@ -0,0 +1,12 @@ using UnityEngine; using System.Collections; // AA 91 炼器活动玩家信息 #tagSCActLianqiPlayerInfo public class DTCAA91_tagSCActLianqiPlayerInfo : DtcBasic { public override void Done(GameNetPackBasic vNetPack) { base.Done(vNetPack); HAA91_tagSCActLianqiPlayerInfo vNetData = vNetPack as HAA91_tagSCActLianqiPlayerInfo; LianQiManager.Instance.UpdateActLianqiPlayerInfo(vNetData); } } Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA91_tagSCActLianqiPlayerInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 64b6cfa4866f22d4f8a122f07fe76ca9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -174,6 +174,8 @@ Register(typeof(HAA72_tagSCActTaskPlayerValueInfo), typeof(DTCAA72_tagSCActTaskPlayerValueInfo)); Register(typeof(HAA73_tagSCActTaskPlayerInfo), typeof(DTCAA73_tagSCActTaskPlayerInfo)); Register(typeof(HA525_tagSCFamilyAtkDefBatInfo), typeof(DTCA525_tagSCFamilyAtkDefBatInfo)); Register(typeof(HAA90_tagSCActLianqiInfo), typeof(DTCAA90_tagSCActLianqiInfo)); Register(typeof(HAA91_tagSCActLianqiPlayerInfo), typeof(DTCAA91_tagSCActLianqiPlayerInfo)); } //主工程注册封包 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA90_tagSCActLianqiInfo.cs
New file @@ -0,0 +1,29 @@ using UnityEngine; using System.Collections; // AA 90 炼器跨服活动信息 #tagSCActLianqiInfo public class HAA90_tagSCActLianqiInfo : GameNetPackBasic { public ushort ServerLen; public string ServerIDInfo; // 活动服务器ID信息,[[从服务器IDA, 到服务器IDB], 或指定某个服务器ID, ...] public uint CrossServerID; // 所属跨服服务器ID public uint ZoneID; // 所属分区,也是活动榜单分组值GroupValue1,用于查询对应榜单 public string StartDate; // 开始日期 y-m-d public string EndtDate; // 结束日期 y-m-d public ushort CfgID; // 活动时间表配置ID public HAA90_tagSCActLianqiInfo () { _cmd = (ushort)0xAA90; } public override void ReadFromBytes (byte[] vBytes) { TransBytes (out ServerLen, vBytes, NetDataType.WORD); TransBytes (out ServerIDInfo, vBytes, NetDataType.Chars, ServerLen); TransBytes (out CrossServerID, vBytes, NetDataType.DWORD); TransBytes (out ZoneID, vBytes, NetDataType.DWORD); TransBytes (out StartDate, vBytes, NetDataType.Chars, 10); TransBytes (out EndtDate, vBytes, NetDataType.Chars, 10); TransBytes (out CfgID, vBytes, NetDataType.WORD); } } Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA90_tagSCActLianqiInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: c740d821af03f144eba03eae95f4ac10 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA91_tagSCActLianqiPlayerInfo.cs
New file @@ -0,0 +1,57 @@ using UnityEngine; using System.Collections; // AA 91 炼器活动玩家信息 #tagSCActLianqiPlayerInfo public class HAA91_tagSCActLianqiPlayerInfo : GameNetPackBasic { public uint Score; // 当前活动积分 public uint ScoreHighest; // 当前活动最高积分,即上榜积分 public ushort Energy; // 当前体力 public uint EnergyTime; // 上次恢复体力时间戳,为0时不用处理倒计时 public uint LVAwardMax; // 已激活的最大合成奖励等级 public uint LVAwardState; // 最大合成等级奖励领取记录,按等级二进制位存储是否已领取 public byte BillAwardState; // 榜单奖励是否已领取 public byte UseItemLen; public ushort[] UseItemCntList; // 本局已使用辅助道具次数 [辅助道具1使用次数, ...] public byte GridDataLen; // 格子数据长度 public string GridData; // 格子二维行列数据,一定会同步,直接替换,行从上往下排 [[第1行格子1,格子2, ...], ...] public byte OPType; // 0-无(如初始化,GM等后端直接设置);1-移动;2-使用道具;3-重新开始;如果是因为操作引起的格子数据变化,则在相关操作表现完毕后再展示最新行列数据,否则直接变更 public byte MoveCount; public tagSCActLianqiTileMove[] MoveList; // 图块移动列表,可能没有数据,有的话先表现移动 public HAA91_tagSCActLianqiPlayerInfo () { _cmd = (ushort)0xAA91; } public override void ReadFromBytes (byte[] vBytes) { TransBytes (out Score, vBytes, NetDataType.DWORD); TransBytes (out ScoreHighest, vBytes, NetDataType.DWORD); TransBytes (out Energy, vBytes, NetDataType.WORD); TransBytes (out EnergyTime, vBytes, NetDataType.DWORD); TransBytes (out LVAwardMax, vBytes, NetDataType.DWORD); TransBytes (out LVAwardState, vBytes, NetDataType.DWORD); TransBytes (out BillAwardState, vBytes, NetDataType.BYTE); TransBytes (out UseItemLen, vBytes, NetDataType.BYTE); TransBytes (out UseItemCntList, vBytes, NetDataType.WORD, UseItemLen); TransBytes (out GridDataLen, vBytes, NetDataType.BYTE); TransBytes (out GridData, vBytes, NetDataType.Chars, GridDataLen); TransBytes (out OPType, vBytes, NetDataType.BYTE); TransBytes (out MoveCount, vBytes, NetDataType.BYTE); MoveList = new tagSCActLianqiTileMove[MoveCount]; for (int i = 0; i < MoveCount; i ++) { MoveList[i] = new tagSCActLianqiTileMove(); TransBytes (out MoveList[i].Row, vBytes, NetDataType.BYTE); TransBytes (out MoveList[i].Col, vBytes, NetDataType.BYTE); TransBytes (out MoveList[i].ToRow, vBytes, NetDataType.BYTE); TransBytes (out MoveList[i].ToCol, vBytes, NetDataType.BYTE); } } public class tagSCActLianqiTileMove { public byte Row; // 行,0为第1行 public byte Col; // 列,0为第1列 public byte ToRow; // 移动到目标行 public byte ToCol; // 移动到目标列 } } Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA91_tagSCActLianqiPlayerInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: d47f7cbada3f84b48b8a6ab37cf094ef MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Main.cs
@@ -126,6 +126,7 @@ managers.Add(HeroSkinFlashSaleManager.Instance); managers.Add(GuildAtkDefBatManager.Instance); managers.Add(HeroTrialManager.Instance); managers.Add(LianQiManager.Instance); foreach (var manager in managers) { Main/System/BattlePass/BattlePassManager.cs
@@ -375,7 +375,10 @@ //通关 return layerNum * 100 + levelNum; } case BattlePassType.LianQi: { return (int)battlePassData.value1; } } @@ -422,4 +425,5 @@ Week = 6, //周战令 BetterMainLine = 7, //高级关卡基金 DJG = 8, // 定军阁 LianQi = 9, // 炼器大会 } Main/System/LianQi.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 1319eea20bd178749b0fe96b53fe6909 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/DragSelectComponentEx.cs
New file @@ -0,0 +1,99 @@ using System; using UnityEngine; using UnityEngine.EventSystems; using System.Collections.Generic; [DisallowMultipleComponent] public class DragSelectComponentEx : MonoBehaviour { [SerializeField] float m_Sensitive = 10f; [SerializeField] GameObject m_TargetObject; public event Action<int> onDragComplete; private bool m_StartDrag = false; Vector3 start_position = Vector3.zero; bool isArea = false; private void LateUpdate() { if (Input.touchCount > 1) { m_StartDrag = false; return; } if (Input.GetMouseButtonDown(0)) { m_StartDrag = true; start_position = Input.mousePosition; isArea = RectTransformUtility.RectangleContainsScreenPoint(this.transform as RectTransform, start_position, CameraManager.uiCamera); if (!IsOverTarget()) { m_StartDrag = false; return; } } else if (Input.GetMouseButtonUp(0) && m_StartDrag) { var delta = Input.mousePosition - start_position; m_StartDrag = false; // 判断滑动方向 if (Mathf.Abs(delta.x) >= m_Sensitive || Mathf.Abs(delta.y) >= m_Sensitive) { int direction = 0; // 水平方向优先 if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) { direction = delta.x > 0 ? 1 : -1; // 1 表示向右滑动,-1 表示向左滑动 } // 垂直方向优先 else { direction = delta.y > 0 ? 2 : -2; // 2 表示向上滑动,-2 表示向下滑动 } // 新增目标对象检测条件 if (onDragComplete != null && isArea) { onDragComplete(direction); } } } } // 新增目标检测方法 private bool IsOverTarget() { if (m_TargetObject == null) return true; PointerEventData eventData = new PointerEventData(EventSystem.current) { position = Input.mousePosition }; List<RaycastResult> results = new List<RaycastResult>(); EventSystem.current.RaycastAll(eventData, results); if (results.Count > 0) { RaycastResult result = results[0]; if (result.gameObject == m_TargetObject) { return true; } if (result.gameObject.transform.parent.gameObject == m_TargetObject) { return true; } } return false; } private void OnDisable() { m_StartDrag = false; } } Main/System/LianQi/DragSelectComponentEx.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 6d85f87c3c94502408fe0bcd595e7278 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiActLevel1.cs
New file @@ -0,0 +1,7 @@ using UnityEngine; public class LianQiActLevel1 : MonoBehaviour { public ImageEx imgItem; public TextEx txtLv; } Main/System/LianQi/LianQiActLevel1.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 084cabb1f52e0d04f8b140b81bbe0e35 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiActLevel2.cs
New file @@ -0,0 +1,14 @@ using UnityEngine; public class LianQiActLevel2 : MonoBehaviour { public int row; public int col; public ImageEx imgItem; public UIEffectPlayer synUIEffect; public UIEffectPlayer hammerUIEffect; public bool isChooseShow = false; public ImageEx imgChoose; public ButtonEx btnChoose; public TextEx txtLv; } Main/System/LianQi/LianQiActLevel2.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 46aa030177529cf46864e0292c216f37 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiAwardCell.cs
New file @@ -0,0 +1,75 @@ using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; public class LianQiAwardCell : CellView { [SerializeField] ImageEx imgCorrespondItem; [SerializeField] ButtonEx btnCorrespondItem; [SerializeField] ImageEx imgProgressBar; [SerializeField] ImageEx imgHaveBG; [SerializeField] TextEx txtItemCount; [SerializeField] Transform transPoint; [SerializeField] Transform transCanHave; LianQiManager M => LianQiManager.Instance; public void Display(int index) { Dictionary<int, List<Item>> correspondingRewards = M.correspondingRewards; if (correspondingRewards == null) return; int[] keysArr = new int[correspondingRewards.Count]; int _idx = 0; foreach (int key in correspondingRewards.Keys) { keysArr[_idx] = key; _idx++; } if (index < 0 || keysArr.Length <= index) return; int awardLv = keysArr[index]; HAA91_tagSCActLianqiPlayerInfo info = M.nowPlayerInfo; if (info == null) return; LianQiCompositeItemInfo itemInfo; if (!M.TryGetCompositeItemInfoByAwardLv(awardLv, out itemInfo) || itemInfo == null) return; bool isItemCountShow = awardLv >= M.MaxItemLv; txtItemCount.SetActive(isItemCountShow); if (isItemCountShow) { int itemCount = awardLv - M.MaxItemLv + 1; txtItemCount.text = StringUtility.Concat("X", itemCount.ToString()); } //0 不可领取 1 可领取 2 已领取 int state = M.GetAwardState(awardLv, (int)info.LVAwardState, (int)info.LVAwardMax); imgHaveBG.SetActive(state == 2); imgProgressBar.SetActive(state != 0); imgCorrespondItem.SetSprite(itemInfo.Icon); imgCorrespondItem.SetNativeSize(); imgCorrespondItem.gray = state == 2; transCanHave.SetActive(state == 1); btnCorrespondItem.SetListener(() => { if (state == 1) { M.ClaimReward(); } else { LianQiSmallTipWin.worldPos = transPoint.position; LianQiSmallTipWin.showAwardLv = awardLv; LianQiSmallTipWin.isDownShow = true; UIManager.Instance.OpenWindow<LianQiSmallTipWin>(); } }); } } Main/System/LianQi/LianQiAwardCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: b2a508bea89d8fe4681cca10aeea85f9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiAwardWin.cs
New file @@ -0,0 +1,174 @@ using System.Collections.Generic; using UnityEngine; public class LianQiAwardWin : UIBase { [SerializeField] ScrollerController awardScroller; [HideInInspector] public string valueFormat = "{0}"; [SerializeField] TextEx myScore;//语言表: [SerializeField] TextEx myRank; [SerializeField] ScrollerController myAwardScroller; [SerializeField] ButtonEx getButton; [SerializeField] ImageEx getImage; [SerializeField] ImageEx redImage; LianQiManager manager => LianQiManager.Instance; bool hasRankRefresh = false; protected override void InitComponent() { base.InitComponent(); getButton.SetListener(OnClickGetButton); } protected override void OnPreOpen() { base.OnPreOpen(); hasRankRefresh = false; RankModel.Instance.onRankRefresh += OnRankRefresh; manager.OnLianqiPlayerInfoAction += OnPlayerInfoRefresh; manager.OnLianqiPhaseChanged += OnPhaseChanged; awardScroller.OnRefreshCell += OnRefreshAwardCell; myAwardScroller.OnRefreshCell += OnRefreshMyAwardCell; RankModel.Instance.ResetQueryParam(); RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, forceQuery: true, groupValue1: manager.groupValue1, crossServerID: manager.crossServerID); Display(); } protected override void OnPreClose() { base.OnPreClose(); RankModel.Instance.onRankRefresh -= OnRankRefresh; manager.OnLianqiPlayerInfoAction -= OnPlayerInfoRefresh; manager.OnLianqiPhaseChanged -= OnPhaseChanged; awardScroller.OnRefreshCell -= OnRefreshAwardCell; myAwardScroller.OnRefreshCell -= OnRefreshMyAwardCell; TryClearEntryRedpointByNoAward(); } void OnRankRefresh(int type) { if (type != manager.sendRankType) return; hasRankRefresh = true; RankRefresh(); } void RankRefresh() { DisplayMyRank(); } private void OnPlayerInfoRefresh() { DisplayMyRank(); } private void OnPhaseChanged(int state) { DisplayMyRank(); } public void Display() { DisplayMyRank(); CreateAwardScroller(); } private void DisplayMyRank() { RankData rankData = null; ActBillboardAwardConfig config = null; bool hasAward = hasRankRefresh && manager.TryGetMyBillAwardConfig(out rankData, out config); uint score = manager.nowPlayerInfo != null ? manager.nowPlayerInfo.ScoreHighest : 0; if (rankData == null) { myRank.text = Language.Get("L1045"); } else { myRank.text = rankData.rank.ToString(); } myScore.text = Language.Get("LianQi14", string.Format(valueFormat, UIHelper.ReplaceLargeNum(score))); SetGetButtonState(hasRankRefresh && manager.CanHaveBillAward()); if (hasAward && config != null) { myAwardScroller.SetActive(true); CreateMyAwardScroller(config.AwardItemList); } else { myAwardScroller.Refresh(); myAwardScroller.Restart(); myAwardScroller.SetActive(false); } } int billTempID; private void CreateAwardScroller() { billTempID = manager.billTempID; var list = ActBillboardAwardConfig.GetRankASortList(billTempID); if (list == null) return; awardScroller.Refresh(); for (int i = 0; i < list.Count; i++) { awardScroller.AddCell(ScrollerDataType.Header, list[i]); } awardScroller.Restart(); } private void OnRefreshAwardCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<LianQiRankAwardCell>(); _cell?.Display(cell.index, billTempID); } private void CreateMyAwardScroller(int[][] awardItemList) { myAwardScroller.Refresh(); for (int i = 0; i < awardItemList.Length; i++) { CellInfo info = new CellInfo(awardItemList[i][0], awardItemList[i][1], null); myAwardScroller.AddCell(ScrollerDataType.Header, i, info); } myAwardScroller.Restart(); } private void OnRefreshMyAwardCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<LianQiRankAwardItemCell>(); _cell?.Display(cell); } private void OnClickGetButton() { if (!hasRankRefresh || !manager.CanHaveBillAward()) { SetGetButtonState(false); return; } SetGetButtonState(false); manager.SendHaveBillAward(); } private void SetGetButtonState(bool canGet) { getButton.interactable = canGet; getImage.gray = !canGet; redImage.SetActive(canGet); } private void TryClearEntryRedpointByNoAward() { if (!hasRankRefresh || manager.IsBillAwardReceived()) return; RankData rankData; ActBillboardAwardConfig config; if (!manager.TryGetMyBillAwardConfig(out rankData, out config)) { manager.ClearBillAwardEntryRedpointByNoAward(); } } } Main/System/LianQi/LianQiAwardWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 7c56c8195deb41048bf513812bb2d4a6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiCoolTime.cs
New file @@ -0,0 +1,70 @@ using UnityEngine; using UnityEngine.UI; public class LianQiCoolTime : MonoBehaviour { [SerializeField] Text m_Time; [SerializeField] Image m_bg; [SerializeField] Text title; private void OnEnable() { GlobalTimeEvent.Instance.secondEvent += RefreshSecond; RefreshSecond(); } private void OnDisable() { GlobalTimeEvent.Instance.secondEvent -= RefreshSecond; } private void RefreshSecond() { bool showCountdown = IsInEnterCountdownTime(out OperationBase operation); bool showAwardText = operation != null && !showCountdown && LianQiManager.Instance.IsInAwardPhase; bool showTime = showCountdown || showAwardText; m_bg.SetActive(showTime); m_Time.SetActive(showTime); title.SetActive(!showTime); if (showCountdown) { int seconds = Mathf.Max(0, GetOperationSurplusTime(LianQiManager.operaType)); m_Time.text = StringUtility.Concat("<color=#8DDC11FF>", TimeUtility.SecondsToHMS(seconds), "</color>"); } else if (showAwardText) { m_Time.text = UIHelper.AppendColor(TextColType.Red, Language.Get("LianQi15")); } } private bool IsInEnterCountdownTime(out OperationBase operation) { operation = null; if (!OperationTimeHepler.Instance.TryGetOperationTime(LianQiManager.operaType, out operation)) return false; var manager = LianQiManager.Instance; var now = TimeUtility.CrossServerNow; var startTime = operation.startDate .AddDays(manager.enterCountdownStartDay - 1) .AddSeconds(manager.enterCountdownStartHour * 60 * 60 + manager.enterCountdownStartMinute * 60); var endTime = operation.startDate .AddDays(manager.enterCountdownEndDay - 1) .AddSeconds(manager.enterCountdownEndHour * 60 * 60 + manager.enterCountdownEndMinute * 60) .AddMinutes(1); return now >= startTime && now < endTime; } public int GetOperationSurplusTime(OperationType type) { if (OperationTimeHepler.Instance.TryGetOperationTime(type, out OperationBase operation)) { return operation.GetSurplusTime(TimeUtility.CrossServerNow); } return 0; } } Main/System/LianQi/LianQiCoolTime.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 23cbd852d3b19ad4ea7625afd99aa05d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiGiftCell.cs
New file @@ -0,0 +1,228 @@ using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; public class LianQiGiftCell : MonoBehaviour { [SerializeField] ImageEx vipImage; [SerializeField] TextEx vipText; [SerializeField] OutlineEx vipTextOutline; [SerializeField] ImageEx rateImage; [SerializeField] TextEx rateText; [SerializeField] ItemCell[] itemCells; [SerializeField] TextEx titleText; [SerializeField] ButtonEx buyButton; [SerializeField] ImageEx buyImage; [SerializeField] TextEx buyText; [SerializeField] TextEx buyText1; [SerializeField] ImageEx moneyIconImage; [SerializeField] ImageEx adImage; [SerializeField] TextEx limitCountText; [SerializeField] ImageEx redImage; LianQiManager manager => LianQiManager.Instance; StoreModel storeModel => StoreModel.Instance; public void Display(int index, List<LianQiGiftItem> giftItems) { if (giftItems.IsNullOrEmpty() || index < 0 || index >= giftItems.Count) return; LianQiGiftItem item = giftItems[index]; if (item.type == 0) { DisplayStore(item.id); return; } if (item.type == 1) { DisplayAD(item.id); return; } DisplayCTG(item.id); } private void DisplayCTG(int ctgId) { redImage.SetActive(false); buyText.SetActive(true); buyText1.SetActive(false); moneyIconImage.SetActive(false); adImage.SetActive(false); rateImage.SetActive(true); if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return; if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return; if (!CTGConfig.HasKey(ctgId)) return; if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return; CTGConfig config = CTGConfig.Get(ctgId); vipImage.SetActive(config.VipLevel > 0); if (config.VipLevel > 0) { vipImage.SetSprite($"VipLevel{config.VipLevel}"); vipText.text = Language.Get($"VipLevelInfo{config.VipLevel}"); vipText.color = InvestModel.Instance.GetTextColor(config.VipLevel); vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(config.VipLevel); } rateImage.SetActive(true); rateText.text = Language.Get("DailySpecials07", config.Percentage); bool isCanBuy = manager.IsCanBuy(ctgId, out bool isNoLimitBuy, out int nowBuyCnt, out int maxBuyCnt); titleText.text = config.Title; buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale)); limitCountText.SetActive(!isNoLimitBuy && maxBuyCnt > 0); if (!isNoLimitBuy && maxBuyCnt > 0) { limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(nowBuyCnt >= maxBuyCnt ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, maxBuyCnt - nowBuyCnt).ToString())); } buyButton.interactable = isCanBuy; buyButton.SetListener(() => { if (config.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto8"); return; } if (config.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto5"); UIManager.Instance.OpenWindow<PrivilegeCardWin>(); return; } if (config.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto7"); UIManager.Instance.OpenWindow<PrivilegeCardWin>(); return; } RechargeManager.Instance.CTG(ctgId); }); for (int i = 0; i < itemCells.Length; i++) { var itemBaisc = itemCells[i]; if (i < rechargeItemList.Count) { var itemInfo = rechargeItemList[i]; itemBaisc.SetActive(true); itemBaisc.Init(new ItemCellModel((int)itemInfo.id, false, itemInfo.countEx)); itemBaisc.button.AddListener(() => { ItemTipUtility.Show((int)itemInfo.id); }); } else { itemBaisc.SetActive(false); } } } private void DisplayStore(int id) { rateImage.SetActive(false); vipImage.SetActive(false); if (!StoreConfig.HasKey(id)) return; StoreConfig storeConfig = StoreConfig.Get(id); int remainNum; storeModel.TryGetIsSellOut(storeConfig, out remainNum); bool isFree = manager.IsFreeShop(id); titleText.text = storeConfig.Name; limitCountText.SetActive(!isFree); limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(remainNum == 0 ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, remainNum).ToString(), true)); bool isCanBuy = manager.IsNoSellOutShopID(id); redImage.SetActive(isFree && isCanBuy); buyText.SetActive(isFree || !isCanBuy); buyText.text = isFree ? Language.Get("L1127") : Language.Get("storename11"); buyText1.SetActive(!isFree && isCanBuy); buyText1.text = UIHelper.GetMoneyFormat(storeConfig.MoneyNum); adImage.SetActive(false); moneyIconImage.SetActive(!isFree && isCanBuy); moneyIconImage.SetIconWithMoneyType(1); buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); buyButton.interactable = isCanBuy; buyButton.SetListener(() => { storeModel.SendBuyShopItemWithPopCheck(storeConfig, 1, (int)BuyStoreItemCheckType.ActGift); }); var items = storeModel.GetShopItemlistByIndex(storeConfig); for (int i = 0; i < itemCells.Length; i++) { var itemBaisc = itemCells[i]; if (i < items.Count) { var itemInfo = items[i]; itemBaisc.SetActive(true); itemBaisc.Init(new ItemCellModel(itemInfo.itemId, false, itemInfo.count)); itemBaisc.button.AddListener(() => { ItemTipUtility.Show(itemInfo.itemId); }); } else { itemBaisc.SetActive(false); } } } private void DisplayAD(int ADID) { rateImage.SetActive(false); vipImage.SetActive(false); ADAwardConfig config = ADAwardConfig.Get(ADID); if (config == null) return; bool isCanBuy = manager.IsAdAwardCanReceive(ADID); int receivedCnt = AdsManager.Instance.GetADCntByADID(ADID); titleText.text = config.Name; limitCountText.SetActive(true); limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(!isCanBuy ? TextColType.Red : TextColType.LightGreen, Mathf.Max(config.ADCntMax - receivedCnt, 0).ToString())); redImage.SetActive(isCanBuy); buyText.SetActive(false); buyText1.SetActive(true); buyText1.text = Language.Get("L1127"); moneyIconImage.SetActive(false); adImage.SetActive(true); adImage.gray = !isCanBuy; buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); buyButton.interactable = isCanBuy; buyButton.SetListener(() => { AdsManager.Instance.GetAdsAward(ADID); }); var items = config.ADAwardItemList; for (int i = 0; i < itemCells.Length; i++) { var itemBaisc = itemCells[i]; if (i < items.Length) { var itemInfo = items[i]; itemBaisc.SetActive(true); itemBaisc.Init(new ItemCellModel(itemInfo[0], false, itemInfo[1])); itemBaisc.button.AddListener(() => { ItemTipUtility.Show(itemInfo[0]); }); } else { itemBaisc.SetActive(false); } } } } Main/System/LianQi/LianQiGiftCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e621e92b191df16418aa8d25c4336fbf MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiGiftWin.cs
New file @@ -0,0 +1,74 @@ using System.Collections.Generic; using UnityEngine; public class LianQiGiftWin : UIBase { [SerializeField] ButtonEx closeButton; [SerializeField] ScrollerController scroller; LianQiManager manager => LianQiManager.Instance; StoreModel storeModel => StoreModel.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent; CreateGiftScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent; } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<LianQiGiftCell>(); _cell?.Display(cell.index, giftItems); } private void OnRechargeCountEvent(int obj) { RefreshAll(); } private void RefreshBuyShopLimitEvent() { RefreshAll(); } private void OnAdsInfoListUpdateEvent(int arg1, int arg2, int arg3) { RefreshAll(); } List<LianQiGiftItem> giftItems; private void CreateGiftScroller() { giftItems = manager.GetGiftItemList(true); scroller.Refresh(); if (!giftItems.IsNullOrEmpty()) { for (int i = 0; i < giftItems.Count; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } scroller.Restart(); } void RefreshAll() { scroller.m_Scorller.RefreshActiveCellViews(); } } Main/System/LianQi/LianQiGiftWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 668f585a6fcbafd47961af6a84bc558f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiItemInfoDoubleWin.cs
New file @@ -0,0 +1,113 @@ using System; using UnityEngine; using UnityEngine.UI; public class LianQiItemInfoDoubleWin : UIBase { [SerializeField] ItemCell itemCell; [SerializeField] Text nameText; [SerializeField] Text countText; [SerializeField] Text descText; [SerializeField] SliderPanel sliderPanel; [SerializeField] Text limitText; [SerializeField] Button buyButton; LianQiManager M => LianQiManager.Instance; int useCount = 1; protected override void InitComponent() { buyButton.AddListener(OnUseClick); } protected override void OnPreOpen() { useCount = 1; Display(); } /// <summary> /// 展示玉露(道具4)的详细信息与数量选择滑块 /// </summary> private void Display() { int itemID = M.nowAssistiveItemId; if (!ItemConfig.HasKey(itemID)) return; var itemConfig = ItemConfig.Get(itemID); long hasCount = PackManager.Instance.GetItemCountByID(PackType.Item, itemID); itemCell.Init(new ItemCellModel(itemID, false, hasCount)); itemCell.countText.SetActive(true); itemCell.countText.text = "1"; countText.text = Language.Get("storename12", hasCount); nameText.text = itemConfig.ItemName; descText.text = itemConfig.Description; if (!M.limitUsesToolCntDict.TryGetValue(itemID, out int limitCnt)) return; int useItemCnt = M.GetUseItemCnt(M.nowPlayerInfo.UseItemCntList, M.nowAssistiveItemNum); int hasCnt = hasCount > limitCnt ? limitCnt : (int)hasCount; int nowResCnt = Mathf.Max(0, limitCnt - useItemCnt); // 本轮剩余次数 int realCnt = nowResCnt > hasCnt ? hasCnt : nowResCnt; limitText.text = Language.Get("LianQi10", Mathf.Max(0, limitCnt - useItemCnt), limitCnt); useCount = 1; // 初始化滑块:数量变化时更新 useCount sliderPanel.Init((value) => { useCount = value; }, realCnt, 1); } /// <summary> /// 使用按钮回调:检查数量与次数,确认后发送 /// </summary> private void OnUseClick() { int itemID = M.nowAssistiveItemId; int num = M.nowAssistiveItemNum; if (!ItemConfig.HasKey(itemID)) return; var itemConfig = ItemConfig.Get(itemID); // 道具数量不足 if (PackManager.Instance.GetItemCountByID(PackType.Item, itemID) <= 0) { SysNotifyMgr.Instance.ShowTip("LianQiAct02"); return; } // 该道具该局已达使用次数上限 if (!M.limitUsesToolCntDict.TryGetValue(itemID, out int cnt)) return; int useItemCnt = M.GetUseItemCnt(M.nowPlayerInfo.UseItemCntList, num); if (useItemCnt >= cnt) { SysNotifyMgr.Instance.ShowTip("LianQiAct03"); return; } if (M.isSkip4) { if (M.IsCanSendUseItem()) M.SendUseOP(useCount, 3, 0, 0); if (UIManager.Instance.IsOpened<LianQiItemInfoDoubleWin>()) UIManager.Instance.CloseWindow<LianQiItemInfoDoubleWin>(); } else { ConfirmCancel.ToggleConfirmCancelEx(Language.Get("Mail101"), Language.Get("LianQi27", useCount, itemConfig.ItemName), Language.Get("ConfirmCancel102"), OnConfirm4, OnConfirm4, M.isSkip4); } } private void OnConfirm4(bool isOk, bool isToggle) { M.isSkip4 = isToggle; if (isOk && M.IsCanSendUseItem()) M.SendUseOP(useCount, 3, 0, 0); if (UIManager.Instance.IsOpened<LianQiItemInfoDoubleWin>()) UIManager.Instance.CloseWindow<LianQiItemInfoDoubleWin>(); } /// <summary> /// 关闭时重置道具使用状态(玉露不进入选格,关闭即结束道具模式) /// </summary> protected override void OnPreClose() { M.isUseTool = false; } } Main/System/LianQi/LianQiItemInfoDoubleWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 197d45697dfbe8e49a50290f9ba1af78 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiItemInfoWin.cs
New file @@ -0,0 +1,83 @@ using System; using UnityEngine; using UnityEngine.UI; public class LianQiItemInfoWin : UIBase { [SerializeField] ItemCell itemCell; [SerializeField] Text nameText; [SerializeField] Text countText; [SerializeField] Text descText; [SerializeField] Text limitText; [SerializeField] Button buyButton; LianQiManager M => LianQiManager.Instance; protected override void InitComponent() { buyButton.AddListener(OnUseClick); } protected override void OnPreOpen() { // 读取当前辅助道具信息并展示 int itemID = M.nowAssistiveItemId; if (!ItemConfig.HasKey(itemID)) return; var itemConfig = ItemConfig.Get(itemID); long hasCount = PackManager.Instance.GetItemCountByID(PackType.Item, itemID); itemCell.Init(new ItemCellModel(itemID, false, hasCount)); itemCell.countText.SetActive(true); itemCell.countText.text = "1"; countText.text = Language.Get("storename12", hasCount); nameText.text = itemConfig.ItemName; descText.text = itemConfig.Description; if (M.limitUsesToolCntDict.TryGetValue(itemID, out int limitCnt)) { int useItemCnt = M.GetUseItemCnt(M.nowPlayerInfo.UseItemCntList, M.nowAssistiveItemNum); limitText.text = Language.Get("LianQi10", Mathf.Max(0, limitCnt - useItemCnt), limitCnt); } } protected override void OnPreClose() { var M = LianQiManager.Instance; // 仅在未进入选格(用户取消)时退出道具模式;已点"使用"则保留状态供 LianQiWin 选格 if (!M.isStartChoose) { M.isUseTool = false; } } /// <summary> /// 使用按钮回调:检查数量与次数,进入选格模式 /// </summary> private void OnUseClick() { int itemID = M.nowAssistiveItemId; int num = M.nowAssistiveItemNum; if (!ItemConfig.HasKey(itemID)) return; // 道具数量不足 if (PackManager.Instance.GetItemCountByID(PackType.Item, itemID) <= 0) { SysNotifyMgr.Instance.ShowTip("LianQiAct02"); return; } // 该道具该局已达使用次数上限 if (!M.limitUsesToolCntDict.TryGetValue(itemID, out int cnt)) return; int useItemCnt = M.GetUseItemCnt(M.nowPlayerInfo.UseItemCntList, num); if (useItemCnt >= cnt) { SysNotifyMgr.Instance.ShowTip("LianQiAct03"); return; } // 进入选格模式(玉露(道具4)不走选格,由 DoubleWin 处理) M.isStartChoose = true; M.isChoose1 = false; M.isChoose2 = false; CloseWindow(); } } Main/System/LianQi/LianQiItemInfoWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f3e4c8989dda2f84d9513d1b607b1642 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiManager.cs
New file @@ -0,0 +1,1248 @@ using LitJson; using System; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; public class LianQiManager : GameSystemManager<LianQiManager>, IOpenServerActivity { public const int activityID = (int)OperationType.LianQiCross; public static OperationType operaType = OperationType.LianQiCross; private const int AwardPhaseState = 99; public int ZhanLingType => 9; public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType); public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType); public bool priorityOpen => redPoint.state == RedPointState.Simple; public readonly int actNum = 99; public const int regesitCrossType = 221; public readonly int sendRankType = 155; public int loadRankType => sendRankType; public int groupValue1 => operationCrossAct != null ? operationCrossAct.m_GroupValue1 : 0; public int crossServerID => operationCrossAct != null ? operationCrossAct.m_CrossServerID : 0; public int billTempID => operationCrossAct != null && operationCrossAct.actTempConfig != null ? operationCrossAct.actTempConfig.PersonalTempID : 0; public OperationLianQiCross GetOperation() => operationCrossAct; public OperationLianQiCross operationCrossAct = null; public HAA91_tagSCActLianqiPlayerInfo lastPlayerInfo = null; public HAA91_tagSCActLianqiPlayerInfo nowPlayerInfo = null; public int[][] nowGridData; public int[][] lastGridData; public bool isWaitReStart = false; public bool isPause = false; public bool isUseTool = false; //1 破天锤 2 造化灵玉 3 九天陨铁 4 甘露仙液 public int nowAssistiveItemNum = 0; public int nowAssistiveItemId; public bool isStartChoose = false; public bool isChoose1 = false; public int useRow1; public int useCol1; public bool isChoose2 = false; public int useRow2; public int useCol2; public bool isPlayAssistiveItemAnimation; public bool isSkip1 = false; public bool isSkip2 = false; public bool isSkip3 = false; public bool isSkip4 = false; public readonly int MaxItemLv = 11; //最大合成物等级 public readonly int MaxGridRows = 4; public readonly int MaxGridCols = 4; public readonly int MaxGridCount = 16; public int actScore { get; private set; } public bool IsJoin => operationCrossAct != null && operationCrossAct.IsInJoinPhase(); public bool IsPrepareTime => IsInPublicityPhase; public bool IsResultShowTime => IsInAwardPhase; public bool IsInPublicityPhase => operationCrossAct != null && operationCrossAct.IsInPublicityPhase(); public bool IsInAwardPhase => operationCrossAct != null && operationCrossAct.IsInAwardPhase(); public int SelectRank { get; set; } public int SelectAwardRank { get; set; } public int no1PlayerID = 0; public int no1PlayerIDCross = 0; PackManager packManager => PackManager.Instance; public event Action OnLianqiPlayerInfoAction; public event Action<int> onStateUpdate; public event Action<int> OnLianqiPhaseChanged; private int lastPhaseState = -1; private bool hasCheckedNoBillAward = false; private void OperationTimeUpdateEvent(OperationType type) { if (type == operaType) { if (UIManager.Instance.IsOpened<LianQiWin>()) UIManager.Instance.CloseWindow<LianQiWin>(); if (OperationTimeHepler.Instance.TryGetOperationTime(operaType, out var operationBase1)) { operationCrossAct = operationBase1 as OperationLianQiCross; } UpdateRedpoint(); } } private void OperationStartEvent(OperationType type, int state) { if (type == operaType && state == 0) { UpdateRedpoint(); onStateUpdate?.Invoke(activityID); } } private void OperationEndEvent(OperationType type, int state) { if (type == operaType && state == 0) { if (UIManager.Instance.IsOpened<LianQiWin>()) UIManager.Instance.CloseWindow<LianQiWin>(); UpdateRedpoint(); onStateUpdate?.Invoke(activityID); if (!OperationTimeHepler.Instance.TryGetOperationTime(operaType, out _)) operationCrossAct = null; } } private void OperationAdvanceEvent(OperationType type) { if (type == operaType) { UpdateRedpoint(); onStateUpdate?.Invoke(activityID); } } private void OnSecondEvent() { if (operationCrossAct == null) return; int cur = operationCrossAct.GetCurrentPhaseState(); if (cur != lastPhaseState) { bool isEnterAwardPhase = cur == AwardPhaseState && lastPhaseState != AwardPhaseState; lastPhaseState = cur; if (isEnterAwardPhase) hasCheckedNoBillAward = false; UpdateRedpoint(); OnLianqiPhaseChanged?.Invoke(cur); } } public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent; OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent; OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent; OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent; StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent; BattlePassManager.Instance.BattlePassDataUpdateEvent += OnBattlePassDataUpdate; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; OpenServerActivityCenter.Instance.Register(regesitCrossType, this); ParseConfig(); } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent; OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent; OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent; OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent; StoreModel.Instance.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent; BattlePassManager.Instance.BattlePassDataUpdateEvent -= OnBattlePassDataUpdate; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; } private void OnBeforePlayerDataInitializeEventOnRelogin() { operationCrossAct = null; actScore = 0; no1PlayerID = 0; no1PlayerIDCross = 0; isSkip1 = false; isSkip2 = false; isSkip3 = false; isSkip4 = false; lastPhaseState = -1; hasCheckedNoBillAward = false; ClearGameplayState(); } private void OnFuncStateChangeEvent(int obj) { if (obj == (int)FuncOpenEnum.LianQi) { UpdateRedpoint(); } } private void OnBattlePassDataUpdate(int type) { if (type == ZhanLingType) { UpdateRedpoint(); OnZhanLingUpdateEvent?.Invoke(); } } private void RefreshBuyShopLimitEvent() { UpdateRedpoint(); } private void OnRechargeCountEvent(int obj) { UpdateRedpoint(); } private void OnAdsInfoListUpdateEvent(int arg1, int arg2, int arg3) { UpdateRedpoint(); } public bool IsLianQiOpen() { return FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.LianQi) && IsOpen; } #region 配置表解析 /// <summary> /// 合成等级对应奖励 {"奖励等级":[[物品ID,个数], ...], ...} /// </summary> public Dictionary<int, List<Item>> correspondingRewards = new Dictionary<int, List<Item>>(); /// <summary> /// 限制单局使用次数 {"物品ID":单局使用次数, ...} /// </summary> public Dictionary<int, int> limitUsesToolCntDict = new Dictionary<int, int>(); /// <summary> /// 辅助道具对应物品ID列表 [辅助道具ID1, ...] /// 辅助道具1 - 碎天锤,消除任意位置,且不减分 /// 辅助道具2 - 造化灵玉,交换任意两个位置 /// 辅助道具3 - 九天陨铁,将任意1个7阶以下进阶,并获得积分及解锁等级奖励 /// 辅助道具4 - 甘露仙液,体力加15 /// </summary> public int[] assistiveItemArr; /// <summary> /// 九天陨铁道具限制x阶以下 /// </summary> public int jiuTianYunTieLevelLimit; /// <summary> /// 最大体力,初始体力默认为最大体力,移动1次体力-1 /// </summary> public int maxEnergy; /// <summary> /// 恢复1点体力所需时间,秒 /// </summary> public int rSecond; /// <summary> /// 入口倒计时显示开始时间,活动第N天 时 分 /// </summary> public int enterCountdownStartDay; public int enterCountdownStartHour; public int enterCountdownStartMinute; /// <summary> /// 入口倒计时显示结束时间,活动第N天 时 分 /// </summary> public int enterCountdownEndDay; public int enterCountdownEndHour; public int enterCountdownEndMinute; private void ParseConfig() { var config = FuncConfigConfig.Get("LianqiSet"); maxEnergy = int.Parse(config.Numerical1); rSecond = int.Parse(config.Numerical2); var rewardArrDict = ConfigParse.ParseIntArray2Dict(config.Numerical3); foreach (var kvp in rewardArrDict) { correspondingRewards[kvp.Key] = new List<Item>(); var value = kvp.Value; for (int j = 0; j < value.Length; j++) correspondingRewards[kvp.Key].Add(new Item(value[j][0], value[j][1])); } config = FuncConfigConfig.Get("LianqiUseItem"); assistiveItemArr = JsonMapper.ToObject<int[]>(config.Numerical1); limitUsesToolCntDict = ConfigParse.ParseIntDict(config.Numerical2); jiuTianYunTieLevelLimit = int.Parse(config.Numerical3); config = FuncConfigConfig.Get("LianqiEnter"); var enterCountdownStartTime = config.Numerical1.Split('|'); enterCountdownStartDay = int.Parse(enterCountdownStartTime[0]); enterCountdownStartHour = int.Parse(enterCountdownStartTime[1]); enterCountdownStartMinute = int.Parse(enterCountdownStartTime[2]); var enterCountdownEndTime = config.Numerical2.Split('|'); enterCountdownEndDay = int.Parse(enterCountdownEndTime[0]); enterCountdownEndHour = int.Parse(enterCountdownEndTime[1]); enterCountdownEndMinute = int.Parse(enterCountdownEndTime[2]); } #endregion #region 礼包 public List<LianQiGiftItem> GetGiftItemList(bool isSort = false) { if (operationCrossAct == null || operationCrossAct.actTempConfig == null) return null; var config = operationCrossAct.actTempConfig; List<LianQiGiftItem> res = new List<LianQiGiftItem>(); if (StoreModel.Instance.storeTypeDict.TryGetValue(config.ActShopType, out var list)) { if (!list.IsNullOrEmpty()) { for (int i = 0; i < list.Count; i++) { var item = list[i]; if (item.storeConfig == null) continue; res.Add(new LianQiGiftItem { type = 0, id = item.storeConfig.ID }); } } } if (ADAwardConfig.Get(config.ADID) != null) { res.Add(new LianQiGiftItem { type = 1, id = config.ADID }); } if (config.CTGIDList != null) { for (int i = 0; i < config.CTGIDList.Length; i++) { res.Add(new LianQiGiftItem { type = 2, id = config.CTGIDList[i] }); } } if (isSort) { Dictionary<LianQiGiftItem, int> originalIndexMap = new Dictionary<LianQiGiftItem, int>(); for (int i = 0; i < res.Count; i++) originalIndexMap[res[i]] = i; res.Sort((a, b) => { bool notBuyA = GetIsNotCanBuy(a); bool notBuyB = GetIsNotCanBuy(b); if (notBuyA != notBuyB) return notBuyA.CompareTo(notBuyB); int orderA = GetSortOrder(a); int orderB = GetSortOrder(b); if (orderA != orderB) return orderA.CompareTo(orderB); int idCmp = a.id.CompareTo(b.id); if (idCmp != 0) return idCmp; return originalIndexMap[a].CompareTo(originalIndexMap[b]); }); } return res; } public bool IsCanBuy(int ctgID, out bool isNoLimitBuy, out int nowBuyCnt, out int maxBuyCnt) { isNoLimitBuy = false; nowBuyCnt = 0; maxBuyCnt = 0; CTGConfig config = CTGConfig.Get(ctgID); if (config == null) return false; if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false; if (config.TotalBuyCount == 0 && config.DailyBuyCount == 0 && config.WeekBuyCount == 0 && config.MonthBuyCount == 0) { isNoLimitBuy = true; return true; } if (config.DailyBuyCount > 0) { nowBuyCnt = rechargeCount.todayCount; maxBuyCnt = config.DailyBuyCount; return rechargeCount.todayCount < config.DailyBuyCount; } if (config.WeekBuyCount > 0) { nowBuyCnt = rechargeCount.weekPayCount; maxBuyCnt = config.WeekBuyCount; return rechargeCount.weekPayCount < config.WeekBuyCount; } if (config.MonthBuyCount > 0) { nowBuyCnt = rechargeCount.monthPayCount; maxBuyCnt = config.MonthBuyCount; return rechargeCount.monthPayCount < config.MonthBuyCount; } if (config.TotalBuyCount > 0) { nowBuyCnt = rechargeCount.totalCount; maxBuyCnt = config.TotalBuyCount; return rechargeCount.totalCount < config.TotalBuyCount; } return false; } public bool IsFreeShop(int shopID) { StoreConfig config = StoreConfig.Get(shopID); if (config == null) return false; return config.MoneyNum == 0; } public bool IsNoSellOutShopID(int shopID) { StoreConfig config = StoreConfig.Get(shopID); if (config == null) return false; StoreModel.Instance.TryGetIsSellOut(config, out int remainNum); return remainNum > 0; } public bool IsAdAwardCanReceive(int adID) { var config = ADAwardConfig.Get(adID); if (config == null) return false; int receivedCnt = AdsManager.Instance.GetADCntByADID(adID); return receivedCnt < config.ADCntMax; } private bool GetIsNotCanBuy(LianQiGiftItem item) { if (item.type == 0) return !IsNoSellOutShopID(item.id); else if (item.type == 1) return !IsAdAwardCanReceive(item.id); else return !IsCanBuy(item.id, out bool _, out int _, out int _); } private int GetSortOrder(LianQiGiftItem item) { if (item.type == 0) { return IsFreeShop(item.id) ? 0 : 2; } if (item.type == 1) { return 1; } return 3; } public bool HasGiftCanHave() { if (operationCrossAct == null || operationCrossAct.actTempConfig == null) return false; var config = operationCrossAct.actTempConfig; if (StoreModel.Instance.storeTypeDict.TryGetValue(config.ActShopType, out var list) && !list.IsNullOrEmpty()) { for (int i = 0; i < list.Count; i++) { if (list[i].storeConfig == null) continue; int shopID = list[i].storeConfig.ID; if (IsFreeShop(shopID) && IsNoSellOutShopID(shopID)) return true; } } if (ADAwardConfig.Get(config.ADID) != null && IsAdAwardCanReceive(config.ADID)) return true; return false; } #endregion #region 红点 public Redpoint redPoint = new Redpoint(MainRedDot.LianQiRepoint); public Redpoint zhanlingRedPoint = new Redpoint(MainRedDot.LianQiRepoint, MainRedDot.LianQiRepoint * 10 + 1); public Redpoint awardRedPoint = new Redpoint(MainRedDot.LianQiRepoint, MainRedDot.LianQiRepoint * 10 + 2); public Redpoint giftRedpoint = new Redpoint(MainRedDot.LianQiRepoint, MainRedDot.LianQiRepoint * 10 + 3); private void UpdateRedpoint() { redPoint.state = RedPointState.None; zhanlingRedPoint.state = RedPointState.None; awardRedPoint.state = RedPointState.None; giftRedpoint.state = RedPointState.None; if (!IsLianQiOpen()) return; if (HasGiftCanHave()) giftRedpoint.state = RedPointState.Simple; if (HasZhanLingCanHave()) zhanlingRedPoint.state = RedPointState.Simple; if (HasBillAwardEntryRedpoint()) awardRedPoint.state = RedPointState.Simple; } private bool HasBillAwardEntryRedpoint() { if (!IsInAwardPhase) return false; if (nowPlayerInfo == null || nowPlayerInfo.BillAwardState != 0) return false; return !hasCheckedNoBillAward; } public void ClearBillAwardEntryRedpointByNoAward() { if (!IsInAwardPhase) return; if (nowPlayerInfo == null || nowPlayerInfo.BillAwardState != 0) return; hasCheckedNoBillAward = true; UpdateRedpoint(); } #endregion #region 战令 public event Action OnZhanLingUpdateEvent; public int GetZhanLingValue() { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); return data != null ? (int)data.value1 : 0; } public static int GetZhanLingValueByType(int zhanLingType) { var data = BattlePassManager.Instance.GetBattlePassData(zhanLingType); return data != null ? (int)data.value1 : 0; } // 0 没购买进阶和玄级 1 购买了进阶没买玄级 2 购买了玄级没买进阶 3 购买了进阶和玄级 public int GetZhanLingBuyState() { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return 0; bool isBuyPaid = data.isActivite > 0; bool isBuyPaidH = data.isActiviteH > 0; if (isBuyPaid && isBuyPaidH) return 3; if (isBuyPaid) return 1; if (isBuyPaidH) return 2; return 0; } public bool HasZhanLingCanHave() { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return false; var dict = ZhanlingConfig.GetTypeToIDDict(ZhanLingType); if (dict.IsNullOrEmpty()) return false; int buyState = GetZhanLingBuyState(); bool isBuyPaid = buyState == 1 || buyState == 3; bool isBuyPaidH = buyState == 2 || buyState == 3; foreach (var kvp in dict) { int needValue = kvp.Key; int freeState = GetZhanLingFreeGiftState(needValue); if (freeState == 1) return true; if (isBuyPaid) { int paidState = GetZhanLingPaidGiftState(needValue); if (paidState == 1) return true; } if (isBuyPaidH) { int paidHState = GetZhanLingPaidGiftHState(needValue); if (paidHState == 1) return true; } } return false; } // 0 不能领 1 未领取 2 已领取 public int GetZhanLingFreeGiftState(int needValue) { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return 0; return BattlePassManager.Instance.GetBPCellAwardState(data, GetZhanLingValue(), needValue, 0); } public int GetZhanLingPaidGiftState(int needValue) { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return 0; return BattlePassManager.Instance.GetBPCellAwardState(data, GetZhanLingValue(), needValue, 1); } public int GetZhanLingPaidGiftHState(int needValue) { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return 0; return BattlePassManager.Instance.GetBPCellAwardState(data, GetZhanLingValue(), needValue, 2); } public void HaveAllZhanLingGift() { var data = BattlePassManager.Instance.GetBattlePassData(ZhanLingType); if (data == null) return; if (PackManager.Instance.GetEmptyGridCount(PackType.Item) < 1) { SysNotifyMgr.Instance.ShowTip("GeRen_lhs_202580"); return; } BattlePassManager.Instance.GetAllAward(data, ZhanLingType, GetZhanLingValue()); } #endregion #region 战令预览购买 public int previewZhanLingType { get; private set; } public int previewGiftType { get; private set; } public void ShowZhanLingHBuy(int zhanLingType, int showGiftType) { previewZhanLingType = zhanLingType; previewGiftType = showGiftType; if (showGiftType == 1 || showGiftType == 2) UIManager.Instance.OpenWindow<LianQiZhanLingPreviewWin>(); } public int GetPreviewCtgID() { int ctgid = 0; if (previewGiftType == 1) { ctgid = BattlePassManager.Instance.GetCTGIDByType(previewZhanLingType); } else if (previewGiftType == 2) { var config = FuncConfigConfig.Get("Zhanling"); if (config != null) { var dict = ConfigParse.ParseIntArrayDict(config.Numerical3); if (dict.TryGetValue(previewZhanLingType, out var arr) && arr.Length > 0) ctgid = arr[0]; } } return ctgid; } public List<Item> GetPreviewGiftAllItem(int maxCountPerSlot = 20) { List<int> collectList = new List<int>(); var dict = ZhanlingConfig.GetTypeToIDDict(previewZhanLingType); if (dict.IsNullOrEmpty()) return new List<Item>(); int[] keysArr = new int[dict.Count]; int _idx = 0; foreach (int key in dict.Keys) { keysArr[_idx] = key; _idx++; } for (int i = 0; i < keysArr.Length; i++) { int needValue = keysArr[i]; collectList.Add(dict[needValue]); } return CollectPreviewItems(collectList, maxCountPerSlot); } public List<Item> GetPreviewGiftNowItem(int maxCountPerSlot = 20) { List<int> collectList = new List<int>(); var dict = ZhanlingConfig.GetTypeToIDDict(previewZhanLingType); if (dict.IsNullOrEmpty()) return new List<Item>(); int nowValue = GetZhanLingValueByType(previewZhanLingType); foreach (var kv in dict) { if (kv.Key <= nowValue) collectList.Add(kv.Value); } return CollectPreviewItems(collectList, maxCountPerSlot); } private List<Item> CollectPreviewItems(List<int> collectList, int maxCountPerSlot) { Dictionary<int, int> resultDict = new Dictionary<int, int>(); for (int i = 0; i < collectList.Count; i++) { int zhanLingId = collectList[i]; int[][] itemArr = GetPreviewItemArr(zhanLingId, previewGiftType); if (itemArr.IsNullOrEmpty()) continue; for (int j = 0; j < itemArr.Length; j++) { int itemID = itemArr[j][0]; int count = itemArr[j][1]; if (resultDict.ContainsKey(itemID)) resultDict[itemID] += count; else resultDict[itemID] = count; } } List<Item> result = GetItemListByDict(resultDict, maxCountPerSlot); result.Sort(CmpPreviewItem); return result; } private int[][] GetPreviewItemArr(int zhanLingId, int showGiftType) { var config = ZhanlingConfig.Get(zhanLingId); if (config == null) return new int[][] { }; if (showGiftType == 1) return config.ZLRewardItemList; if (showGiftType == 2) return config.ZLRewardItemListH; return new int[][] { }; } private List<Item> GetItemListByDict(Dictionary<int, int> dict, int maxCountPerSlot) { List<Item> result = new List<Item>(); int[] keysArr = new int[dict.Count]; int _idx = 0; foreach (int key in dict.Keys) { keysArr[_idx] = key; _idx++; } for (int i = 0; i < keysArr.Length; i++) { int itemID = keysArr[i]; int count = dict[itemID]; result.Add(new Item(itemID, count)); } return result; } private int CmpPreviewItem(Item a, Item b) { int quality1 = ItemConfig.Get(a.id).ItemColor; int quality2 = ItemConfig.Get(b.id).ItemColor; if (quality1 != quality2) return quality2.CompareTo(quality1); return a.countEx.CompareTo(b.countEx); } #endregion #region 炼器棋盘玩法 private void ClearGameplayState() { nowPlayerInfo = null; lastPlayerInfo = null; nowGridData = null; lastGridData = null; isWaitReStart = false; isPause = false; isUseTool = false; nowAssistiveItemNum = 0; nowAssistiveItemId = 0; isStartChoose = false; isChoose1 = false; isChoose2 = false; useRow1 = 0; useCol1 = 0; useRow2 = 0; useCol2 = 0; isPlayAssistiveItemAnimation = false; SelectRank = 0; SelectAwardRank = 0; } public int GetPlayerId(RankData rankData) { if (rankData == null) return 0; switch (SelectRank) { case 0: case 1: return (int)rankData.id; case 2: return (int)rankData.id2; default: return 0; } } public int GetUseItemCnt(ushort[] UseItemCntList, int nowAssistiveItemNum) { if (nowAssistiveItemNum < 1 || nowAssistiveItemNum > 4) return 0; if (UseItemCntList.IsNullOrEmpty() || UseItemCntList.Length != 4) return 0; return UseItemCntList[Mathf.Max(0, nowAssistiveItemNum - 1)]; } public int GetAwardState(int awardLv, int lvAwardState, int lvAwardMax) { if (lvAwardMax >= awardLv) return ((int)Math.Pow(2, awardLv) & lvAwardState) == 0 ? 1 : 2; return 0; } public bool TryGetCompositeItemInfoByAwardLv(int awardLv, out LianQiCompositeItemInfo lianQiCompositeItemInfo) { lianQiCompositeItemInfo = new LianQiCompositeItemInfo(); string iconStr = StringUtility.Concat("LianQiCompositeItemIcon", "_", awardLv.ToString()); if (!IconConfig.HasKey(iconStr)) { Debug.LogWarning($"没有配置I.Icon表中LianQiCompositeItemIcon_{awardLv}项"); return false; } lianQiCompositeItemInfo.Icon = iconStr; string nameStr = StringUtility.Concat("LianQiCompositeItemName", "_", awardLv.ToString()); if (!LanguageConfig.HasKey(StringUtility.Concat("LianQiCompositeItemName", "_", awardLv.ToString()))) { Debug.LogWarning($"没有配置Y.语言表中LianQiCompositeItemName_{awardLv}项"); return false; } lianQiCompositeItemInfo.Name = Language.Get(nameStr); string descriptionStr = StringUtility.Concat("LianQiCompositeItemDescription", "_", awardLv.ToString()); if (!LanguageConfig.HasKey(StringUtility.Concat("LianQiCompositeItemDescription", "_", awardLv.ToString()))) { Debug.LogWarning($"没有配置Y.语言表中LianQiCompositeItemDescription_{awardLv}项"); return false; } lianQiCompositeItemInfo.Description = Language.Get(descriptionStr); return true; } public void SetActive(Component compoent, bool active) { if (compoent != null) { if (active && !compoent.gameObject.activeSelf) { compoent.gameObject.SetActive(true); } else if (!active && compoent.gameObject.activeSelf) { compoent.gameObject.SetActive(false); } } } public void SetSprite(ImageEx compoent, int awardLv) { if (compoent != null) { if (awardLv > 0) { SetActive(compoent, true); compoent.SetSprite(StringUtility.Concat("LianQiCompositeItemIcon", "_", awardLv.ToString())); } else { SetActive(compoent, false); } } } public void SetTextLv(TextEx compoent, int awardLv) { if (compoent != null) { if (awardLv > 0) { SetActive(compoent, true); compoent.text = awardLv.ToString(); } else { SetActive(compoent, false); } } } public bool IsEnergyEnough(int energy) { return energy > 0; } public void UpdateActLianqiPlayerInfo(HAA91_tagSCActLianqiPlayerInfo pack) { lastPlayerInfo = nowPlayerInfo; nowPlayerInfo = pack; lastGridData = nowGridData; actScore = (int)pack.ScoreHighest; nowGridData = JsonMapper.ToObject<int[][]>(pack.GridData); if (pack.OPType == 1 || pack.OPType == 3) { isPause = false; } else if (pack.OPType == 2 && nowAssistiveItemNum != 4) { isPause = false; } if (pack.OPType == 3) { isWaitReStart = false; } OnLianqiPlayerInfoAction?.Invoke(); UpdateRedpoint(); } public bool IsBillAwardReceived() { return nowPlayerInfo != null && nowPlayerInfo.BillAwardState != 0; } public bool TryGetMyBillAwardConfig(out RankData rankData, out ActBillboardAwardConfig config) { rankData = RankModel.Instance.GetMyRank(loadRankType); config = null; if (rankData == null || rankData.rank <= 0) return false; var list = ActBillboardAwardConfig.GetRankASortList(billTempID); if (list == null) return false; for (int i = 0; i < list.Count; i++) { var tempConfig = ActBillboardAwardConfig.GetConfig(billTempID, list[i]); if (tempConfig == null) continue; if (rankData.rank >= tempConfig.RankA && rankData.rank <= tempConfig.RankB) { config = tempConfig; return true; } } return false; } public bool CanHaveBillAward() { if (!IsInAwardPhase) return false; if (nowPlayerInfo == null || nowPlayerInfo.BillAwardState != 0) return false; RankData rankData; ActBillboardAwardConfig config; return TryGetMyBillAwardConfig(out rankData, out config); } public int PieceCount(int[][] board) { if (board.IsNullOrEmpty()) return 0; int count = 0; for (int i = 0; i < MaxGridRows; i++) { for (int j = 0; j < MaxGridCols; j++) { if (board[i][j] > 0) { count += 1; } } } return count; } public bool IsCanMove(int[][] board, int direction) { if (board.IsNullOrEmpty()) return false; switch (direction) { case 1: // 向上 for (int i = 1; i < MaxGridRows; i++) { for (int j = 0; j < MaxGridCols; j++) { if (board[i][j] != 0 && (board[i - 1][j] == 0 || board[i][j] == board[i - 1][j]) || board[i][j] < MaxItemLv) { return true; } } } break; case 2: // 向下 for (int i = 0; i < MaxGridRows - 1; i++) { for (int j = 0; j < MaxGridCols; j++) { if (board[i][j] != 0 && (board[i + 1][j] == 0 || board[i][j] == board[i + 1][j]) || board[i][j] < MaxItemLv) { return true; } } } break; case 3: // 向左 for (int i = 0; i < MaxGridRows; i++) { for (int j = 1; j < MaxGridCols; j++) { if (board[i][j] != 0 && (board[i][j - 1] == 0 || board[i][j] == board[i][j - 1]) || board[i][j] < MaxItemLv) { return true; } } } break; case 4: // 向右 for (int i = 0; i < MaxGridRows; i++) { for (int j = 0; j < MaxGridCols - 1; j++) { if (board[i][j] != 0 && (board[i][j + 1] == 0 || board[i][j] == board[i][j + 1]) || board[i][j] < MaxItemLv) { return true; } } } break; } return false; } public bool IsDeadLock(int[][] board) { for (int i = 0; i < MaxGridRows; i++) { for (int j = 0; j < MaxGridCols; j++) { if (board[i][j] == 0) { return false; } } } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (j < 3 && board[i][j] == board[i][j + 1]) { if (board[i][j] < MaxItemLv) { return false; } } if (i < 3 && board[i][j] == board[i + 1][j]) { if (board[i][j] < MaxItemLv) { return false; } } } } return true; } public void SendMoveOP(int direction) { SendAA25LianqiOP(1, direction, 0, 0); } public void SendUseOP(int useCount, int useItemIndex, int valueARow, int valueALine, int valueBRow = 0, int valueBLine = 0) { int value1 = useCount * 10 + useItemIndex; int value2 = valueARow * 10 + valueALine; int value3 = valueBRow * 10 + valueBLine; SendAA25LianqiOP(2, value1, value2, value3); } public void SendRestartOP() { SendAA25LianqiOP(3, 0, 0, 0); } public void SendHaveAward(int awardLv) { SendAA25LianqiOP(4, awardLv, 0, 0); } public void SendHaveBillAward() { if (!CanHaveBillAward()) return; SendAA25LianqiOP(5, 0, 0, 0); } public void ClaimReward() { if (nowPlayerInfo == null) return; if (correspondingRewards == null) return; int[] keysArr = new int[correspondingRewards.Count]; int _idx = 0; foreach (int key in correspondingRewards.Keys) { keysArr[_idx] = key; _idx++; } for (int i = 0; i < keysArr.Length; i++) { int rewardLv = keysArr[i]; int state = GetAwardState(rewardLv, (int)nowPlayerInfo.LVAwardState, (int)nowPlayerInfo.LVAwardMax); if (state == 1) { SendHaveAward(rewardLv); } } } public int RewardJumpIndex() { if (nowPlayerInfo == null) return 0; if (correspondingRewards == null) return 0; int[] keysArr = new int[correspondingRewards.Count]; int _idx = 0; foreach (int key in correspondingRewards.Keys) { keysArr[_idx] = key; _idx++; } int lastNonClaimedIndex = -1; for (int i = 0; i < keysArr.Length; i++) { int rewardLv = keysArr[i]; int state = GetAwardState(rewardLv, (int)nowPlayerInfo.LVAwardState, (int)nowPlayerInfo.LVAwardMax); if (state != 2) { return i; } else { lastNonClaimedIndex = i; } } return lastNonClaimedIndex >= 0 ? lastNonClaimedIndex : 0; } public bool IsCanSendUseItem() { if (!IsJoin) { SysNotifyMgr.Instance.ShowTip("ActionUnOpen1"); return false; } int itemID = nowAssistiveItemId; int num = nowAssistiveItemNum; if (packManager.GetItemCountByID(PackType.Item, itemID) <= 0) { SysNotifyMgr.Instance.ShowTip("LianQiAct02"); return false; } if (!limitUsesToolCntDict.TryGetValue(itemID, out int cnt)) return false; int useItemCnt = GetUseItemCnt(nowPlayerInfo.UseItemCntList, num); if (useItemCnt >= cnt) { SysNotifyMgr.Instance.ShowTip("LianQiAct03"); return false; } if (nowAssistiveItemNum == 1) { if (PieceCount(nowGridData) <= 1) { SysNotifyMgr.Instance.ShowTip("LianQiAct06"); return false; } } else if (nowAssistiveItemNum == 2) { if (PieceCount(nowGridData) <= 1) { SysNotifyMgr.Instance.ShowTip("LianQiAct08"); return false; } } else if (nowAssistiveItemNum == 4) { if (nowPlayerInfo.Energy >= maxEnergy) { SysNotifyMgr.Instance.ShowTip("LianQiAct05"); return false; } } return true; } private void SendAA25LianqiOP(int type, int value1, int value2, int value3) { CAA25_tagCSActLianqiOP pack = new CAA25_tagCSActLianqiOP(); pack.OPType = (byte)type; pack.OPValue = (uint)value1; pack.OPValue2 = (uint)value2; pack.OPValue3 = (uint)value3; GameNetSystem.Instance.SendInfo(pack); } #endregion } public class LianQiGiftItem { public int type; // 0 商店 / 1 广告 / 2 CTG充值 public int id; } public class LianQiCompositeItemInfo { public int AwardLv; public string Name; public string Icon; public string Description; } Main/System/LianQi/LianQiManager.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 6d7b7777c8faf2b45b0e10f65ecbaafd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiPopTipWin.cs
New file @@ -0,0 +1,30 @@ using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; public class LianQiPopTipWin : UIBase { [SerializeField] Button popConfirmBtn; [SerializeField] Button popCancelBtn; // [SerializeField] Button closeBtn; LianQiManager model => LianQiManager.Instance; protected override void InitComponent() { popConfirmBtn.AddListener(() => { model.isWaitReStart = true; UIManager.Instance.OpenWindow<LianQiRoundSettlementWin>(); }); popCancelBtn.AddListener(() => { model.isPause = true; CloseWindow(); }); // closeBtn.onClick.AddListener(() => // { // model.isPause = true; // CloseWindow(); // }); } } Main/System/LianQi/LianQiPopTipWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: a4d572792b25a8444a433009e2d6e612 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRankAwardCell.cs
New file @@ -0,0 +1,72 @@ using UnityEngine; public class LianQiRankAwardCell : CellView { [SerializeField] ImageEx imgRank; [SerializeField] TextEx txtRank; [SerializeField] ScrollerController itemScroller; private void OnDisable() { UnbindItemScroller(); } public void Display(int rankA, int templateID) { UnbindItemScroller(); var config = ActBillboardAwardConfig.GetConfig(templateID, rankA); if (config == null) { itemScroller.Refresh(); itemScroller.Restart(); return; } if (rankA <= 3) { imgRank.SetActive(true); txtRank.SetActive(false); imgRank.SetSprite(StringUtility.Concat("Rank", rankA.ToString())); txtRank.text = rankA.ToString(); } else { imgRank.SetActive(false); txtRank.SetActive(true); txtRank.text = Language.Get("Arena15", rankA, config.RankB); } CreateItemScroller(config.AwardItemList); } private void CreateItemScroller(int[][] rewardArr) { itemScroller.OnRefreshCell += OnRefreshItemCell; itemScroller.OnRefreshCompleteEvent += OnRefreshItemComplete; itemScroller.Refresh(); for (int i = 0; i < rewardArr.Length; i++) { CellInfo info = new CellInfo(rewardArr[i][0], rewardArr[i][1], null); itemScroller.AddCell(ScrollerDataType.Header, i, info); } itemScroller.Restart(); } private void OnRefreshItemComplete() { UnbindItemScroller(); } private void OnRefreshItemCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<LianQiRankAwardItemCell>(); _cell?.Display(cell); } private void UnbindItemScroller() { itemScroller.OnRefreshCell -= OnRefreshItemCell; itemScroller.OnRefreshCompleteEvent -= OnRefreshItemComplete; } } Main/System/LianQi/LianQiRankAwardCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: abbe3f17f7bb33a41a72cc99c6a72fbd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRankAwardItemCell.cs
New file @@ -0,0 +1,15 @@ using UnityEngine; public class LianQiRankAwardItemCell : CellView { [SerializeField] ItemCell itemCell; public void Display(CellView cell) { if (cell == null || !cell.info.HasValue) return; int itemID = cell.info.Value.infoInt1; int count = cell.info.Value.infoInt2; itemCell.Init(new ItemCellModel(itemID, true, count)); itemCell.button.SetListener(() => ItemTipUtility.Show(itemID, true)); } } Main/System/LianQi/LianQiRankAwardItemCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 56c2cae1dd95d3a4e87a0dd7ead5c260 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRankCell.cs
New file @@ -0,0 +1,89 @@ using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; public class LianQiRankCell : MonoBehaviour { [SerializeField] AvatarCell avatarCell; [SerializeField] Text rankText; [SerializeField] Text rankValueText; //排名比较内容 [SerializeField] Text nameText; [SerializeField] OfficialTitleCell officialTitleCell; [SerializeField] Button queryPlayerBtn; //后续添加点击查看玩家详情 [SerializeField] TextEx countText;//合成物数量 LianQiManager manager => LianQiManager.Instance; // rank 为0 代表玩家自己 public void Display(int rankType, int rank, string valueFormat) { int billTempID = manager.billTempID; var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank); RankData rankData = null; int viewPlayerId = (int)PlayerDatas.Instance.baseData.PlayerID; int sid = 0; if (rank != 0) { rankData = RankModel.Instance.GetRankDataByRank(rankType, rank); } else { rankData = RankModel.Instance.GetMyRank(rankType); if (rankData == null) { //取玩家自己的数据 avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID, PlayerDatas.Instance.baseData.face, PlayerDatas.Instance.baseData.facePic)); rankText.text = Language.Get("L1045"); rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue); nameText.text = PlayerDatas.Instance.baseData.PlayerName; officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID); if (countText != null) countText.SetActive(false); return; } rank = rankData.rank; } if (rankData == null) { officialTitleCell.SetActive(false); avatarCell.SetActive(false); nameText.text = Language.Get("L1124"); rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue); if (countText != null) countText.SetActive(false); } else { officialTitleCell.SetActive(true); officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2); avatarCell.SetActive(true); avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4)); viewPlayerId = (int)rankData.id; sid = UIHelper.GetServerIDByAccount(rankData.name2); nameText.text = rankData.name1; rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue)); if (countText != null) { int cmpVal = (int)rankData.cmpValue2; if (cmpVal >= manager.MaxItemLv) { countText.SetActive(true); countText.text = StringUtility.Concat("X", (cmpVal - manager.MaxItemLv + 1).ToString()); } else { countText.SetActive(false); } } } rankText.text = rank.ToString(); if (queryPlayerBtn != null) { queryPlayerBtn.AddListener(() => { AvatarHelper.TryViewOtherPlayerInfo(viewPlayerId, sid); }); } } } Main/System/LianQi/LianQiRankCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: ca5fdd745e5d54947a6bd54c0a558f45 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRankTop3Cell.cs
New file @@ -0,0 +1,58 @@ using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; public class LianQiRankTop3Cell : MonoBehaviour { //[SerializeField] Model 显示NPC 武将模型 [SerializeField] Text rankValueText; //排名比较内容 [SerializeField] Text nameText; [SerializeField] OfficialTitleCell officialTitleCell; [SerializeField] Button queryPlayerBtn; //后续添加点击查看玩家详情 [SerializeField] HorseController model; [SerializeField] TextEx countText;//合成物数量 LianQiManager manager => LianQiManager.Instance; public void Display(int rankType, int rank, string valueFormat = "{0}") { int billTempID = manager.billTempID; var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank); var rankData = RankModel.Instance.GetRankDataByRank(rankType, rank); if (rankData == null) { rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut40", awardConfig.NeedValue); nameText.text = Language.Get("L1124"); officialTitleCell.SetActive(false); model.SetActive(false); if (countText != null) countText.SetActive(false); return; } officialTitleCell.SetActive(true); int sid = UIHelper.GetServerIDByAccount(rankData.name2); rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue)); nameText.text = rankData.name1; officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2); model.SetActive(true); model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f); queryPlayerBtn.SetListener(() => { AvatarHelper.TryViewOtherPlayerInfo((int)rankData.id, sid); }); if (countText != null) { int cmpVal = (int)rankData.cmpValue2; if (cmpVal >= manager.MaxItemLv) { countText.SetActive(true); countText.text = StringUtility.Concat("X", (cmpVal - manager.MaxItemLv + 1).ToString()); } else { countText.SetActive(false); } } } } Main/System/LianQi/LianQiRankTop3Cell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: c6440faf5ed25ad45bde8aa5a9be7e88 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRankWin.cs
New file @@ -0,0 +1,83 @@ using System.Collections.Generic; using UnityEngine; public class LianQiRankWin : UIBase { [SerializeField] ScrollerController rankScroller; [SerializeField] List<LianQiRankTop3Cell> playerTop3Cells; [SerializeField] LianQiRankCell myRankCell; [HideInInspector] public string valueFormat = "{0}"; LianQiManager manager => LianQiManager.Instance; protected override void OnPreOpen() { base.OnPreOpen(); RankModel.Instance.ResetQueryParam(); RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: manager.groupValue1, crossServerID: manager.crossServerID); RankModel.Instance.onRankRefresh += OnRankRefresh; rankScroller.OnRefreshCell += OnRefreshCell; Display(); } protected override void OnPreClose() { base.OnPreClose(); RankModel.Instance.onRankRefresh -= OnRankRefresh; rankScroller.OnRefreshCell -= OnRefreshCell; } void OnRankRefresh(int type) { if (type != manager.sendRankType) return; RankRefresh(); } void RankRefresh() { ShowTop3(); rankScroller.m_Scorller.RefreshActiveCellViews(); DisplayMyRank(); } void CreateRankScroller() { rankScroller.Refresh(); var cnt = RankModel.Instance.GetRankShowMaxCnt(manager.sendRankType); for (int i = 3; i < cnt; i++) { rankScroller.AddCell(ScrollerDataType.Header, i); } rankScroller.Restart(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<LianQiRankCell>(); _cell.Display(manager.loadRankType, cell.index + 1, valueFormat); RankModel.Instance.ListenRankPage(manager.sendRankType, cell.index, groupValue1: manager.groupValue1, crossServerID: manager.crossServerID); } public void Display() { ShowTop3(); CreateRankScroller(); DisplayMyRank(); } private void DisplayMyRank() { myRankCell.Display(manager.loadRankType, 0, valueFormat); } void ShowTop3() { for (int i = 0; i < playerTop3Cells.Count; i++) { playerTop3Cells[i].Display(manager.loadRankType, i + 1); } } } Main/System/LianQi/LianQiRankWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 27286beae2fe3a8499faf7a1ebc6d524 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiRoundSettlementWin.cs
New file @@ -0,0 +1,35 @@ using UnityEngine; public class LianQiRoundSettlementWin : UIBase { [SerializeField] TextEx txtInfo; int score; LianQiManager model => LianQiManager.Instance; protected override void OnPreOpen() { if (model.nowPlayerInfo == null) return; score = (int)model.nowPlayerInfo.Score; RankModel.Instance.onRankRefresh += OnRankRefresh; UIManager.Instance.CloseWindow<LianQiPopTipWin>(); model.SendRestartOP(); RankModel.Instance.QueryRankByPage(model.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: model.groupValue1, forceQuery: true, crossServerID: model.crossServerID); txtInfo.text = StringUtility.Concat(Language.Get("LianQi12", score)); } protected override void OnPreClose() { RankModel.Instance.onRankRefresh -= OnRankRefresh; } private void OnRankRefresh(int type) { if (type != model.sendRankType) return; if (model.nowPlayerInfo == null) return; var myRank = RankModel.Instance.GetMyRank(model.loadRankType); if (myRank != null) txtInfo.text = StringUtility.Concat(Language.Get("LianQi12", score), " ", Language.Get("LianQi13", myRank.rank.ToString())); else txtInfo.text = StringUtility.Concat(Language.Get("LianQi12", score), " ", Language.Get("LianQi13", Language.Get("L1045"))); } } Main/System/LianQi/LianQiRoundSettlementWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 726a07544ea852f4ba12e5aa78776817 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiSmallTipWin.cs
New file @@ -0,0 +1,124 @@ using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; public class LianQiSmallTipWin : UIBase { [SerializeField] RectTransform rectTransform; [SerializeField] RectTransform arrowUpImage; [SerializeField] Text descText; [SerializeField] Text itemName; [SerializeField] Image itemImg; [SerializeField] ItemCell[] awards; public static Vector3 worldPos; //世界坐标系位置 public static string showText; public static bool isDownShow = false; // 是否向下显示 public static int showAwardLv; protected override void OnPreOpen() { var M = LianQiManager.Instance; LianQiCompositeItemInfo info; if (M.TryGetCompositeItemInfoByAwardLv(showAwardLv, out info) && info != null) { itemName.text = info.Name; descText.text = info.Description; itemImg.SetSprite(info.Icon); } else { itemName.text = string.Empty; descText.text = string.Empty; } List<Item> rewards = null; bool hasRewards = M.correspondingRewards != null && M.correspondingRewards.TryGetValue(showAwardLv, out rewards) && rewards != null; if (awards != null) { for (int i = 0; i < awards.Length; i++) { if (hasRewards && i < rewards.Count && awards[i] != null) { awards[i].Init(new ItemCellModel(rewards[i].id, false, rewards[i].countEx)); awards[i].SetActive(true); } else if (awards[i] != null) { awards[i].SetActive(false); } } } rectTransform.position = new Vector3(100, 100, 100); //初始化时,屏幕范围外 arrowUpImage.SetActive(isDownShow); } protected override void OnPreClose() { isDownShow = false; } protected override void OnOpen() { UpdatePos(); } async UniTask UpdatePos() { await UniTask.DelayFrame(3); if (this == null) return; // destroyed during await // 限制在屏幕范围内 Vector3[] corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); float minY = corners[0].y; float maxY = corners[0].y; for (int i = 1; i < corners.Length; i++) { if (corners[i].y < minY) minY = corners[i].y; if (corners[i].y > maxY) maxY = corners[i].y; } float screenHeight = maxY - minY; Vector2 adjustedPos = new Vector2(worldPos.x, worldPos.y + (!isDownShow ? screenHeight * 0.5f : -screenHeight * 0.5f)); Vector2 screenAdjustedPos = CameraManager.uiCamera.WorldToScreenPoint(adjustedPos); var rectWidth = rectTransform.rect.width * Screen.width / canvasScaler.referenceResolution.x; screenAdjustedPos.x = Mathf.Clamp(screenAdjustedPos.x, rectWidth * 0.5f, Screen.width - rectWidth * 0.5f); screenAdjustedPos.y = Mathf.Clamp(screenAdjustedPos.y, rectTransform.rect.height * 0.5f, Screen.height - rectTransform.rect.height * 0.5f - 15); adjustedPos = CameraManager.uiCamera.ScreenToWorldPoint(screenAdjustedPos); rectTransform.position = adjustedPos; if (!isDownShow) { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y + 15, rectTransform.localPosition.z); } else { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y - 15, rectTransform.localPosition.z); } rectTransform.GetWorldCorners(corners); float minX = corners[0].x; float maxX = corners[0].x; for (int i = 1; i < corners.Length; i++) { if (corners[i].x < minX) minX = corners[i].x; if (corners[i].x > maxX) maxX = corners[i].x; } Vector3 arrowUpImagePosition = arrowUpImage.position; arrowUpImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX); arrowUpImage.position = arrowUpImagePosition; } } Main/System/LianQi/LianQiSmallTipWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: dcb7be20f4a34e2429c33ee894152490 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiWin.cs
New file @@ -0,0 +1,740 @@ using DG.Tweening; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; public class LianQiWin : UIBase { [SerializeField] ButtonEx btnClose; [SerializeField] ButtonEx btnRank; [SerializeField] ButtonEx btnReward; [SerializeField] ButtonEx btnGift; [SerializeField] ButtonEx btnZhanLing; [SerializeField] ButtonEx serverButton; [SerializeField] ScrollerController awardScroller; [SerializeField] Transform transGameEnd; [SerializeField] TextEx txtEnd; [SerializeField] TextEx txtTip; [SerializeField] TextEx txtTip2; [Header("辅助道具")] [SerializeField] List<ItemCell> assistiveItemCells; [Header("体力和回复时间")] [SerializeField] TextEx txtEnergy; [SerializeField] Transform transEnergyTime; [SerializeField] TextEx txtEnergyTime; [Header("棋盘相关")] [SerializeField] DragSelectComponentEx dragSelect; [SerializeField] ClickScreenOtherSpace clickScreenOtherSpace; [SerializeField] TextEx txtScore; [SerializeField] List<RectTransform> rectStartPos; RectTransform[][] rectStartPosArr; [SerializeField] List<LianQiActLevel1> level1; LianQiActLevel1[][] level1Arr; [SerializeField] List<LianQiActLevel2> level2; LianQiActLevel2[][] level2Arr; Sequence sequence; private const float SynEffectDelay = 0.8f; private const float HammerEffectDelay = 1.4f; protected override void InitComponent() { btnClose.SetListener(CloseWindow); btnRank.SetListener(() => UIManager.Instance.OpenWindow<LianQiRankWin>()); btnReward.SetListener(() => UIManager.Instance.OpenWindow<LianQiAwardWin>()); btnZhanLing.SetListener(() => UIManager.Instance.OpenWindow<LianQiZhanLingWin>()); btnGift.SetListener(() => UIManager.Instance.OpenWindow<LianQiGiftWin>()); serverButton.SetListener(() => { var act = LianQiManager.Instance.operationCrossAct; if (act == null) return; var serverIDList = act.GetServerIDList(); if (serverIDList.Count == 0) return; UIHelper.ShowServersPanel(serverIDList); }); } protected override void OnPreOpen() { var M = LianQiManager.Instance; M.isWaitReStart = false; M.isPause = false; M.isUseTool = false; InitPanel(); dragSelect.onDragComplete += OnDragComplete; M.OnLianqiPlayerInfoAction += OnLianqiPlayerInfoAction; PackManager.Instance.RefreshItemEvent += OnRefreshItemCountEvent; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; awardScroller.OnRefreshCell += OnRefreshAwardCell; clickScreenOtherSpace.AddListener(() => { var M = LianQiManager.Instance; if (!M.isUseTool) return; InitPanel(); // 取消道具模式,重置所有状态 }); // 绑定辅助道具选格按钮 for (int i = 0; i < level2.Count; i++) { int index = i; level2[i].btnChoose.SetListener(() => { var M = LianQiManager.Instance; if (!M.isUseTool || !M.isStartChoose) return; if (M.nowAssistiveItemNum == 1 && M.isChoose1) return; if (M.nowAssistiveItemNum == 2 && M.isChoose1 && M.isChoose2) return; if (M.nowAssistiveItemNum == 3 && M.isChoose1) return; if (M.nowAssistiveItemNum == 4) return; // 道具2(化腐朽):棋盘只有一个物品无法交换 if (M.nowAssistiveItemNum == 2 && M.PieceCount(M.nowGridData) <= 1) { SysNotifyMgr.Instance.ShowTip("LianQiAct08"); return; } // 道具3(九天玄铁):等级超限 if (M.nowAssistiveItemNum == 3 && M.nowGridData[level2[index].row][level2[index].col] >= M.jiuTianYunTieLevelLimit) { SysNotifyMgr.Instance.ShowTip("LianQiAct04"); InitPanel(); return; } level2[index].isChooseShow = !level2[index].isChooseShow; level2[index].imgChoose.SetActive(level2[index].isChooseShow); if (!M.isChoose1) { M.useRow1 = level2[index].row; M.useCol1 = level2[index].col; M.isChoose1 = true; // 单选道具(1/3)选满立即确认 if (M.nowAssistiveItemNum == 1 || M.nowAssistiveItemNum == 3) TryConfirmUseTool(); } else if (!M.isChoose2) { // 道具2第2格不能与第1格相同 if (level2[index].row == M.useRow1 && level2[index].col == M.useCol1) { SysNotifyMgr.Instance.ShowTip("LianQiAct07"); InitPanel(); return; } M.useRow2 = level2[index].row; M.useCol2 = level2[index].col; M.isChoose2 = true; // 双选道具(2)选满立即确认 if (M.nowAssistiveItemNum == 2) TryConfirmUseTool(); } }); } DisplayScore(); DisplayEnergy(); SecondChange(); DisplayActivityTime(); RefreshGameEndState(); } protected override void OnPreClose() { var M = LianQiManager.Instance; dragSelect.onDragComplete -= OnDragComplete; M.OnLianqiPlayerInfoAction -= OnLianqiPlayerInfoAction; PackManager.Instance.RefreshItemEvent -= OnRefreshItemCountEvent; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; awardScroller.OnRefreshCell -= OnRefreshAwardCell; clickScreenOtherSpace.RemoveAllListeners(); sequence.Kill(); } protected override void OnOpen() { CreateAwardScroller(); } private void CreateAwardScroller() { var M = LianQiManager.Instance; var dict = M.correspondingRewards; awardScroller.Refresh(); if (dict == null) return; int[] keysArr = new int[dict.Count]; int _idx = 0; foreach (int key in dict.Keys) { keysArr[_idx] = key; _idx++; } for (int i = 0; i < keysArr.Length; i++) { awardScroller.AddCell(ScrollerDataType.Header, i); } awardScroller.Restart(); awardScroller.JumpIndex(M.RewardJumpIndex()); } private void OnRefreshAwardCell(ScrollerDataType type, CellView cell) { cell.GetComponent<LianQiAwardCell>()?.Display(cell.index); } private void PlaySynEffect(LianQiActLevel2 grid) { grid.synUIEffect.Stop(); grid.synUIEffect.Play(); } private void OnDragComplete(int direction) { var M = LianQiManager.Instance; M.isPause = false; if (M.nowPlayerInfo == null) return; if (!UIManager.Instance.IsOpened<LianQiWin>()) return; if (!M.IsJoin) { SysNotifyMgr.Instance.ShowTip("ActionUnOpen1"); return; } if (!M.IsEnergyEnough(M.nowPlayerInfo.Energy)) { SysNotifyMgr.Instance.ShowTip("LianQiAct01"); M.isUseTool = true; int index = 3; M.nowAssistiveItemNum = index + 1; // = 4 int itemID = M.assistiveItemArr[index]; M.nowAssistiveItemId = itemID; UIManager.Instance.OpenWindow<LianQiItemInfoDoubleWin>(); return; } InitPanel(); int dir = 0; switch (direction) { case 1: dir = 4; break; // 向右 case -1: dir = 3; break; // 向左 case 2: dir = 1; break; // 向上 case -2: dir = 2; break; // 向下 } if (!M.IsCanMove(M.nowGridData, dir)) { SysNotifyMgr.Instance.ShowTip("LianqiMoveUnable"); return; } M.SendMoveOP(dir); } private void OnLianqiPlayerInfoAction() { var M = LianQiManager.Instance; DisplayScore(); DisplayEnergy(); DisplayAssistiveItem(); // 刷新辅助道具数量(道具4使用后尤其需要) SecondChange(); RefreshGameEndState(); awardScroller.m_Scorller.RefreshActiveCellViews(); int[][] nowGridData = M.nowGridData; int[][] lastGridData = M.lastGridData; if (lastGridData.IsNullOrEmpty()) return; if (M.nowPlayerInfo.OPType == 1) { if (M.nowPlayerInfo.MoveList.Length > 0) { sequence = DOTween.Sequence(); bool hasSynEffect = false; for (int i = 0; i < M.nowPlayerInfo.MoveList.Length; i++) { var move = M.nowPlayerInfo.MoveList[i]; var girdLevel1From = level1Arr[move.Row][move.Col]; var girdLevel2From = level2Arr[move.Row][move.Col]; var girdLevel2To = level2Arr[move.ToRow][move.ToCol]; var StartPosFrom = rectStartPosArr[move.Row][move.Col]; bool isComposite = nowGridData[move.ToRow][move.ToCol] > lastGridData[move.Row][move.Col]; if (isComposite) hasSynEffect = true; M.SetTextLv(girdLevel1From.txtLv, lastGridData[move.Row][move.Col]); M.SetSprite(girdLevel1From.imgItem, lastGridData[move.Row][move.Col]); M.SetActive(girdLevel2From.imgItem, false); sequence.Join(girdLevel1From.transform.DOMove(rectStartPosArr[move.ToRow][move.ToCol].position, 0.1f).SetEase(Ease.Linear).OnComplete(() => { M.SetTextLv(girdLevel2To.txtLv, nowGridData[move.ToRow][move.ToCol]); M.SetSprite(girdLevel2To.imgItem, nowGridData[move.ToRow][move.ToCol]); M.SetActive(girdLevel1From.imgItem, false); girdLevel1From.transform.position = StartPosFrom.position; if (isComposite) PlaySynEffect(girdLevel2To); })); } if (hasSynEffect) sequence.AppendInterval(SynEffectDelay); sequence.OnComplete(() => { InitPanel(); }); } } else if (M.nowPlayerInfo.OPType == 2) { if (M.nowAssistiveItemNum == 1) // 锻造锤:特效动画 { M.isPlayAssistiveItemAnimation = true; var grid = level2Arr[M.useRow1][M.useCol1]; grid.hammerUIEffect.Stop(); grid.hammerUIEffect.Play(); sequence = DOTween.Sequence(); sequence.AppendInterval(HammerEffectDelay).OnComplete(() => { InitPanel(); }); } else if (M.nowAssistiveItemNum == 2) // 化腐朽:双格level1互换 { M.isPlayAssistiveItemAnimation = true; var grid1Level1 = level1Arr[M.useRow1][M.useCol1]; var grid1Level2 = level2Arr[M.useRow1][M.useCol1]; var grid2Level1 = level1Arr[M.useRow2][M.useCol2]; var grid2Level2 = level2Arr[M.useRow2][M.useCol2]; var startPos1 = rectStartPosArr[M.useRow1][M.useCol1]; var startPos2 = rectStartPosArr[M.useRow2][M.useCol2]; sequence = DOTween.Sequence(); sequence.Join(grid1Level1.transform.DOMove(startPos2.position, 0.5f).SetEase(Ease.Linear) .OnStart(() => { M.SetTextLv(grid1Level1.txtLv, M.lastGridData[M.useRow1][M.useCol1]); M.SetSprite(grid1Level1.imgItem, M.lastGridData[M.useRow1][M.useCol1]); M.SetActive(grid1Level2.imgItem, false); }) .OnComplete(() => { M.SetActive(grid1Level1.imgItem, false); M.SetSprite(grid1Level2.imgItem, M.nowGridData[M.useRow1][M.useCol1]); M.SetTextLv(grid1Level2.txtLv, M.nowGridData[M.useRow1][M.useCol1]); grid1Level1.transform.position = startPos1.position; })); sequence.Join(grid2Level1.transform.DOMove(startPos1.position, 0.5f).SetEase(Ease.Linear) .OnStart(() => { M.SetTextLv(grid2Level1.txtLv, M.lastGridData[M.useRow2][M.useCol2]); M.SetSprite(grid2Level1.imgItem, M.lastGridData[M.useRow2][M.useCol2]); M.SetActive(grid2Level2.imgItem, false); }) .OnComplete(() => { M.SetActive(grid2Level1.imgItem, false); M.SetSprite(grid2Level2.imgItem, M.nowGridData[M.useRow2][M.useCol2]); M.SetTextLv(grid2Level2.txtLv, M.nowGridData[M.useRow2][M.useCol2]); grid1Level2.transform.position = startPos2.position; })); sequence.OnComplete(() => { InitPanel(); }); } else if (M.nowAssistiveItemNum == 3) // 九天玄铁:合成特效 { M.isPlayAssistiveItemAnimation = true; var grid = level2Arr[M.useRow1][M.useCol1]; sequence = DOTween.Sequence(); PlaySynEffect(grid); sequence.AppendInterval(SynEffectDelay).OnComplete(() => { InitPanel(); }); } // nowAssistiveItemNum==4(玉露):无棋盘动画;道具数量已在本方法开头刷新 } else if (M.nowPlayerInfo.OPType == 3) // 重新开始:直接刷新棋盘 { InitPanel(); } } private void LateUpdate() { var M = LianQiManager.Instance; if (M.nowGridData == null) return; if (M.IsDeadLock(M.nowGridData)) { if (UIManager.Instance.IsOpened<LianQiRoundSettlementWin>()) return; if (UIManager.Instance.IsOpened<LianQiItemInfoDoubleWin>()) return; if (UIManager.Instance.IsOpened<LianQiItemInfoWin>()) return; if (!M.IsJoin) return; if (M.isWaitReStart) return; if (M.isPause) return; if (M.isUseTool) return; if (!UIManager.Instance.IsOpened<LianQiPopTipWin>()) UIManager.Instance.OpenWindow<LianQiPopTipWin>(); } } /// <summary> /// 选格确认:按当前道具类型发起确认弹窗或直接发送 /// </summary> private void TryConfirmUseTool() { var M = LianQiManager.Instance; if (M.nowAssistiveItemNum == 1 && M.isStartChoose && M.isChoose1) { if (!M.TryGetCompositeItemInfoByAwardLv(M.nowGridData[M.useRow1][M.useCol1], out LianQiCompositeItemInfo info) || info == null) return; if (!ItemConfig.HasKey(M.nowAssistiveItemId)) return; var itemConfig = ItemConfig.Get(M.nowAssistiveItemId); if (M.isSkip1) { M.isUseTool = false; if (M.IsCanSendUseItem()) M.SendUseOP(1, 0, M.useRow1, M.useCol1); else InitPanel(); } else { ConfirmCancel.ToggleConfirmCancelEx(Language.Get("Mail101"), Language.Get("LianQi29", info.Name, itemConfig.ItemName), Language.Get("ConfirmCancel102"), OnConfirm1, OnConfirm1, M.isSkip1); } } else if (M.nowAssistiveItemNum == 2 && M.isStartChoose && M.isChoose1 && M.isChoose2) { if (!M.TryGetCompositeItemInfoByAwardLv(M.nowGridData[M.useRow1][M.useCol1], out LianQiCompositeItemInfo info1) || info1 == null) return; if (!M.TryGetCompositeItemInfoByAwardLv(M.nowGridData[M.useRow2][M.useCol2], out LianQiCompositeItemInfo info2) || info2 == null) return; if (!ItemConfig.HasKey(M.nowAssistiveItemId)) return; var itemConfig = ItemConfig.Get(M.nowAssistiveItemId); if (M.isSkip2) { M.isUseTool = false; if (M.IsCanSendUseItem()) M.SendUseOP(1, 1, M.useRow1, M.useCol1, M.useRow2, M.useCol2); else InitPanel(); } else { ConfirmCancel.ToggleConfirmCancelEx(Language.Get("Mail101"), Language.Get("LianQi28", itemConfig.ItemName, info1.Name, info2.Name), Language.Get("ConfirmCancel102"), OnConfirm2, OnConfirm2, M.isSkip2); } } else if (M.nowAssistiveItemNum == 3 && M.isStartChoose && M.isChoose1) { if (!M.TryGetCompositeItemInfoByAwardLv(M.nowGridData[M.useRow1][M.useCol1], out LianQiCompositeItemInfo info) || info == null) return; if (!ItemConfig.HasKey(M.nowAssistiveItemId)) return; var itemConfig = ItemConfig.Get(M.nowAssistiveItemId); if (M.isSkip3) { M.isUseTool = false; if (M.IsCanSendUseItem()) M.SendUseOP(1, 2, M.useRow1, M.useCol1); else InitPanel(); } else { ConfirmCancel.ToggleConfirmCancelEx(Language.Get("Mail101"), Language.Get("LianQi29", info.Name, itemConfig.ItemName), Language.Get("ConfirmCancel102"), OnConfirm3, OnConfirm3, M.isSkip3); } } } private void OnConfirm1(bool isOk, bool isToggle) { var M = LianQiManager.Instance; M.isSkip1 = isToggle; M.isUseTool = false; if (isOk && M.IsCanSendUseItem()) M.SendUseOP(1, 0, M.useRow1, M.useCol1); else InitPanel(); } private void OnConfirm2(bool isOk, bool isToggle) { var M = LianQiManager.Instance; M.isSkip2 = isToggle; M.isUseTool = false; if (isOk && M.IsCanSendUseItem()) M.SendUseOP(1, 1, M.useRow1, M.useCol1, M.useRow2, M.useCol2); else InitPanel(); } private void OnConfirm3(bool isOk, bool isToggle) { var M = LianQiManager.Instance; M.isSkip3 = isToggle; M.isUseTool = false; if (isOk && M.IsCanSendUseItem()) M.SendUseOP(1, 2, M.useRow1, M.useCol1); else InitPanel(); } private void OnSecondEvent() { SecondChange(); RefreshGameEndState(); } private void SecondChange() { var M = LianQiManager.Instance; if (M.nowPlayerInfo == null) { transEnergyTime.SetActive(false); return; } int currentTime = TimeUtility.AllSeconds; int rSecond = M.rSecond; int energyTime = (int)M.nowPlayerInfo.EnergyTime; if (energyTime == 0) { transEnergyTime.SetActive(false); return; } int resTime = rSecond - (currentTime - energyTime); if (rSecond > 0) { txtEnergyTime.text = TimeUtility.SecondsToDHMS(resTime); transEnergyTime.SetActive(true); } else { transEnergyTime.SetActive(false); } } private void DisplayEnergy() { var M = LianQiManager.Instance; if (M.nowPlayerInfo == null) txtEnergy.text = Language.Get("BlessedLand036", 0, M.maxEnergy); else txtEnergy.text = Language.Get("BlessedLand036", M.nowPlayerInfo.Energy, M.maxEnergy); } private void DisplayScore() { var M = LianQiManager.Instance; if (M.nowPlayerInfo == null) txtScore.text = Language.Get("LianQi07", 0); else txtScore.text = Language.Get("LianQi07", M.nowPlayerInfo.Score); } private void DisplayActivityTime() { var M = LianQiManager.Instance; var act = M.operationCrossAct; if (act == null || act.flowPhases == null || act.flowPhases.Count == 0) return; var first = act.flowPhases[0]; var last = act.flowPhases[act.flowPhases.Count - 1]; string tip = string.Format("{0:D2}/{1:D2} {2:D2}:{3:D2}:00~{4:D2}/{5:D2} {6:D2}:{7:D2}:59", act.startDate.month, act.startDate.day, first.StartHour, first.StartMinute, act.endDate.month, act.endDate.day, last.EndHour, last.EndMinute); txtTip.text = Language.Get("FestivalActivity01", tip); string joinRange = string.Empty; for (int i = 0; i < act.flowPhases.Count; i++) { if (act.flowPhases[i].StateValue == 1) { var p = act.flowPhases[i]; int totalMin = p.EndHour * 60 + p.EndMinute + 1; joinRange = string.Format("{0:D2}:{1:D2}-{2:D2}:{3:D2}", p.StartHour, p.StartMinute, (totalMin / 60) % 24, totalMin % 60); break; } } txtTip2.text = Language.Get("LianQi08", joinRange); } private void RefreshGameEndState() { var M = LianQiManager.Instance; if (M.operationCrossAct == null) { transGameEnd.SetActive(false); return; } bool isJoin = M.IsJoin; transGameEnd.SetActive(!isJoin); if (!isJoin) { txtEnd.text = M.IsInPublicityPhase ? Language.Get("LianQi31") : Language.Get("LianQi32"); } } private void InitPanel() { if (this == null) return; // 防御:Clock 回调在窗口销毁后触发 var M = LianQiManager.Instance; sequence.Kill(); rectStartPosArr = RectTransListToArr(rectStartPos); level1Arr = LianQiActLevelListToArr(level1); level2Arr = LianQiActLevelListToArr(level2); M.isPlayAssistiveItemAnimation = false; M.isUseTool = false; M.isStartChoose = false; M.isChoose1 = false; M.isChoose2 = false; for (int i = 0; i < M.MaxGridCount; i++) { M.SetActive(level1[i].imgItem, false); M.SetActive(level2[i].imgItem, false); level1[i].transform.localPosition = rectStartPos[i].transform.localPosition; level2[i].transform.localPosition = rectStartPos[i].transform.localPosition; level2[i].synUIEffect.Stop(); level2[i].hammerUIEffect.Stop(); level2[i].imgChoose.SetActive(false); level2[i].isChooseShow = false; level2[i].imgChoose.SetActive(level2[i].isChooseShow); } if (M.nowPlayerInfo == null) return; int[][] gridData = M.nowGridData; if (!gridData.IsNullOrEmpty()) { for (int i = 0; i < gridData.Length; i++) { for (int j = 0; j < gridData[i].Length; j++) { if (gridData[i][j] > 0) { level2Arr[i][j].imgItem.SetSprite(StringUtility.Concat("LianQiCompositeItemIcon", "_", gridData[i][j].ToString())); M.SetTextLv(level2Arr[i][j].txtLv, gridData[i][j]); M.SetActive(level2Arr[i][j].imgItem, true); } } } } // 每次刷新棋盘后刷新辅助道具显示 DisplayAssistiveItem(); } /// <summary> /// 外部道具数量变化时刷新辅助道具栏(邮件/任务/购买等获得辅助道具) /// </summary> private void OnRefreshItemCountEvent(PackType type, int index, int itemID) { var M = LianQiManager.Instance; if (M.assistiveItemArr.IsNullOrEmpty()) return; // 仅刷新:道具背包整体变化(type==Item) 或 变化物品是辅助道具之一 if (type != PackType.Item && !M.assistiveItemArr.Contains(itemID)) return; DisplayAssistiveItem(); } /// <summary> /// 刷新辅助道具栏显示 /// </summary> private void DisplayAssistiveItem() { var M = LianQiManager.Instance; if (M.assistiveItemArr.IsNullOrEmpty()) return; for (int i = 0; i < assistiveItemCells.Count; i++) { int index = i; if (index < M.assistiveItemArr.Length) { int itemID = M.assistiveItemArr[index]; long count = PackManager.Instance.GetItemCountByID(PackType.Item, itemID); assistiveItemCells[index].Init(new ItemCellModel(itemID, false, count)); assistiveItemCells[index].countText.SetActive(true); assistiveItemCells[index].countText.text = count.ToString(); assistiveItemCells[index].button.SetListener(() => { if (M.isPlayAssistiveItemAnimation) return; M.isUseTool = true; M.nowAssistiveItemNum = index + 1; M.nowAssistiveItemId = itemID; if (M.nowAssistiveItemNum == 4) UIManager.Instance.OpenWindow<LianQiItemInfoDoubleWin>(); else UIManager.Instance.OpenWindow<LianQiItemInfoWin>(); }); } else { assistiveItemCells[i].SetActive(false); } } } private RectTransform[][] RectTransListToArr(List<RectTransform> list) { var M = LianQiManager.Instance; int maxRowGrid = M.MaxGridRows; int maxLineGrid = M.MaxGridCols; RectTransform[][] arr = new RectTransform[maxRowGrid][]; for (int i = 0; i < maxRowGrid; i++) { arr[i] = new RectTransform[maxLineGrid]; } int index = 0; for (int i = 0; i < maxRowGrid; i++) { for (int j = 0; j < maxLineGrid; j++) { arr[i][j] = list[index]; index++; } } return arr; } private LianQiActLevel1[][] LianQiActLevelListToArr(List<LianQiActLevel1> list) { var M = LianQiManager.Instance; int maxRowGrid = M.MaxGridRows; int maxLineGrid = M.MaxGridCols; LianQiActLevel1[][] arr = new LianQiActLevel1[maxRowGrid][]; for (int i = 0; i < maxRowGrid; i++) { arr[i] = new LianQiActLevel1[maxLineGrid]; } int index = 0; for (int i = 0; i < maxRowGrid; i++) { for (int j = 0; j < maxLineGrid; j++) { arr[i][j] = list[index]; index++; } } return arr; } private LianQiActLevel2[][] LianQiActLevelListToArr(List<LianQiActLevel2> list) { var M = LianQiManager.Instance; int maxRowGrid = M.MaxGridRows; int maxLineGrid = M.MaxGridCols; LianQiActLevel2[][] arr = new LianQiActLevel2[maxRowGrid][]; for (int i = 0; i < maxRowGrid; i++) { arr[i] = new LianQiActLevel2[maxLineGrid]; } int index = 0; for (int i = 0; i < maxRowGrid; i++) { for (int j = 0; j < maxLineGrid; j++) { arr[i][j] = list[index]; index++; } } return arr; } } Main/System/LianQi/LianQiWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: af0caad58ecd61d4698d52b34c9b1bbc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiZhanLingCell.cs
New file @@ -0,0 +1,126 @@ using System.Collections.Generic; using UnityEngine; public class LianQiZhanLingCell : CellView { [SerializeField] ItemCell freeItemCell; [SerializeField] Transform freeGotRect; [SerializeField] Transform baseCanGetAwardRect; [SerializeField] ItemCell[] paidAwards; [SerializeField] Transform[] paidGotRects; [SerializeField] Transform[] paidCanGetRects; [SerializeField] Transform[] paidLockRects; [SerializeField] ItemCell[] paidHAwards; [SerializeField] Transform[] paidHGotRects; [SerializeField] Transform[] paidHCanGetRects; [SerializeField] Transform[] paidHLockRects; [SerializeField] Transform upProcssBGRect; [SerializeField] Transform upProcessRect; [SerializeField] Transform downProcssBGRect; [SerializeField] Transform downProcessRect; [SerializeField] TextEx txtUnlockLV; [SerializeField] Transform mask; LianQiManager manager => LianQiManager.Instance; public void Display(int needValue) { var totalValue = BattlePassManager.Instance.GetTotalValue(manager.ZhanLingType); int zhanlingId = ZhanlingConfig.GetTypeToIDDict(manager.ZhanLingType)[needValue]; int freeState = manager.GetZhanLingFreeGiftState(needValue); int paidState = manager.GetZhanLingPaidGiftState(needValue); int paidHState = manager.GetZhanLingPaidGiftHState(needValue); int buyState = manager.GetZhanLingBuyState(); freeGotRect.SetActive(freeState == 2); baseCanGetAwardRect.SetActive(freeState == 1); mask.SetActive(freeState == 0); for (int i = 0; i < paidAwards.Length; i++) { bool isBuy = buyState == 1 || buyState == 3; paidGotRects[i].SetActive(paidState == 2); paidCanGetRects[i].SetActive(paidState == 1 && isBuy); paidLockRects[i].SetActive(!isBuy || paidState == 0); } for (int i = 0; i < paidHAwards.Length; i++) { bool isBuy = buyState == 2 || buyState == 3; paidHGotRects[i].SetActive(paidHState == 2); paidHCanGetRects[i].SetActive(paidHState == 1 && isBuy); paidHLockRects[i].SetActive(!isBuy || paidHState == 0); } txtUnlockLV.text = needValue.ToString(); // 进度条显示逻辑 var ids = new List<int>(); foreach (int val in ZhanlingConfig.GetTypeToIDDict(manager.ZhanLingType).Values) { ids.Add(val); } ids.Sort(); upProcssBGRect.SetActive(ids[0] != zhanlingId); upProcessRect.SetActive(freeState != 0); downProcssBGRect.SetActive(ids[ids.Count - 1] != zhanlingId); var nextConfig = ZhanlingConfig.Get(zhanlingId + 1); downProcessRect.SetActive(nextConfig != null && totalValue >= nextConfig.NeedValue); // 展示ItemCell var config = ZhanlingConfig.Get(zhanlingId); if (config == null) return; // 免费奖励 int freeItemId = config.FreeRewardItemList[0][0]; freeItemCell.Init(new ItemCellModel(freeItemId, false, config.FreeRewardItemList[0][1])); freeItemCell.button.onClick.RemoveAllListeners(); freeItemCell.button.onClick.AddListener(() => { if (freeState == 1) manager.HaveAllZhanLingGift(); else ItemTipUtility.Show(freeItemId); }); // 普通奖励 for (int i = 0; i < paidAwards.Length; i++) { if (i >= config.ZLRewardItemList.Length) continue; int itemId2 = config.ZLRewardItemList[i][0]; paidAwards[i].Init(new ItemCellModel(itemId2, false, config.ZLRewardItemList[i][1])); paidAwards[i].button.onClick.RemoveAllListeners(); paidAwards[i].button.onClick.AddListener(() => { if (buyState == 0 || buyState == 2) manager.ShowZhanLingHBuy(manager.ZhanLingType, 1); else if (paidState == 1) manager.HaveAllZhanLingGift(); else ItemTipUtility.Show(itemId2); }); } // 高级奖励 for (int i = 0; i < paidHAwards.Length; i++) { if (i >= config.ZLRewardItemListH.Length) continue; int itemId3 = config.ZLRewardItemListH[i][0]; paidHAwards[i].Init(new ItemCellModel(itemId3, false, config.ZLRewardItemListH[i][1])); paidHAwards[i].button.onClick.RemoveAllListeners(); paidHAwards[i].button.onClick.AddListener(() => { if (buyState == 0 || buyState == 1) manager.ShowZhanLingHBuy(manager.ZhanLingType, 2); else if (paidHState == 1) manager.HaveAllZhanLingGift(); else ItemTipUtility.Show(itemId3); }); } } } Main/System/LianQi/LianQiZhanLingCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 01d25e56104ca3641bc593d2d438f7fc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiZhanLingPreviewCell.cs
New file @@ -0,0 +1,26 @@ using UnityEngine; using System.Collections.Generic; public class LianQiZhanLingPreviewCell : CellView { [SerializeField] ItemCell items; public void Display(int rowIndex, List<Item> showItems) { if (showItems == null || rowIndex >= showItems.Count) { items.SetActive(false); return; } items.SetActive(true); int itemID = showItems[rowIndex].id; long count = showItems[rowIndex].countEx; items.Init(new ItemCellModel(itemID, false, count)); items.button.onClick.RemoveAllListeners(); items.button.onClick.AddListener(() => { ItemTipUtility.Show(itemID); }); } } Main/System/LianQi/LianQiZhanLingPreviewCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 2665fd70d1cbb434daeaac801ad084e5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiZhanLingPreviewWin.cs
New file @@ -0,0 +1,115 @@ using System; using UnityEngine; using UnityEngine.UI; public class LianQiZhanLingPreviewWin : UIBase { [SerializeField] ScrollerController allScroller; //所有等级奖励 [SerializeField] Button btnClose; [SerializeField] Button btnBuy; [SerializeField] Text txtBuy; [SerializeField] Text txtPercentage; [SerializeField] Image imgMoney; [SerializeField] Text txtMoney; [SerializeField] Image imgTitleLow; [SerializeField] Image imgTitleHigh; [SerializeField] ScrollerController nowScroller; //当前等级奖励 LianQiManager manager => LianQiManager.Instance; int ctgID; int showCnt = 10; protected override void OnPreOpen() { allScroller.OnRefreshCell += OnScrollerRefreshAllCell; nowScroller.OnRefreshCell += OnScrollerRefreshNowCell; btnClose.AddListener(CloseWindow); btnBuy.AddListener(OnBuyClick); Display(); } protected override void OnPreClose() { allScroller.OnRefreshCell -= OnScrollerRefreshAllCell; nowScroller.OnRefreshCell -= OnScrollerRefreshNowCell; } void OnBuyClick() { if (ctgID == 0) { CloseWindow(); return; } CloseWindow(); RechargeManager.Instance.CTG(ctgID); } protected override void NextFrameAfterOpen() { CreateAllScroller(); CreateNowScroller(); } private void OnScrollerRefreshAllCell(ScrollerDataType type, CellView cell) { var _cell = cell as LianQiZhanLingPreviewCell; _cell.Display(_cell.index, manager.GetPreviewGiftAllItem(showCnt)); } private void OnScrollerRefreshNowCell(ScrollerDataType type, CellView cell) { var _cell = cell as LianQiZhanLingPreviewCell; _cell.Display(_cell.index, manager.GetPreviewGiftNowItem(showCnt)); } void Display() { ctgID = manager.GetPreviewCtgID(); var config = CTGConfig.Get(ctgID); if (config == null) { CloseWindow(); return; } OrderInfoConfig orderCfg; RechargeManager.Instance.TryGetOrderInfo(ctgID, out orderCfg); txtPercentage.text = Language.Get("TimingGift02", config.Percentage); txtBuy.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderCfg.PayRMBNumOnSale)); imgMoney.SetIconWithMoneyType(config.MoneyType); txtMoney.text = config.GainGold.ToString(); imgTitleLow.SetActive(manager.previewGiftType == 1); imgTitleHigh.SetActive(manager.previewGiftType == 2); } private void CreateAllScroller() { var items = manager.GetPreviewGiftAllItem(showCnt); allScroller.Refresh(); if (items == null || items.Count == 0) return; for (int i = 0; i < items.Count; i++) { allScroller.AddCell(ScrollerDataType.Header, i); } allScroller.Restart(); } private void CreateNowScroller() { var items = manager.GetPreviewGiftNowItem(showCnt); nowScroller.Refresh(); if (items == null || items.Count == 0) return; for (int i = 0; i < items.Count; i++) { nowScroller.AddCell(ScrollerDataType.Header, i); } nowScroller.Restart(); } } Main/System/LianQi/LianQiZhanLingPreviewWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: a8bb1a13a5649904dbc930f266fec87e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/LianQiZhanLingWin.cs
New file @@ -0,0 +1,114 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // 武将登场战令 public class LianQiZhanLingWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx closeBtn; [SerializeField] ButtonEx btnPaid; [SerializeField] ButtonEx btnPaidH; [SerializeField] ImageEx imgPaidLock; [SerializeField] ImageEx imgPaidLockH; [SerializeField] Text txtNowNeedValue; [SerializeField] Text txtPaidLock; [SerializeField] Text txtPaidLockH; [SerializeField] Text txtPaidLockBuyed; [SerializeField] Text txtPaidLockBuyedH; LianQiManager manager => LianQiManager.Instance; protected override void InitComponent() { btnPaid.AddListener(OnPaidClick); btnPaidH.AddListener(OnPaidHClick); closeBtn.AddListener(CloseWindow); } protected override void OnPreOpen() { manager.OnZhanLingUpdateEvent += OnZhanLingUpdateEvent; scroller.OnRefreshCell += OnScrollerRefreshCell; Initialize(); Display(); } protected override void OnPreClose() { manager.OnZhanLingUpdateEvent -= OnZhanLingUpdateEvent; scroller.OnRefreshCell -= OnScrollerRefreshCell; } private void Display() { //0 没购买进阶和玄级 1 购买了进阶没买玄级 2 购买了玄级没买进阶 3 购买了进阶和玄级 int buyState = manager.GetZhanLingBuyState(); scroller.m_Scorller.RefreshActiveCellViews(); txtNowNeedValue.text = Language.Get("LianQi24", manager.GetZhanLingValue()); // imgPaidLock: 未购买进阶(type 1)且未购买玄级(type 2)时显示锁,或已购买玄级但未购买进阶时显示锁 imgPaidLock.SetActive(buyState == 0 || buyState == 2); // imgPaidLockH: 未购买玄级且未购买进阶时显示锁,或已购买进阶但未购买玄级时显示锁 imgPaidLockH.SetActive(buyState == 0 || buyState == 1); txtPaidLock.SetActive(buyState == 0 || buyState == 2); txtPaidLockBuyed.SetActive(buyState == 1 || buyState == 3); txtPaidLockH.SetActive(buyState == 0 || buyState == 1); txtPaidLockBuyedH.SetActive(buyState == 2 || buyState == 3); } private void OnZhanLingUpdateEvent() { Display(); scroller.m_Scorller.RefreshActiveCellViews(); } private void OnScrollerRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as LianQiZhanLingCell; _cell.Display(_cell.index); } private void Initialize() { var cellList = new List<int>(); foreach (int key in ZhanlingConfig.GetTypeToIDDict(manager.ZhanLingType).Keys) { cellList.Add(key); } scroller.Refresh(); for (int i = 0; i < cellList.Count; i++) { scroller.AddCell(ScrollerDataType.Header, cellList[i]); } scroller.Restart(); var data = BattlePassManager.Instance.GetBattlePassData(manager.ZhanLingType); var totalValue = BattlePassManager.Instance.GetTotalValue(manager.ZhanLingType); scroller.JumpIndex(BattlePassManager.Instance.JumpIndex(data, manager.ZhanLingType, totalValue)); } void OnPaidClick() { int buyState = manager.GetZhanLingBuyState(); // 已购买进阶(type 1)或已购买玄级和进阶(buyState == 3)时不再跳转 if (buyState == 1 || buyState == 3) return; manager.ShowZhanLingHBuy(manager.ZhanLingType, 1); } void OnPaidHClick() { int buyState = manager.GetZhanLingBuyState(); // 已购买玄级(type 2)或已购买玄级和进阶(buyState == 3)时不再跳转 if (buyState == 2 || buyState == 3) return; manager.ShowZhanLingHBuy(manager.ZhanLingType, 2); } } Main/System/LianQi/LianQiZhanLingWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 2c4d75e9485645649935520c73ea3dc8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/LianQi/OperationLianQiCross.cs
New file @@ -0,0 +1,162 @@ using System; using System.Collections.Generic; using UnityEngine; //轮回殿活动 public class OperationLianQiCross : OperationBase { string m_ServerIDRangeInfo; //开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服 public string m_ServerListStr; public int m_GroupValue1; // 活动榜单分组值1,用于查询对应榜单 public int m_CrossServerID; // 所属跨服服务器ID public int CfgID; public int ActFuncType; public int ActTempID; public ActTypeConfig actTempConfig; public string ActFlow; public List<ActTimeFlowConfig> flowPhases; public override bool SatisfyOpenCondition() { return PlayerDatas.Instance.baseData.LV >= limitLv; } //显示参与时间 public string ToDisplayJoinTime() { if (flowPhases == null) return string.Empty; var textBuilder = OperationTimeHepler.textBuilder; textBuilder.Length = 0; bool found = false; for (int i = 0; i < flowPhases.Count; i++) { if (flowPhases[i].StateValue == 1) { textBuilder.Append(string.Format(" {0}:{1}", flowPhases[i].StartHour.ToString("D2"), flowPhases[i].StartMinute.ToString("D2"))); textBuilder.Append(" - "); textBuilder.Append(string.Format(" {0}:{1}", flowPhases[i].EndHour.ToString("D2"), flowPhases[i].EndMinute.ToString("D2"))); found = true; break; } } return found ? textBuilder.ToString() : string.Empty; } public override string ToDisplayTime() { var textBuilder = OperationTimeHepler.textBuilder; textBuilder.Length = 0; textBuilder.Append(startDate.ToDisplay(false)); textBuilder.Append(" - "); textBuilder.Append(endDate.ToDisplay(false)); return textBuilder.ToString(); } //结果展示时间 转为倒计时,以跨服时间为准 public string ShowResultTime() { var endDataTime = TimeUtility.GetDayStartTime(TimeUtility.CrossServerNow.Year, TimeUtility.CrossServerNow.Month, TimeUtility.CrossServerNow.Day).AddDays(1); return TimeUtility.SecondsToHMS((int)(endDataTime - TimeUtility.CrossServerNow).TotalSeconds); } //是否展示结果时间, 以跨服时间为准(前提为以判断是活动中) public bool IsShowResultTime() { var endJoinDateTime = new DateTime(endDate.year, endDate.month, endDate.day, joinEndHour, joinEndMinute, 0); return TimeUtility.CrossServerNow >= endJoinDateTime; } public int GetCurrentPhaseState() { if (flowPhases == null || flowPhases.Count == 0) return 0; var startDateDt = new DateTime(startDate.year, startDate.month, startDate.day); int day = (TimeUtility.CrossServerNow.Date - startDateDt).Days + 1; if (day < 1) return 0; if (TimeUtility.CrossServerNow.Date > new DateTime(endDate.year, endDate.month, endDate.day)) return 0; int nowTotalMin = (day - 1) * 1440 + TimeUtility.CrossServerNow.Hour * 60 + TimeUtility.CrossServerNow.Minute; for (int i = 0; i < flowPhases.Count; i++) { var p = flowPhases[i]; int phaseStartMin = (p.StartDay - 1) * 1440 + p.StartHour * 60 + p.StartMinute; int phaseEndMin = (p.EndDay - 1) * 1440 + p.EndHour * 60 + p.EndMinute; if (phaseStartMin <= nowTotalMin && nowTotalMin <= phaseEndMin) return p.StateValue; } return 0; } public bool IsInJoinPhase() { return GetCurrentPhaseState() == 1; } public bool IsInPublicityPhase() { return GetCurrentPhaseState() == 90; } public bool IsInAwardPhase() { return GetCurrentPhaseState() == 99; } public List<int> GetServerIDList() { List<int> serverIDList = new List<int>(); if (string.IsNullOrEmpty(m_ServerIDRangeInfo) || m_ServerIDRangeInfo == "[]") { return serverIDList; } LitJson.JsonData serverArray = LitJson.JsonMapper.ToObject(m_ServerIDRangeInfo); for (int i = 0; i < serverArray.Count; i++) { LitJson.JsonData serverInfo = serverArray[i]; if (serverInfo.IsArray) { int startID = (int)serverInfo[0]; int endID = serverInfo.Count > 1 ? (int)serverInfo[1] : startID; for (int j = startID; j <= endID; j++) { serverIDList.Add(j); } } else { serverIDList.Add((int)serverInfo); } } return serverIDList; } public override void Reset() { base.Reset(); CfgID = 0; ActFuncType = 0; ActTempID = 0; actTempConfig = null; ActFlow = null; flowPhases = null; m_CrossServerID = 0; } public void ParseCrossActLianqiInfo(HAA90_tagSCActLianqiInfo package) { m_ServerIDRangeInfo = package.ServerIDInfo; m_ServerListStr = UIHelper.GetServers(m_ServerIDRangeInfo); m_GroupValue1 = (int)package.ZoneID; m_CrossServerID = (int)package.CrossServerID; CfgID = package.CfgID; var actTime = ActTimeConfig.Get(CfgID); if (actTime == null) { Debug.LogError(string.Format("ActTimeConfig 缺失 CfgID={0}", CfgID)); return; } ActNum = actTime.ActNum; ActFuncType = actTime.ActFuncType; ActTempID = actTime.ActTempID; actTempConfig = ActTypeConfig.GetConfig(ActFuncType, ActTempID); if (actTempConfig == null) { Debug.LogError(string.Format("ActTypeConfig 缺失 ActFuncType={0} ActTempID={1}", ActFuncType, ActTempID)); return; } ActFlow = actTime.ActFlow; flowPhases = ActTimeFlowConfig.GetByActFlow(ActFlow); } } Main/System/LianQi/OperationLianQiCross.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: d3150b2cf4acd60448a57d04ba4c924d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/Main/HomeWin.cs
@@ -79,6 +79,7 @@ [SerializeField] GradientText festivalTitleText; [SerializeField] OutlineEx festivalTitleOutline; [SerializeField] Button superVIPBtn; [SerializeField] Button lianQiBtn; //坐骑 [SerializeField] Image horseBGImg; @@ -245,6 +246,10 @@ { UIManager.Instance.OpenWindow<SuperVIPWin>(); }); lianQiBtn.AddListener(() => { UIManager.Instance.OpenWindow<LianQiWin>(); }); } @@ -314,6 +319,7 @@ DisplayHeroSkinFlash(); DisplayFestivalActivity(); DisplaySuperVipBtn(); DisplayLianQiButton(); DelayPlayMusic().Forget(); } @@ -371,6 +377,10 @@ { DisplayHeroSkinFlash(); } else if (type == OperationType.LianQiCross) { DisplayLianQiButton(); } } private void OpenServerActivityStateChange() @@ -381,6 +391,7 @@ DisplayGalaBtn(); DisplayFestivalActivity(); DisplayHeroSkinFlash(); DisplayLianQiButton(); } private void OnShowGiftIdListAddEvent() @@ -896,6 +907,10 @@ { DisplayHeroSkinFlash(); } else if (funcId == (int)FuncOpenEnum.LianQi) { DisplayLianQiButton(); } } private void OnUpdateFirstChargeInfo() @@ -1022,6 +1037,12 @@ superVIPBtn.SetActive(isOpen); SuperVipManager.Instance.UpdateRedpoint(); } void DisplayLianQiButton() { bool isOpen = LianQiManager.Instance.IsLianQiOpen(); lianQiBtn.SetActive(isOpen); } } Main/System/OpenServerActivity/OperationTimeHepler.cs
@@ -120,6 +120,30 @@ } } public void UpdateCrossActLianqiInfo(HAA90_tagSCActLianqiInfo package) { OperationBase operationBase = null; operationDict.TryGetValue(OperationType.LianQiCross, out operationBase); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(OperationType.LianQiCross); return; } if (operationBase == null) { operationBase = new OperationLianQiCross(); operationDict.Add(OperationType.LianQiCross, operationBase); } OperationLianQiCross operation = operationBase as OperationLianQiCross; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ParseCrossActLianqiInfo(package); operationTimeUpdateEvent?.Invoke(OperationType.LianQiCross); } public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package) { OperationBase operationBase = null; @@ -758,5 +782,6 @@ FestivalActivity_CheckIn = 9, //节日活动-签到 FestivalActivity_Mission = 10, //节日活动-任务 HeroSkinFlashSale = 11, //时装特卖 LianQiCross = 12, //炼器大会跨服 max, } Main/System/Redpoint/MainRedDot.cs
@@ -136,7 +136,6 @@ public const int FairyEmbleManageRepoint = 462;//仙盟徽章管理入口红点 public const int YunShiRepoint = 464; //运势 public const int LianQiRepoint = 465; //仙匠大会 public const int FairySiegeRepoint = 466; //仙盟攻城战 public const int MailRepoint = 467; //邮箱 public const int FirstChargeRepoint = 468; //首充 @@ -161,6 +160,7 @@ public const int SuperVIPRepoint = 487; public const int GuildAtkDefBatRepoint = 488;//公会攻防战 public const int HeroTrialRepoint = 489;//武将试炼 public const int LianQiRepoint = 490;//炼器 public void Register() { Main/Utility/EnumHelper.cs
@@ -863,6 +863,7 @@ HeroSkinFlashSale = 66,//时装特卖 GuildAtkDefBat = 67,//公会攻防战 HeroTrial = 68,//武将试炼 LianQi = 69,//炼器大会 }