using System; using System.Collections.Generic; using System.Linq; using Data; using UnityEngine; using Utils; using System.Threading.Tasks; // 导入异步命名空间 namespace Managers { /// /// 阵营管理器,负责管理游戏中的所有阵营定义及其相互关系。 /// 继承自 ,确保全局只有一个实例。 /// public class AffiliationManager : Singleton, ILaunchManager { /// /// 存储所有已加载的阵营定义,键为阵营的唯一名称,值为对应的 对象。 /// private readonly Dictionary _affiliations = new(); public bool Completed { get; set; } // Renamed from Loaded to Completed public string StepDescription => "正在区分派系"; private string _playerAffiliation; public string PlayerAffiliation { get { if (string.IsNullOrEmpty(_playerAffiliation)) { _playerAffiliation = Configs.ConfigManager.Instance.GetValue("playerAffiliation"); } return _playerAffiliation; } } /// /// 初始化阵营管理器,从 加载所有 。 /// 在首次需要阵营数据时调用。 /// public async Task Init() // Changed to async Task { // 如果管理器已经初始化完成,则直接返回,避免重复加载。 if (Completed) return; var affiliationList = DefineManager.Instance.QueryDefinesByType(); if (affiliationList == null || affiliationList.Length == 0) { // 记录警告,说明未能加载任何阵营定义。 Debug.LogWarning("未找到任何 AffiliationDef 或阵营列表为空。"); Completed = true; // 即使没有加载到,也标记为完成,避免后续重复尝试 await Task.CompletedTask; // 返回一个已完成的Task return; } foreach (var affiliation in affiliationList) // 尝试将阵营定义添加到字典中。如果名称已存在,则记录错误。 if (!_affiliations.TryAdd(affiliation.defName, affiliation)) Debug.LogError($"添加阵营 '{affiliation.defName}' 失败。已存在同名阵营。"); // 验证并修复加载后的阵营关系,以确保数据一致性。 ValidateAndFixRelationships(); Completed = true; // 标记为完成 await Task.CompletedTask; // 返回一个已完成的Task } /// /// 清理所有已加载的阵营定义。 /// 在游戏会话结束或需要重新加载所有定义时调用。 /// public void Clear() { _affiliations.Clear(); Completed = false; // 清理后,标记为未完成,下次需要时可重新Init _playerAffiliation = null; } /// /// 根据阵营定义名称获取其默认名称。 /// /// 阵营的定义名称。 /// 阵营的默认名称或传入的defName(若未找到并给出警告)。 public string GetAffiliationName(string defName) { if (_affiliations.TryGetValue(defName, out var affiliationDef)) { return affiliationDef.defName; } Debug.LogWarning($"获取阵营名称失败: 阵营 '{defName}' 不存在。"); // 根据实际需求,这里可以抛出异常、返回空字符串或返回 defName 本身。 // 暂时返回 defName,但警告。 return defName; } /// /// 获取两个阵营间的关系。 /// /// 第一个阵营的 对象。 /// 第二个阵营的 对象。 /// 两个阵营之间的 public Relation GetRelation(AffiliationDef affiliation1, AffiliationDef affiliation2) { // 如果任一阵营定义为空,则返回中立关系。 if (affiliation1 == null || affiliation2 == null) return Relation.Neutral; return GetRelation(affiliation1.defName, affiliation2.defName); } public Relation GetRelation(Entity.Entity entity1, Entity.Entity entity2) { // 如果任一实体为空,则返回中立关系。 if (entity1 == null || entity2 == null) return Relation.Neutral; return GetRelation(entity1.affiliation, entity2.affiliation); } /// /// 获取两个阵营名称之间的关系。 /// /// 第一个阵营的名称。 /// 第二个阵营的名称。 /// 两个阵营之间的 public Relation GetRelation(string factionName1, string factionName2) { // 如果查询的是同一个阵营,则默认为友好关系。 if (factionName1 == factionName2) return Relation.Friendly; // 获取第一个阵营的定义。如果不存在,则返回中立关系。 // (无法通过一个不存在的阵营来判断与其相关的任何关系)。 if (!_affiliations.TryGetValue(factionName1, out var faction1)) { return Relation.Neutral; } // 获取第二个阵营的定义。如果不存在,则使用第一个阵营的默认关系。 // (如果只有第二个阵营不存在,第一个阵营可以决定其对未知阵营的态度)。 if (!_affiliations.TryGetValue(factionName2, out _)) { return faction1.defaultRelation; } // 检查 faction1 是否将 faction2 明确列为敌对。 if (faction1.hostileFactions != null && faction1.hostileFactions.Contains(factionName2)) return Relation.Hostile; // 检查 faction1 是否将 faction2 明确列为友好。 if (faction1.friendlyFactions != null && faction1.friendlyFactions.Contains(factionName2)) return Relation.Friendly; // 检查 faction1 是否将 faction2 明确列为中立。 if (faction1.neutralFactions != null && faction1.neutralFactions.Contains(factionName2)) return Relation.Neutral; // 如果 faction1 没有明确设置与 faction2 的关系,则使用 faction1 的默认关系。 return faction1.defaultRelation; } /// /// 设置两个阵营之间的关系。 /// /// 第一个阵营的名称。 /// 第二个阵营的名称。 /// 要设置的 。 /// 当尝试设置同一个阵营的关系或其中一个阵营不存在时抛出。 /// 当传入的关系类型无效时抛出。 public void SetRelation(string factionName1, string factionName2, Relation relation) { // 不能设置自己与自己的关系。 if (factionName1 == factionName2) throw new ArgumentException("不能设置同一个阵营之间的关系"); // 确保两个阵营都存在。 if (!_affiliations.TryGetValue(factionName1, out var faction1) || !_affiliations.TryGetValue(factionName2, out _)) throw new ArgumentException("一个或两个阵营不存在"); // 确保关系列表已初始化,避免空引用异常。 faction1.hostileFactions ??= new List(); faction1.friendlyFactions ??= new List(); faction1.neutralFactions ??= new List(); // 先移除 factionName2 在 faction1 所有关系列表中的现有关系。 faction1.hostileFactions.Remove(factionName2); faction1.friendlyFactions.Remove(factionName2); faction1.neutralFactions.Remove(factionName2); // 根据传入的关系类型,将 factionName2 添加到对应列表中。 switch (relation) { case Relation.Hostile: faction1.hostileFactions.Add(factionName2); break; case Relation.Friendly: faction1.friendlyFactions.Add(factionName2); break; case Relation.Neutral: faction1.neutralFactions.Add(factionName2); break; default: // 如果传入的关系类型无效,抛出异常。 throw new ArgumentOutOfRangeException(nameof(relation), relation, null); } } /// /// 检查并修复所有阵营之间的关系,以确保没有冲突。 /// 修复遵循优先级规则:友好关系优先于敌对关系,敌对关系优先于中立关系。 /// private void ValidateAndFixRelationships() { foreach (var faction in _affiliations.Values) { // 确保所有关系列表已初始化,避免空引用异常。 faction.hostileFactions ??= new List(); faction.friendlyFactions ??= new List(); faction.neutralFactions ??= new List(); // 遍历并检查所有敌对阵营。由于可能修改列表,使用 ToList() 创建副本进行遍历。 foreach (var hostileFaction in faction.hostileFactions.ToList()) { // 如果敌对阵营同时存在于友好列表中,则移除其敌对关系(友好关系具有更高优先级)。 if (faction.friendlyFactions.Contains(hostileFaction)) { faction.hostileFactions.Remove(hostileFaction); continue; // 继续检查下一个敌对阵营。 } // 如果敌对阵营同时存在于中立列表中,则移除其中立关系(敌对关系具有更高优先级)。 if (faction.neutralFactions.Contains(hostileFaction)) faction.neutralFactions.Remove(hostileFaction); } // 遍历并检查所有中立阵营。由于可能修改列表,使用 ToList() 创建副本进行遍历。 foreach (var neutralFaction in faction.neutralFactions.ToList()) // 如果中立阵营同时存在于友好列表中,则移除其中立关系(友好关系具有更高优先级)。 if (faction.friendlyFactions.Contains(neutralFaction)) faction.neutralFactions.Remove(neutralFaction); } } } }