EventManager.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Excel2Json;
  6. using Fort23.UTool;
  7. using UnityEngine;
  8. using Utility;
  9. public class EventSystemManager : Singleton<EventSystemManager>
  10. {
  11. List<EventConfig> eventConfigs = new List<EventConfig>();
  12. private List<DivineSenseIntervalConfig> divineSenseIntervalConfigs = new List<DivineSenseIntervalConfig>();
  13. public void CustomInit()
  14. {
  15. eventConfigs = ConfigComponent.Instance.GetAll<EventConfig>().ToList();
  16. divineSenseIntervalConfigs = ConfigComponent.Instance.GetAll<DivineSenseIntervalConfig>().ToList();
  17. }
  18. public void DetectEvents(int bigMapId)
  19. {
  20. BigMap bigMap = ConfigComponent.Instance.Get<BigMap>(bigMapId);
  21. DivineSenseConfig divineSenseConfig = ConfigComponent.Instance.Get<DivineSenseConfig>(1);
  22. // 选择神识区间
  23. DivineSenseIntervalConfig interval = SelectInterval(200);
  24. // 获取通用事件
  25. List<EventConfig> globalEvents = eventConfigs
  26. .Where(e => e.EventTriggerType == 3 && CanTriggerEvent(e.ID) &&
  27. interval.EventQualities.Contains(e.EventQuality))
  28. .ToList();
  29. //获取特定事件
  30. var eventIDs = bigMap.DivineSenseEvent.ToList();
  31. List<EventConfig> candidateEvents = eventConfigs
  32. .Where(e => eventIDs.Contains(e.ID) && CanTriggerEvent(e.ID))
  33. .ToList();
  34. candidateEvents.AddRange(globalEvents);
  35. if (candidateEvents.Count == 0)
  36. {
  37. LogTool.Warning("没有可以刷新的任务");
  38. return;
  39. }
  40. // 计算高品质事件加成
  41. float qualityBonusMultiplier = divineSenseConfig.QualityBonusChance *
  42. Mathf.Floor((200 - divineSenseConfig.MinDivineSenseValue) /
  43. divineSenseConfig.DivineSenseCount);
  44. // 获得全部权重
  45. var eventWeights = new List<(EventConfig Event, int Weight)>();
  46. float totalProbability = candidateEvents.Sum(evt =>
  47. {
  48. float prob = evt.BaseProbability;
  49. if (evt.EventQuality >= 2)
  50. prob *= (1f + qualityBonusMultiplier);
  51. return prob;
  52. });
  53. foreach (var evt in candidateEvents)
  54. {
  55. float probability = evt.BaseProbability;
  56. if (evt.EventQuality >= 2)
  57. probability *= (1f + qualityBonusMultiplier);
  58. int weight = Mathf.Max(1, Mathf.RoundToInt(probability / totalProbability * 100));
  59. eventWeights.Add((evt, weight));
  60. }
  61. // 调整权重确保总和=100
  62. int totalWeight = 100;
  63. int currentSum = eventWeights.Sum(ew => ew.Weight);
  64. if (currentSum != totalWeight)
  65. {
  66. float scale = (float)totalWeight / currentSum;
  67. eventWeights = eventWeights.Select(ew => (ew.Event, Mathf.Max(1, Mathf.RoundToInt(ew.Weight * scale))))
  68. .ToList();
  69. // 微调总和
  70. currentSum = eventWeights.Sum(ew => ew.Weight);
  71. if (currentSum != totalWeight)
  72. {
  73. int diff = totalWeight - currentSum;
  74. var maxWeightEvent = eventWeights.OrderByDescending(ew => ew.Weight).First();
  75. eventWeights[eventWeights.IndexOf(maxWeightEvent)] =
  76. (maxWeightEvent.Event, maxWeightEvent.Weight + diff);
  77. }
  78. }
  79. foreach (var (evt, weight) in eventWeights)
  80. {
  81. LogTool.Log($"EventId {evt.ID}: 权重={weight} ({weight / (float)totalWeight:P2})");
  82. }
  83. // 随机抽取事件
  84. var triggeredEvents = new List<EventConfig>();
  85. for (int i = 0; i < divineSenseConfig.DetectEventCount && eventWeights.Count > 0; i++)
  86. {
  87. int randomValue = UnityEngine.Random.Range(0, 101);
  88. int cumulative = 0;
  89. foreach (var (evt, weight) in eventWeights.ToList())
  90. {
  91. cumulative += weight;
  92. if (randomValue < cumulative)
  93. {
  94. triggeredEvents.Add(evt);
  95. eventWeights.RemoveAll(ew => ew.Event.ID == evt.ID);
  96. LogTool.Log($"S旋转事件 {evt.ID}, 权重={weight}, 随机到的权重={randomValue}");
  97. break;
  98. }
  99. }
  100. }
  101. // 触发事件
  102. foreach (var evt in triggeredEvents)
  103. {
  104. TriggerEvent(evt);
  105. }
  106. if (triggeredEvents.Count == 0)
  107. {
  108. Debug.Log("没有可以触发的事件");
  109. }
  110. }
  111. /// <summary>
  112. /// 根据神识值选择通用神识区间
  113. /// </summary>
  114. private DivineSenseIntervalConfig SelectInterval(float divineSenseValue)
  115. {
  116. var intervals = divineSenseIntervalConfigs
  117. .Where(i => divineSenseValue >= i.MinValue && divineSenseValue < i.MaxValue)
  118. .ToList();
  119. return intervals.FirstOrDefault();
  120. }
  121. /// <summary>
  122. /// 触发单个事件,处理对话、奖励和完成逻辑。
  123. /// </summary>
  124. public void TriggerEvent(EventConfig evt)
  125. {
  126. Debug.Log($"触发事件: {evt.Description} (ID: {evt.ID}, 品质: {evt.EventQuality})");
  127. if (evt.DialogueID > 0)
  128. {
  129. DialogueManager.Instance.StartDialogue(evt.DialogueID, evt.ID);
  130. }
  131. if (evt.RewardID.Length > 0)
  132. {
  133. // TODO: 实现奖励逻辑
  134. }
  135. CompleteEvent(evt.ID);
  136. }
  137. /// <summary>
  138. /// 检查事件是否满足触发条件。
  139. /// </summary>
  140. private bool CanTriggerEvent(int eventID)
  141. {
  142. var evt = eventConfigs.Find(e => e.ID == eventID);
  143. if (evt.ID == 0)
  144. return false;
  145. for (var i = 0; i < evt.EventConditionId.Length; i++)
  146. {
  147. if (!CheckCondition(evt.EventConditionId[i], evt.EventVlaue[i]))
  148. return false;
  149. }
  150. return true;
  151. }
  152. /// <summary>
  153. /// 检查单个触发条件。
  154. /// </summary>
  155. private bool CheckCondition(int conditionid, int EventVlaue)
  156. {
  157. //>=
  158. if (EventVlaue == 1)
  159. {
  160. }
  161. //=
  162. else if (EventVlaue == 2)
  163. {
  164. }
  165. // <=
  166. else if (EventVlaue == 3)
  167. {
  168. }
  169. return false;
  170. }
  171. /// <summary>
  172. /// 完成任务
  173. /// </summary>
  174. /// <param name="eventID">事件ID</param>
  175. public void CompleteEvent(int eventID)
  176. {
  177. LogTool.Log($"完成任务{eventID}");
  178. }
  179. }