ArenaDataManager.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using ET;
  5. using UnityEngine;
  6. using FairyGUI;
  7. namespace GFGGame
  8. {
  9. public class ArenaDataManager : SingletonBase<ArenaDataManager>
  10. {
  11. public long LastFightTime = 0; //上次战斗时间,时间为0,说明未战斗过,则没有段位奖励
  12. public List<int> ThemeList = new List<int>() { 1, 2, 3 }; //本周主题列表
  13. public string Tag = "异域"; //本周标签
  14. public int SeasonId = 1; // 赛季id
  15. public int Grade = 1; //本赛季段位
  16. public int Rank = 10000; //本赛季段位内排名
  17. public int HighestGrade = 1; //本赛季最高段位
  18. public int HighestRank = 10000; //本赛最高季段位内排名
  19. public List<FightData> DressupList = new List<FightData>(); //我的搭配列表
  20. public List<ArenaTargetData> Targets = new List<ArenaTargetData>(); //对手
  21. public ArenaTargetData SelfData; //自己的排行榜信息
  22. public ArenaTargetData SelfLastData; //自己的上赛季排行榜信息
  23. public Dictionary<int, List<ArenaTargetData>>
  24. RankDatasDic = new Dictionary<int, List<ArenaTargetData>>(); //排行榜数据
  25. public List<ArenaHistoryData> HistoryDatas = new List<ArenaHistoryData>(); //获取竞技场历史记录
  26. /*************************************************************************************************************************************/
  27. // public Dictionary<int, Texture2D> TextureDic = new Dictionary<int, Texture2D>();
  28. public List<int> roundTime = new List<int>();
  29. public List<int> targetRoundTime = new List<int>();
  30. //Dictionary<回合下标, Dictionary<partId, Dictionary<战斗节点, List<PassivitySkillLvlCfg>>>>
  31. public Dictionary<int, Dictionary<int, Dictionary<int, List<PassivitySkillLvlCfg>>>> vaildSkills =
  32. new Dictionary<int, Dictionary<int, Dictionary<int, List<PassivitySkillLvlCfg>>>>();
  33. public Dictionary<int, Dictionary<int, Dictionary<int, List<PassivitySkillLvlCfg>>>> targetVaildSkills =
  34. new Dictionary<int, Dictionary<int, Dictionary<int, List<PassivitySkillLvlCfg>>>>();
  35. public int SelectThemeIndex = 0; //当前选中换装主题(ThemeList)的下标
  36. public int SelectTargetIndex = -1; //当前选中挑战对象的下标
  37. public int CurFightIndex = 0; //当前挑战场次下标
  38. public List<long> myScore = new List<long>(); //对战数据,三轮分数
  39. public List<long> targetScore = new List<long>(); //对战数据,三轮分数
  40. public List<long> myFightPower = new List<long>(); //对战数据,竞技场战力,搭配战力,卓越点击战力,卡牌战力
  41. public List<long> targetFightPower = new List<long>(); //对战数据,对手竞技场战力,搭配战力,卓越点击战力,卡牌战力
  42. /*************************************************************************************************************************************/
  43. public int LastGrade; //战斗前段位
  44. public int LastRank; //战斗前排行
  45. public OtherRoleInfoData LastTargetInfo = new OtherRoleInfoData(); //战斗对手角色信息
  46. public List<ArenaTargetData> LastTargets = new List<ArenaTargetData>(); //对手
  47. public int RewardId; //段位提升奖励
  48. public List<ItemData> BonusList; //战斗结算奖励
  49. /*************************************************************************************************************************************/
  50. /// <summary>
  51. /// 是否快速挑战
  52. /// </summary>
  53. /// <value></value>
  54. public bool QuickFight
  55. {
  56. get
  57. {
  58. return StorageDataManager.Instance.GetStorageValue(ConstStorageId.ARENA_QUICK_FIGHT) == 1
  59. ? true
  60. : false;
  61. }
  62. set
  63. {
  64. StorageSProxy.ReqSetClientValue(ConstStorageId.ARENA_QUICK_FIGHT, value == true ? 1 : 0).Coroutine();
  65. }
  66. }
  67. public void Clear()
  68. {
  69. ThemeList.Clear();
  70. DressupList.Clear();
  71. Targets.Clear();
  72. RankDatasDic.Clear();
  73. HistoryDatas.Clear();
  74. // TextureDic.Clear();
  75. myScore.Clear();
  76. targetScore.Clear();
  77. myFightPower.Clear();
  78. targetFightPower.Clear();
  79. roundTime.Clear();
  80. targetRoundTime.Clear();
  81. // LastTargetInfo = null;
  82. SelfData = null;
  83. SelfLastData = null;
  84. }
  85. /// <summary>
  86. /// 是否结算中
  87. /// </summary>
  88. /// <returns></returns>
  89. public bool IsArenaClearing
  90. {
  91. get
  92. {
  93. long curTime = TimeHelper.ServerNow();
  94. long startTime = TimeUtil.GetCurWeekTime(GlobalCfgArray.globalCfg.clearingStartWeekDay,
  95. GlobalCfgArray.globalCfg.clearingStartTime);
  96. long endTime = TimeUtil.GetCurWeekTime(GlobalCfgArray.globalCfg.clearingEndWeekDay,
  97. GlobalCfgArray.globalCfg.clearingEndTime);
  98. if (GlobalCfgArray.globalCfg.clearingEndWeekDay >= GlobalCfgArray.globalCfg.clearingStartWeekDay)
  99. {
  100. //结算时间开始到结束未跨周(例:本周六开始,本周日结束)
  101. return curTime >= startTime && curTime <= endTime;
  102. }
  103. else
  104. {
  105. //结算时间开始到结束跨周(例:本周六开始,下周一结束)
  106. return curTime <= endTime || curTime >= startTime;
  107. }
  108. }
  109. }
  110. /// <summary>
  111. /// 赛季是否开启
  112. /// </summary>
  113. /// <value></value>
  114. public bool IsSeasonOpen
  115. {
  116. get
  117. {
  118. ArenaOpenCfg cfg = ArenaOpenCfgArray.Instance.GetCfg(SeasonId);
  119. if (TimeUtil.IsBeforeCurTime(cfg.openTime) && TimeUtil.IsLaterCurTime(cfg.endTime))
  120. {
  121. return true;
  122. }
  123. return false;
  124. }
  125. }
  126. /// <summary>
  127. /// 试图更新最高段位、排行数据
  128. /// </summary>
  129. public void TryUpdateHighest()
  130. {
  131. HighestGrade = HighestGrade >= Grade ? HighestGrade : Grade;
  132. HighestRank = HighestRank >= Rank ? HighestRank : Rank;
  133. }
  134. //获取竞技场对手角色战斗数据
  135. public FightData GetArenaFightData(int index, ArenaTargetData arenaTarget)
  136. {
  137. return arenaTarget.FightDatas[index];
  138. }
  139. /// <summary>
  140. /// 获取推荐卡牌
  141. /// </summary>
  142. public int GetRecommentCardId(int scoreType, List<int> itemList, List<int> wearCardIds)
  143. {
  144. float dressListAllAcore = FightDataManager.Instance.GetDressListAllScore(itemList, scoreType);
  145. List<CardData> cardDatas = FightDataManager.Instance.SortCardList(CardDataManager.GetCardListByRarity(0),
  146. dressListAllAcore, scoreType);
  147. cardDatas = cardDatas.Where(a => !wearCardIds.Contains(a.id)).ToList();
  148. if (cardDatas.Count == 0) return 0;
  149. wearCardIds.Add(cardDatas[0].itemCfg.id);
  150. return cardDatas[0].itemCfg.id;
  151. }
  152. /// <summary>
  153. /// 获取推荐列表
  154. /// </summary>
  155. /// <param name="scoreType"></param>
  156. /// <param name="tags"></param>
  157. /// <returns></returns>
  158. public List<int> GetRecommentItemList(int scoreType, string[] tags)
  159. {
  160. Dictionary<int, List<int>> itemListDic = new Dictionary<int, List<int>>();
  161. Dictionary<int, List<int>> itemDatasDic = DressUpMenuItemDataManager.ItemDatasBySubTypeDic;
  162. foreach (int subType in itemDatasDic.Keys)
  163. {
  164. int key = subType;
  165. if (itemDatasDic.Count == 0) continue;
  166. if (DressUpMenuItemCfg1Array.Instance.CheckIsSceneTypeBySubType(subType)) continue;
  167. List<int> dressList = SortDressList(itemDatasDic[subType], scoreType, tags);
  168. int max = subType == (int)ConstDressUpItemType.TE_SHU ? 3 : 1;
  169. max = Math.Min(max, dressList.Count);
  170. if (DressUpMenuItemCfg1Array.Instance.CheckIsOrnamentsTypeBySubType(subType))
  171. {
  172. key = ConstDressUpItemType.TE_SHU; //饰品全放在一个列表里
  173. }
  174. if (!itemListDic.ContainsKey(key))
  175. {
  176. itemListDic[key] = new List<int>();
  177. }
  178. itemListDic[key].AddRange(dressList.GetRange(0, max));
  179. }
  180. bool isHasLYQ = itemListDic.ContainsKey(ConstDressUpItemType.LIAN_YI_QUN);
  181. bool isHasSY = itemListDic.ContainsKey(ConstDressUpItemType.SHANG_YI);
  182. bool isHasXZ = itemListDic.ContainsKey(ConstDressUpItemType.XIA_ZHUANG);
  183. bool isHasND = itemListDic.ContainsKey(ConstDressUpItemType.NEI_DA);
  184. int countTagLYQ =
  185. isHasLYQ && ItemDataManager.CheckItemTagsRight(itemListDic[ConstDressUpItemType.LIAN_YI_QUN][0], tags)
  186. ? 1
  187. : 0;
  188. int countTagSY =
  189. isHasSY && ItemDataManager.CheckItemTagsRight(itemListDic[ConstDressUpItemType.SHANG_YI][0], tags)
  190. ? 1
  191. : 0;
  192. int countTagXZ =
  193. isHasXZ && ItemDataManager.CheckItemTagsRight(itemListDic[ConstDressUpItemType.XIA_ZHUANG][0], tags)
  194. ? 1
  195. : 0;
  196. int countTagND =
  197. isHasND && ItemDataManager.CheckItemTagsRight(itemListDic[ConstDressUpItemType.NEI_DA][0], tags)
  198. ? 1
  199. : 0;
  200. if (countTagLYQ > countTagSY + countTagXZ + countTagND)
  201. {
  202. itemListDic.Remove(ConstDressUpItemType.NEI_DA);
  203. itemListDic.Remove(ConstDressUpItemType.SHANG_YI);
  204. itemListDic.Remove(ConstDressUpItemType.XIA_ZHUANG);
  205. }
  206. else if (countTagLYQ < countTagSY + countTagXZ + countTagND)
  207. {
  208. itemListDic.Remove(ConstDressUpItemType.LIAN_YI_QUN);
  209. }
  210. else
  211. {
  212. int scoreLYQ = !isHasLYQ
  213. ? 0
  214. : ItemDataManager.GetItemAdditionScore(itemListDic[ConstDressUpItemType.LIAN_YI_QUN][0], scoreType,
  215. tags);
  216. int scoreSY = !isHasSY
  217. ? 0
  218. : ItemDataManager.GetItemAdditionScore(itemListDic[ConstDressUpItemType.SHANG_YI][0], scoreType,
  219. tags);
  220. int scoreXZ = !isHasXZ
  221. ? 0
  222. : ItemDataManager.GetItemAdditionScore(itemListDic[ConstDressUpItemType.XIA_ZHUANG][0], scoreType,
  223. tags);
  224. int scoreND = !isHasND
  225. ? 0
  226. : ItemDataManager.GetItemAdditionScore(itemListDic[ConstDressUpItemType.NEI_DA][0], scoreType,
  227. tags);
  228. if (scoreLYQ > scoreSY + scoreXZ + scoreND)
  229. {
  230. itemListDic.Remove(ConstDressUpItemType.SHANG_YI);
  231. itemListDic.Remove(ConstDressUpItemType.XIA_ZHUANG);
  232. itemListDic.Remove(ConstDressUpItemType.NEI_DA);
  233. }
  234. else
  235. {
  236. itemListDic.Remove(ConstDressUpItemType.LIAN_YI_QUN);
  237. }
  238. }
  239. List<int> itemList = new List<int>();
  240. foreach (int subType in itemListDic.Keys)
  241. {
  242. DressUpMenuItemDataManager.SortItemListByHighScore(itemListDic[subType]);
  243. if (subType == ConstDressUpItemType.TE_SHU)
  244. {
  245. int max = Math.Min(itemListDic[subType].Count, 5);
  246. itemList.AddRange(itemListDic[subType].GetRange(0, max));
  247. }
  248. else
  249. {
  250. itemList.AddRange(itemListDic[subType]);
  251. }
  252. }
  253. return itemList;
  254. }
  255. private List<int> SortDressList(List<int> dressList, int scoreType, string[] tags)
  256. {
  257. dressList.Sort((int a, int b) =>
  258. {
  259. ItemCfg cfgA = ItemCfgArray.Instance.GetCfg(a);
  260. ItemCfg cfgB = ItemCfgArray.Instance.GetCfg(b);
  261. bool isTagA = ItemDataManager.CheckItemTagsRight(a, tags);
  262. bool isTagB = ItemDataManager.CheckItemTagsRight(b, tags);
  263. if (isTagA && !isTagB) return -1;
  264. if (isTagB && !isTagA) return 1;
  265. int scoreA = ItemDataManager.GetItemAdditionScore(a, scoreType, tags);
  266. int scoreB = ItemDataManager.GetItemAdditionScore(b, scoreType, tags);
  267. if (scoreA > scoreB) return -1;
  268. if (scoreA < scoreB) return 1;
  269. return cfgA.id - cfgB.id;
  270. });
  271. return dressList;
  272. }
  273. /// <summary>
  274. /// 获取符合标签的服装总个数
  275. /// </summary>
  276. /// <param name="itemList">服装列表</param>
  277. /// <param name="tags">标签</param>
  278. /// <returns></returns>
  279. public int GetTagsCount(List<int> itemList, string[] tags)
  280. {
  281. int count = 0;
  282. for (int i = 0; i < itemList.Count; i++)
  283. {
  284. if (ItemDataManager.CheckItemTagsRight(itemList[i], tags))
  285. {
  286. if (ItemUtilCS.GetItemSubType(itemList[i]) == ConstDressUpItemType.LIAN_YI_QUN)
  287. {
  288. count += 3;
  289. }
  290. {
  291. count++;
  292. }
  293. }
  294. }
  295. return count;
  296. }
  297. /*********************************************************************************************************************/
  298. public void SetMineFightAttrs()
  299. {
  300. for (int i = 0; i < DressupList.Count; i++)
  301. {
  302. SetMineFightAttr(DressupList[i], ThemeList[i]);
  303. }
  304. }
  305. public void SetMineFightAttr(FightData fightData, int theme)
  306. {
  307. fightData.cardScore = ItemDataManager.GetItemAdditionScore(fightData.cardId, theme, fightData.tags);
  308. fightData.skillLvs = SkillDataManager.Instance.GetCardSkillLvs(fightData.cardId);
  309. FightDataManager.Instance.SetItemScoreList(fightData);
  310. }
  311. /// <summary>
  312. /// 获取三套服装总战力
  313. /// </summary>
  314. /// <param name="roleType"></param>
  315. /// <param name="roleDatas"></param>
  316. /// <param name="robotDatas"></param>
  317. /// <returns></returns>
  318. public long GetAllFightScore(List<long> fightScores)
  319. {
  320. long fightScore = 0;
  321. for (int i = 0; i < fightScores.Count; i++)
  322. {
  323. fightScore += fightScores[i];
  324. }
  325. return fightScore;
  326. }
  327. public long GetAllFightScore(List<FightData> roleDatas)
  328. {
  329. long fightScore = 0;
  330. List<long> fightScoreDatas = GetFightScoreList(roleDatas);
  331. for (int i = 0; i < fightScoreDatas.Count; i++)
  332. {
  333. fightScore += fightScoreDatas[i];
  334. }
  335. return fightScore;
  336. }
  337. /// <summary>
  338. /// index=0:搭配战力
  339. /// index=1:卓越点击战力
  340. /// index=2:卡牌战力/技能战力
  341. /// </summary>
  342. /// <param name="roleType"></param>
  343. /// <param name="fightDatas"></param>
  344. /// <param name="robotDatas"></param>
  345. /// <returns></returns>
  346. public List<long> GetFightScoreList(List<FightData> fightDatas)
  347. {
  348. List<long> fightScoreDatas = new List<long>();
  349. long itemSum = 0;
  350. double clickScore = 0;
  351. long skillScore = 0;
  352. for (int i = 0; i < ThemeList.Count; i++)
  353. {
  354. if (fightDatas[i].type == FightTargetType.PLAYER)
  355. {
  356. long itemsScore = GetItemScoreSum(fightDatas[i].itemScoreList);
  357. itemSum += itemsScore;
  358. clickScore += GetPerfectClickScore(fightDatas[i]);
  359. skillScore += FightDataManager.Instance.GetSkillFightScore(itemsScore, fightDatas[i].baseScore,
  360. fightDatas[i].leagueSkillScore, fightDatas[i].cardId, fightDatas[i].cardScore,
  361. fightDatas[i].skillLvs);
  362. }
  363. else
  364. {
  365. long itemsScore = GetItemScoreSum(fightDatas[i].itemScoreList);
  366. itemSum += itemsScore;
  367. clickScore += GetRobotPerfectClickScore(fightDatas[i]);
  368. skillScore += FightDataManager.Instance.GetSkillFightScore(itemsScore, fightDatas[i].baseScore,
  369. fightDatas[i].leagueSkillScore, fightDatas[i].cardId, fightDatas[i].cardScore,
  370. fightDatas[i].skillLvs);
  371. }
  372. }
  373. clickScore = clickScore / ConstScoreSystem.PART_SCORE;
  374. fightScoreDatas.Add(itemSum);
  375. fightScoreDatas.Add((long)Math.Ceiling(clickScore));
  376. fightScoreDatas.Add(skillScore);
  377. return fightScoreDatas;
  378. }
  379. /// <summary>
  380. /// 所有部件主属性和
  381. /// </summary>
  382. /// <returns></returns>
  383. public long GetItemScoreSum(List<float> itemScoreList)
  384. {
  385. long scoreSum = 0;
  386. for (int i = 0; i < itemScoreList.Count; i++)
  387. {
  388. scoreSum += (long)itemScoreList[i];
  389. }
  390. return scoreSum;
  391. }
  392. //玩家卓越点击战力
  393. private long GetPerfectClickScore(FightData roleData)
  394. {
  395. double clickScore = 0;
  396. foreach (int key in roleData.pardScoreListDic.Keys)
  397. {
  398. double partBaseScore = ScoreSystemData.Instance.GetPartBaseScore(roleData, key);
  399. double score =
  400. (partBaseScore + (roleData.baseScore + roleData.leagueSkillScore + roleData.cardScore) *
  401. ConstScoreSystem.PERFECT_SCORE) * ConstScoreSystem.CLICK_SCORE;
  402. clickScore += score;
  403. }
  404. return (long)Math.Ceiling(clickScore);
  405. }
  406. //机器人卓越点击战力
  407. private long GetRobotPerfectClickScore(FightData robotData)
  408. {
  409. long clickScore = 0;
  410. FightScoreCfg[] scoreCfg = FightScoreCfgArray.Instance.dataArray;
  411. for (int i = 0; i < scoreCfg.Length; i++)
  412. {
  413. clickScore +=
  414. (long)ScoreSystemData.Instance.GetRobotPartScore(robotData, i + 1, ClickType.PREFACT_CLICK, 0);
  415. }
  416. return clickScore;
  417. }
  418. /************************************************************************************************************/
  419. public void AddCheckSeasonOpenTimer()
  420. {
  421. RemoveCheckSeasonOpenTimer();
  422. Timers.inst.Add(1, 0, OnTimeUpdate);
  423. }
  424. private void OnTimeUpdate(object param)
  425. {
  426. if (!IsSeasonOpen) return;
  427. if (ThemeList.Count == 0)
  428. {
  429. ReqArenaInfo();
  430. }
  431. RemoveCheckSeasonOpenTimer();
  432. }
  433. public async void ReqArenaInfo()
  434. {
  435. if (FunctionOpenDataManager.Instance.CheckIsFunOpenById(typeof(ArenaView).Name, false))
  436. {
  437. await ArenaSproxy.ReqArenaInfos();
  438. for (int i = 0; i < ArenaDataManager.Instance.Targets.Count; i++)
  439. {
  440. ArenaTargetData targetData = ArenaDataManager.Instance.Targets[i];
  441. if (targetData.Type == FightTargetType.PLAYER)
  442. {
  443. ArenaSproxy.ReqArenaFightAttr(targetData.RoleInfo.roleId, targetData.FightDatas).Coroutine();
  444. }
  445. }
  446. ArenaSproxy.ReqArenaHistory().Coroutine();
  447. }
  448. }
  449. private void RemoveCheckSeasonOpenTimer()
  450. {
  451. Timers.inst.Remove(OnTimeUpdate);
  452. }
  453. }
  454. }