EventSystemManager.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Common.Utility.CombatEvent;
  5. using Core.Language;
  6. using Excel2Json;
  7. using Fort23.Core;
  8. using Fort23.Mono;
  9. using Fort23.UTool;
  10. using GameLogic.Combat;
  11. using GameLogic.Combat.CombatTool;
  12. using UnityEngine;
  13. using Utility;
  14. using EventConfig = Excel2Json.EventConfig;
  15. using Random = UnityEngine.Random;
  16. public class EventSystemManager : Singleton<EventSystemManager>
  17. {
  18. List<EventConfig> eventConfigs = new List<EventConfig>();
  19. public AccountFileInfo.EventList CurrentEventList;
  20. public bool isTriggerEvent;
  21. List<DivineSenseConfig> divineSenseConfigs = new List<DivineSenseConfig>();
  22. List<int> qualitys = new List<int>() { 1, 2, 3, 4, 5, 6 };
  23. public bool isOpenUi;
  24. Action onCompleteCallback;
  25. public void CustomInit()
  26. {
  27. eventConfigs = ConfigComponent.Instance.GetAll<EventConfig>().ToList();
  28. divineSenseConfigs = ConfigComponent.Instance.GetAll<DivineSenseConfig>().ToList();
  29. StaticUpdater.Instance.AddRenderUpdateCallBack(Update);
  30. EventManager.Instance.AddEventListener(CustomEventType.DetectRandomEvent, RenfenceRandomEvent);
  31. EventManager.Instance.AddEventListener(CustomEventType.AddItem, ItemUpdate);
  32. EventManager.Instance.AddEventListener(CustomEventType.JingJieUpgrade, JingJieUpgrade);
  33. }
  34. private void JingJieUpgrade(IEventData e)
  35. {
  36. CeekEventCompletes(3, null);
  37. }
  38. private void ItemUpdate(IEventData e)
  39. {
  40. ItemUpdateData data = e as ItemUpdateData;
  41. CeekEventCompletes(1, new[] { data.ItemInfo.itemID });
  42. CeekEventCompletes(6, new[] { data.ItemInfo.itemID, data.Count });
  43. }
  44. private void RenfenceRandomEvent(IEventData e)
  45. {
  46. DetectRandomEvents();
  47. }
  48. private float timer = 0;
  49. private void Update()
  50. {
  51. timer += Time.deltaTime;
  52. if (timer > 1)
  53. {
  54. timer = 0;
  55. HeroPowerUpConfig heroPowerUpConfig = PlayerManager.Instance.myHero.powerUpConfig;
  56. if (AccountFileInfo.Instance.playerData.divineSensePoint < heroPowerUpConfig.ShenshiMax)
  57. {
  58. AccountFileInfo.Instance.playerData.divineSensePoint += 3;
  59. EventManager.Instance.Dispatch(CustomEventType.DivineSensePointChange, null);
  60. AccountFileInfo.Instance.SavePlayerData();
  61. }
  62. }
  63. }
  64. public List<AccountFileInfo.EventList> UseDivinesense()
  65. {
  66. HeroPowerUpConfig heroPowerUpConfig = PlayerManager.Instance.myHero.powerUpConfig;
  67. int count = AccountFileInfo.Instance.playerData.divineSensePoint / PlayerManager.Instance.gameConstantConfig.DetectEventCount;
  68. if (count <= 0)
  69. {
  70. //神识值不够
  71. return null;
  72. }
  73. int maxCount = heroPowerUpConfig.ShenshiMax / PlayerManager.Instance.gameConstantConfig.DetectEventCount;
  74. count = count + AccountFileInfo.Instance.playerData.eventList.Count > maxCount ? maxCount - AccountFileInfo.Instance.playerData.eventList.Count : count;
  75. int xiaoHao = count * PlayerManager.Instance.gameConstantConfig.DetectEventCount;
  76. AccountFileInfo.Instance.playerData.divineSenseexp += xiaoHao;
  77. AccountFileInfo.Instance.playerData.divineSensePoint -= xiaoHao;
  78. EventManager.Instance.Dispatch(CustomEventType.DivineSensePointChange, null);
  79. // 神识升级逻辑
  80. UpDivinesense();
  81. var eventConfigs = DetectEvents(count);
  82. if (eventConfigs == null || eventConfigs.Count == 0)
  83. return default;
  84. AccountFileInfo.Instance.playerData.eventList.AddRange(eventConfigs);
  85. AccountFileInfo.Instance.SavePlayerData();
  86. return eventConfigs;
  87. }
  88. private void UpDivinesense()
  89. {
  90. for (var i = AccountFileInfo.Instance.playerData.divineSenseLevel - 1; i < divineSenseConfigs.Count; i++)
  91. {
  92. if (AccountFileInfo.Instance.playerData.divineSenseexp >= divineSenseConfigs[i].exp)
  93. {
  94. AccountFileInfo.Instance.playerData.divineSenseexp -= divineSenseConfigs[i].exp;
  95. AccountFileInfo.Instance.playerData.divineSenseLevel = divineSenseConfigs[i].ID;
  96. }
  97. }
  98. AccountFileInfo.Instance.SavePlayerData();
  99. }
  100. private bool BagIsEvent(int eventID)
  101. {
  102. foreach (var eventList in AccountFileInfo.Instance.playerData.eventList)
  103. {
  104. if (eventList.eventID == eventID)
  105. {
  106. return true;
  107. }
  108. }
  109. return false;
  110. }
  111. private bool IsEventTrigger(int eventID)
  112. {
  113. foreach (var eventList in AccountFileInfo.Instance.playerData.completeEvents)
  114. {
  115. if (eventList.eventID == eventID)
  116. {
  117. return true;
  118. }
  119. }
  120. return false;
  121. }
  122. private List<AccountFileInfo.EventList> DetectEvents(int eventCount)
  123. {
  124. PlacesConfig bigMap = ConfigComponent.Instance.Get<PlacesConfig>(PlayerManager.Instance.CurrentPlaces.id);
  125. DivineSenseConfig divineSenseConfig = ConfigComponent.Instance.Get<DivineSenseConfig>(AccountFileInfo.Instance.playerData.divineSenseLevel);
  126. LogTool.Log($"使用神识,神识等级:{AccountFileInfo.Instance.playerData.divineSenseLevel}");
  127. List<AccountFileInfo.EventList> eventLists = new List<AccountFileInfo.EventList>();
  128. //找出可以刷新的支线任务
  129. if (bigMap.ZhixianActivatedPercentage != null)
  130. {
  131. List<EventConfig> zhiXianEvents = new List<EventConfig>();
  132. for (var i = 0; i < bigMap.ZhixianActivatedPercentage.Length; i++)
  133. {
  134. if (PlayerManager.Instance.PlacesBl >= bigMap.ZhixianActivatedPercentage[i])
  135. {
  136. if (!BagIsEvent(bigMap.ZhixianID[i]) && !IsEventTrigger(bigMap.ZhixianID[i]) && CanTriggerEvent(bigMap.ZhixianID[i]))
  137. {
  138. zhiXianEvents.Add(ConfigComponent.Instance.Get<EventConfig>(bigMap.ZhixianID[i]));
  139. }
  140. }
  141. }
  142. foreach (var c in zhiXianEvents)
  143. {
  144. AccountFileInfo.EventList eventList = AddEvent(c.ID);
  145. if (eventList != null)
  146. {
  147. eventLists.Add(eventList);
  148. eventCount--;
  149. if (eventCount == 0)
  150. {
  151. return eventLists;
  152. }
  153. }
  154. }
  155. }
  156. for (int i = 0; i < eventCount; i++)
  157. {
  158. //先掉落出品质
  159. int quality = UtilTools.GetRandomByWeight(qualitys, divineSenseConfig.QualityBonusChance);
  160. // 获取通用事件
  161. List<EventConfig> globalEvents = eventConfigs.Where(e => e.EventTriggerType == 1 && CanTriggerEvent(e.ID) && e.EventQuality == quality && !BagIsEvent(e.ID)).ToList();
  162. //场景特定事件
  163. List<EventConfig> candidateEvents = eventConfigs.Where(e => bigMap.SpecialTaskID.Contains(e.ID) && CanTriggerEvent(e.ID) && e.EventQuality == quality && !BagIsEvent(e.ID)).ToList();
  164. if (candidateEvents.Count == 0 && globalEvents.Count == 0)
  165. {
  166. continue;
  167. }
  168. int randomValue1 = Random.Range(0, 101);
  169. // 达到怪率刷新场景特定事件
  170. //不然刷新通用事件(每个地图都可以刷的)
  171. if (randomValue1 >= bigMap.DivineSenseGeneralProbability && candidateEvents.Count > 0)
  172. {
  173. int randomValue2 = Random.Range(0, candidateEvents.Count);
  174. eventLists.Add(AddEvent(candidateEvents[randomValue2].ID));
  175. }
  176. else if (globalEvents.Count > 0)
  177. {
  178. int randomValue2 = Random.Range(0, globalEvents.Count);
  179. eventLists.Add(AddEvent(globalEvents[randomValue2].ID));
  180. }
  181. }
  182. if (eventLists.Count == 0)
  183. {
  184. LogTool.Error("没有可以触发的事件");
  185. return null;
  186. }
  187. return eventLists;
  188. }
  189. //添加事件
  190. public AccountFileInfo.EventList AddEvent(int eventID)
  191. {
  192. EventConfig eventConfig = ConfigComponent.Instance.Get<EventConfig>(eventID);
  193. AccountFileInfo.EventList eventList = null;
  194. AccountFileInfo.EventList e = AccountFileInfo.Instance.playerData.eventList.FirstOrDefault(e => e.eventID == eventID);
  195. if (e == null)
  196. {
  197. //主线任务只能刷一次
  198. if (eventConfig.EventTriggerType == 4)
  199. {
  200. e = AccountFileInfo.Instance.playerData.completeEvents.FirstOrDefault(e => e.eventID == eventID);
  201. if (e == null)
  202. {
  203. eventList = new AccountFileInfo.EventList();
  204. eventList.eventID = eventID;
  205. }
  206. }
  207. else
  208. {
  209. eventList = new AccountFileInfo.EventList();
  210. eventList.eventID = eventID;
  211. }
  212. }
  213. //初始化神识链条,用于监听条件是否完成
  214. if (eventList != null && eventConfig.EventType != 2)
  215. {
  216. foreach (var i in eventConfig.EventLinksId)
  217. {
  218. AccountFileInfo.EventLinkData eventLinkData = AccountFileInfo.Instance.playerData.eventLinkDatas.FirstOrDefault(el => el.eventLinkId == i);
  219. if (eventLinkData == null)
  220. {
  221. eventLinkData = new AccountFileInfo.EventLinkData();
  222. eventLinkData.eventId = eventList.eventID;
  223. eventLinkData.eventLinkId = i;
  224. AccountFileInfo.Instance.playerData.eventLinkDatas.Add(eventLinkData);
  225. }
  226. eventLinkData.fishCount = 0;
  227. //初始化先检测一些条件
  228. CeekTaskComplete(eventLinkData.eventLinkId, 1, null);
  229. CeekTaskComplete(eventLinkData.eventLinkId, 3, null);
  230. }
  231. }
  232. return eventList;
  233. }
  234. /// <summary>
  235. /// 触发随机事件
  236. /// </summary>
  237. public void DetectRandomEvents()
  238. {
  239. if (isTriggerEvent)
  240. return;
  241. if (isOpenUi)
  242. return;
  243. // 获取随机事件
  244. List<EventConfig> randomEvents = eventConfigs.Where(e => e.EventTriggerType == 2 && CanTriggerEvent(e.ID)).ToList();
  245. if (randomEvents.Count == 0)
  246. {
  247. LogTool.Warning("没有可以刷新的事件");
  248. return;
  249. }
  250. int idex = Random.Range(0, randomEvents.Count);
  251. TriggerEvent(randomEvents[idex]);
  252. }
  253. /// <summary>
  254. /// 挂机事件触发
  255. /// </summary>
  256. public void TriggerEvent(EventConfig evt)
  257. {
  258. if (isTriggerEvent)
  259. return;
  260. isTriggerEvent = true;
  261. LogTool.Log($"触发事件: {evt.EventName} (ID: {evt.ID}, 品质: {evt.EventQuality})");
  262. CombatDrive.Instance.CombatController.ChangeState(CombatController.idle);
  263. DialogueManager.Instance.StartDialogue(evt.EventLinksId[0], evt.ID, () => { CompleteEvent(evt.ID); });
  264. }
  265. /// <summary>
  266. /// 其他类型事件触发
  267. /// </summary>
  268. public async CTask TriggerEvent(AccountFileInfo.EventList evt, Action oncompleteCallBack = null)
  269. {
  270. if (isTriggerEvent)
  271. return;
  272. CTask cTask = CTask.Create();
  273. this.onCompleteCallback = oncompleteCallBack;
  274. isTriggerEvent = true;
  275. EventConfig eventConfig = ConfigComponent.Instance.Get<EventConfig>(evt.eventID);
  276. LogTool.Log($"触发事件: {LanguageManager.Instance.Text(eventConfig.EventName)} (ID: {eventConfig.ID}, 品质: {eventConfig.EventQuality})");
  277. int dialogueID = 0;
  278. if (evt.curStep == 0)
  279. {
  280. dialogueID = eventConfig.EventLinksId[0];
  281. }
  282. else
  283. {
  284. dialogueID = evt.curStep;
  285. }
  286. CurrentEventList = evt;
  287. CombatDrive.Instance.CombatController.ChangeState(CombatController.idle);
  288. DialogueManager.Instance.StartDialogue(dialogueID, eventConfig.ID, () =>
  289. {
  290. CompleteEvent(CurrentEventList);
  291. cTask.SetResult();
  292. }, () =>
  293. {
  294. CancelEvent(CurrentEventList);
  295. cTask.SetResult();
  296. });
  297. await cTask;
  298. }
  299. //任务是否完成
  300. public bool IsEvenkLinkComplete(int eventLinkId)
  301. {
  302. EventLinkConfig eventLinkConfig = ConfigComponent.Instance.Get<EventLinkConfig>(eventLinkId);
  303. if (eventLinkConfig.ConditionType == 0)
  304. return true;
  305. AccountFileInfo.EventLinkData eventLinkData = AccountFileInfo.Instance.playerData.eventLinkDatas.FirstOrDefault(el => el.eventLinkId == eventLinkId);
  306. if (eventLinkData != null)
  307. {
  308. return eventLinkData.fishCount >= eventLinkConfig.finishCount;
  309. }
  310. return false;
  311. }
  312. public void CeekEventCompletes(int type, int[] value)
  313. {
  314. foreach (var playerDataEventLinkData in AccountFileInfo.Instance.playerData.eventLinkDatas)
  315. {
  316. CeekTaskComplete(playerDataEventLinkData.eventLinkId, type, value);
  317. }
  318. EventManager.Instance.Dispatch(CustomEventType.RemoveEvent, null);
  319. }
  320. public void CeekTaskComplete(int eventLiknId, int type, int[] value)
  321. {
  322. //任务完成了跳过检测
  323. if (IsEvenkLinkComplete(eventLiknId))
  324. return;
  325. AccountFileInfo.EventLinkData eventLinkData = AccountFileInfo.Instance.playerData.eventLinkDatas.FirstOrDefault(el => el.eventLinkId == eventLiknId);
  326. EventLinkConfig eventLinkConfig = ConfigComponent.Instance.Get<EventLinkConfig>(eventLiknId);
  327. switch (type)
  328. {
  329. //检测背包道具
  330. case 1:
  331. if (eventLinkConfig.ConditionType == 1)
  332. {
  333. eventLinkData.fishCount += (int)PlayerManager.Instance.BagController.GetItemCount(eventLinkConfig.ConditionPara[0]);
  334. if (IsEvenkLinkComplete(eventLiknId))
  335. {
  336. CompleteTask(eventLiknId);
  337. }
  338. }
  339. break;
  340. //境界检测
  341. case 3:
  342. if (eventLinkConfig.ConditionType == 3 && PlayerManager.Instance.myHero.powerUpConfig.ID >= eventLinkConfig.ConditionPara[0])
  343. {
  344. eventLinkData.fishCount++;
  345. if (IsEvenkLinkComplete(eventLiknId))
  346. {
  347. CompleteTask(eventLiknId);
  348. }
  349. }
  350. break;
  351. //战斗胜利
  352. case 5:
  353. if (eventLinkConfig.ConditionType == 5 && eventLinkConfig.ConditionPara[0] == value[0])
  354. {
  355. eventLinkData.fishCount++;
  356. if (IsEvenkLinkComplete(eventLiknId))
  357. {
  358. CompleteEvent(eventLiknId);
  359. }
  360. }
  361. break;
  362. //获得道具
  363. case 6:
  364. if (eventLinkConfig.ConditionType == 6 && eventLinkConfig.ConditionPara[0] == value[0])
  365. {
  366. eventLinkData.fishCount += value[1];
  367. if (IsEvenkLinkComplete(eventLiknId))
  368. {
  369. CompleteEvent(eventLinkData);
  370. }
  371. }
  372. break;
  373. }
  374. AccountFileInfo.Instance.SavePlayerData();
  375. }
  376. private void CompleteTask(object taskID)
  377. {
  378. }
  379. /// <summary>
  380. /// 检查事件是否满足触发条件。
  381. /// </summary>
  382. private bool CanTriggerEvent(int eventID)
  383. {
  384. var evt = eventConfigs.Find(e => e.ID == eventID);
  385. if (evt.ID == 0)
  386. return false;
  387. switch (evt.EventConditionId)
  388. {
  389. //背包道具检测
  390. case 1:
  391. return PlayerManager.Instance.BagController.GetItemCount(evt.EventValue[0]) >= evt.EventCount;
  392. //境界判断
  393. case 2:
  394. return PlayerManager.Instance.myHero.level >= evt.EventCount;
  395. //概率判断
  396. case 3:
  397. int randomValue1 = Random.Range(0, 1001);
  398. return randomValue1 <= evt.EventCount;
  399. }
  400. return true;
  401. }
  402. /// <summary>
  403. /// 完成事件
  404. /// </summary>
  405. /// <param name="eventID">事件ID</param>
  406. public void CompleteEvent(int evtId)
  407. {
  408. isTriggerEvent = false;
  409. LogTool.Log($"完成挂机事件{evtId}");
  410. EventConfig eventConfig = ConfigComponent.Instance.Get<EventConfig>(evtId);
  411. AccountFileInfo.EventList eventList = new AccountFileInfo.EventList();
  412. eventList.eventID = evtId;
  413. AccountFileInfo.Instance.playerData.completeEvents.Add(eventList);
  414. if (PlayerManager.Instance.CurrentPlaces.progress < 100)
  415. PlayerManager.Instance.CurrentPlaces.progress += eventConfig.Score;
  416. AccountFileInfo.Instance.SavePlayerData();
  417. CombatDrive.Instance.CombatController.ChangeState(CombatController.update);
  418. EventManager.Instance.Dispatch(CustomEventType.CompleteEvent, null);
  419. }
  420. /// <summary>
  421. /// 完成事件
  422. /// </summary>
  423. /// <param name="eventID">事件ID</param>
  424. public void CompleteEvent(AccountFileInfo.EventList eventList, bool isTriggerEvent = false)
  425. {
  426. this.isTriggerEvent = isTriggerEvent;
  427. LogTool.Log($"完成事件{eventList.eventID}");
  428. EventConfig eventConfig = ConfigComponent.Instance.Get<EventConfig>(eventList.eventID);
  429. AccountFileInfo.EventList ceventList = AccountFileInfo.Instance.playerData.completeEvents.FirstOrDefault(ce => ce.eventID == eventList.eventID);
  430. if (ceventList == null)
  431. {
  432. PlacesConfig[] placesConfigs = ConfigComponent.Instance.GetAll<PlacesConfig>();
  433. int pId = 0;
  434. for (var i = 0; i < placesConfigs.Length; i++)
  435. {
  436. if (placesConfigs[i].MainTaskID == null || placesConfigs[i].ZhixianID == null)
  437. continue;
  438. if (placesConfigs[i].MainTaskID.Contains(eventConfig.ID) ||
  439. placesConfigs[i].ZhixianID.Contains(eventConfig.ID))
  440. {
  441. pId = placesConfigs[i].ID;
  442. break;
  443. }
  444. }
  445. if (pId == 0)
  446. {
  447. PlayerManager.Instance.CurrentPlaces.progress += eventConfig.Score;
  448. }
  449. else
  450. {
  451. PlayerManager.Instance.GetPlacesData(pId).progress += eventConfig.Score;
  452. }
  453. }
  454. AccountFileInfo.Instance.playerData.completeEvents.Add(eventList);
  455. // if (PlayerManager.Instance.CurrentPlaces.progress < 100)
  456. //
  457. AccountFileInfo.Instance.playerData.eventList.Remove(eventList);
  458. AccountFileInfo.Instance.SavePlayerData();
  459. if (eventConfig.EventTriggerType == 4)
  460. {
  461. TaskInfoPanel.OpenPanel(eventList.eventID, "任务完成");
  462. }
  463. CombatDrive.Instance.CombatController.ChangeState(CombatController.update);
  464. EventManager.Instance.Dispatch(CustomEventType.CompleteEvent, null);
  465. onCompleteCallback?.Invoke();
  466. onCompleteCallback = null;
  467. }
  468. /// <summary>
  469. /// 完成事件
  470. /// </summary>
  471. /// <param name="eventID">事件ID</param>
  472. public void CompleteEvent(AccountFileInfo.EventLinkData eventLinkData)
  473. {
  474. }
  475. /// <summary>
  476. /// 取消事件
  477. /// </summary>
  478. /// <param name="eventID">事件ID</param>
  479. public void CancelEvent(AccountFileInfo.EventList eventList)
  480. {
  481. LogTool.Log($"取消事件{eventList.eventID}");
  482. isTriggerEvent = false;
  483. EventManager.Instance.Dispatch(CustomEventType.CompleteEvent, null);
  484. CombatDrive.Instance.CombatController.ChangeState(CombatController.update);
  485. onCompleteCallback?.Invoke();
  486. onCompleteCallback = null;
  487. }
  488. public void RemoveEvent(AccountFileInfo.EventList eventList)
  489. {
  490. AccountFileInfo.Instance.playerData.eventList.Remove(eventList);
  491. AccountFileInfo.Instance.SavePlayerData();
  492. EventManager.Instance.Dispatch(CustomEventType.RemoveEvent, null);
  493. }
  494. /// <summary>
  495. /// 获得主线事件
  496. /// </summary>
  497. /// <returns></returns>
  498. public AccountFileInfo.EventList GetMainEventDta()
  499. {
  500. foreach (var eventList in AccountFileInfo.Instance.playerData.eventList)
  501. {
  502. EventConfig eventConfig = ConfigComponent.Instance.Get<EventConfig>(eventList.eventID);
  503. if (eventConfig.EventTriggerType == 4)
  504. {
  505. return eventList;
  506. }
  507. }
  508. return null;
  509. }
  510. }