|
@@ -0,0 +1,212 @@
|
|
|
|
+using System;
|
|
|
|
+using System.Collections;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Linq;
|
|
|
|
+using Excel2Json;
|
|
|
|
+using Fort23.UTool;
|
|
|
|
+using UnityEngine;
|
|
|
|
+using Utility;
|
|
|
|
+
|
|
|
|
+public class EventSystemManager : Singleton<EventSystemManager>
|
|
|
|
+{
|
|
|
|
+ List<EventConfig> eventConfigs = new List<EventConfig>();
|
|
|
|
+ private List<DivineSenseIntervalConfig> divineSenseIntervalConfigs = new List<DivineSenseIntervalConfig>();
|
|
|
|
+
|
|
|
|
+ public void CustomInit()
|
|
|
|
+ {
|
|
|
|
+ eventConfigs = ConfigComponent.Instance.GetAll<EventConfig>().ToList();
|
|
|
|
+ divineSenseIntervalConfigs = ConfigComponent.Instance.GetAll<DivineSenseIntervalConfig>().ToList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public void DetectEvents(int bigMapId)
|
|
|
|
+ {
|
|
|
|
+ BigMap bigMap = ConfigComponent.Instance.Get<BigMap>(bigMapId);
|
|
|
|
+ DivineSenseConfig divineSenseConfig = ConfigComponent.Instance.Get<DivineSenseConfig>(1);
|
|
|
|
+
|
|
|
|
+ // 选择神识区间
|
|
|
|
+ DivineSenseIntervalConfig interval = SelectInterval(200);
|
|
|
|
+
|
|
|
|
+ // 获取通用事件
|
|
|
|
+ List<EventConfig> globalEvents = eventConfigs
|
|
|
|
+ .Where(e => e.EventTriggerType == 3 && CanTriggerEvent(e.ID) &&
|
|
|
|
+ interval.EventQualities.Contains(e.EventQuality))
|
|
|
|
+ .ToList();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //获取特定事件
|
|
|
|
+ var eventIDs = bigMap.DivineSenseEvent.ToList();
|
|
|
|
+ List<EventConfig> candidateEvents = eventConfigs
|
|
|
|
+ .Where(e => eventIDs.Contains(e.ID) && CanTriggerEvent(e.ID))
|
|
|
|
+ .ToList();
|
|
|
|
+ candidateEvents.AddRange(globalEvents);
|
|
|
|
+
|
|
|
|
+ if (candidateEvents.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ LogTool.Warning("没有可以刷新的任务");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算高品质事件加成
|
|
|
|
+ float qualityBonusMultiplier = divineSenseConfig.QualityBonusChance *
|
|
|
|
+ Mathf.Floor((200 - divineSenseConfig.MinDivineSenseValue) /
|
|
|
|
+ divineSenseConfig.DivineSenseCount);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 获得全部权重
|
|
|
|
+ var eventWeights = new List<(EventConfig Event, int Weight)>();
|
|
|
|
+ float totalProbability = candidateEvents.Sum(evt =>
|
|
|
|
+ {
|
|
|
|
+ float prob = evt.BaseProbability;
|
|
|
|
+ if (evt.EventQuality >= 2)
|
|
|
|
+ prob *= (1f + qualityBonusMultiplier);
|
|
|
|
+ return prob;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ foreach (var evt in candidateEvents)
|
|
|
|
+ {
|
|
|
|
+ float probability = evt.BaseProbability;
|
|
|
|
+ if (evt.EventQuality >= 2)
|
|
|
|
+ probability *= (1f + qualityBonusMultiplier);
|
|
|
|
+ int weight = Mathf.Max(1, Mathf.RoundToInt(probability / totalProbability * 100));
|
|
|
|
+ eventWeights.Add((evt, weight));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 调整权重确保总和=100
|
|
|
|
+ int totalWeight = 100;
|
|
|
|
+ int currentSum = eventWeights.Sum(ew => ew.Weight);
|
|
|
|
+ if (currentSum != totalWeight)
|
|
|
|
+ {
|
|
|
|
+ float scale = (float)totalWeight / currentSum;
|
|
|
|
+ eventWeights = eventWeights.Select(ew => (ew.Event, Mathf.Max(1, Mathf.RoundToInt(ew.Weight * scale))))
|
|
|
|
+ .ToList();
|
|
|
|
+ // 微调总和
|
|
|
|
+ currentSum = eventWeights.Sum(ew => ew.Weight);
|
|
|
|
+ if (currentSum != totalWeight)
|
|
|
|
+ {
|
|
|
|
+ int diff = totalWeight - currentSum;
|
|
|
|
+ var maxWeightEvent = eventWeights.OrderByDescending(ew => ew.Weight).First();
|
|
|
|
+ eventWeights[eventWeights.IndexOf(maxWeightEvent)] =
|
|
|
|
+ (maxWeightEvent.Event, maxWeightEvent.Weight + diff);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ foreach (var (evt, weight) in eventWeights)
|
|
|
|
+ {
|
|
|
|
+ LogTool.Log($"EventId {evt.ID}: 权重={weight} ({weight / (float)totalWeight:P2})");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 随机抽取事件
|
|
|
|
+ var triggeredEvents = new List<EventConfig>();
|
|
|
|
+ for (int i = 0; i < divineSenseConfig.DetectEventCount && eventWeights.Count > 0; i++)
|
|
|
|
+ {
|
|
|
|
+ int randomValue = UnityEngine.Random.Range(0, 101);
|
|
|
|
+ int cumulative = 0;
|
|
|
|
+ foreach (var (evt, weight) in eventWeights.ToList())
|
|
|
|
+ {
|
|
|
|
+ cumulative += weight;
|
|
|
|
+ if (randomValue < cumulative)
|
|
|
|
+ {
|
|
|
|
+ triggeredEvents.Add(evt);
|
|
|
|
+ eventWeights.RemoveAll(ew => ew.Event.ID == evt.ID);
|
|
|
|
+ LogTool.Log($"S旋转事件 {evt.ID}, 权重={weight}, 随机到的权重={randomValue}");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 触发事件
|
|
|
|
+ foreach (var evt in triggeredEvents)
|
|
|
|
+ {
|
|
|
|
+ TriggerEvent(evt);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (triggeredEvents.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ Debug.Log("没有可以触发的事件");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 根据神识值选择通用神识区间
|
|
|
|
+ /// </summary>
|
|
|
|
+ private DivineSenseIntervalConfig SelectInterval(float divineSenseValue)
|
|
|
|
+ {
|
|
|
|
+ var intervals = divineSenseIntervalConfigs
|
|
|
|
+ .Where(i => divineSenseValue >= i.MinValue && divineSenseValue < i.MaxValue)
|
|
|
|
+ .ToList();
|
|
|
|
+ return intervals.FirstOrDefault();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 触发单个事件,处理对话、奖励和完成逻辑。
|
|
|
|
+ /// </summary>
|
|
|
|
+ public void TriggerEvent(EventConfig evt)
|
|
|
|
+ {
|
|
|
|
+ Debug.Log($"触发事件: {evt.Description} (ID: {evt.ID}, 品质: {evt.EventQuality})");
|
|
|
|
+ if (evt.DialogueID > 0)
|
|
|
|
+ {
|
|
|
|
+ DialogueManager.Instance.StartDialogue(evt.DialogueID, evt.ID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (evt.RewardID.Length > 0)
|
|
|
|
+ {
|
|
|
|
+ // TODO: 实现奖励逻辑
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CompleteEvent(evt.ID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 检查事件是否满足触发条件。
|
|
|
|
+ /// </summary>
|
|
|
|
+ private bool CanTriggerEvent(int eventID)
|
|
|
|
+ {
|
|
|
|
+ var evt = eventConfigs.Find(e => e.ID == eventID);
|
|
|
|
+ if (evt.ID == 0)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for (var i = 0; i < evt.EventConditionId.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ if (!CheckCondition(evt.EventConditionId[i], evt.EventVlaue[i]))
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 检查单个触发条件。
|
|
|
|
+ /// </summary>
|
|
|
|
+ private bool CheckCondition(int conditionid, int EventVlaue)
|
|
|
|
+ {
|
|
|
|
+ //>=
|
|
|
|
+ if (EventVlaue == 1)
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+ //=
|
|
|
|
+ else if (EventVlaue == 2)
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+ // <=
|
|
|
|
+ else if (EventVlaue == 3)
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 完成任务
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="eventID">事件ID</param>
|
|
|
|
+ public void CompleteEvent(int eventID)
|
|
|
|
+ {
|
|
|
|
+ LogTool.Log($"完成任务{eventID}");
|
|
|
|
+ }
|
|
|
|
+}
|