using Data; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Managers { /// /// 阵营管理器,负责管理游戏中的所有阵营定义及其相互关系。 /// 继承自 ,确保全局只有一个实例。 /// public class AffiliationManager : Utils.Singleton, ILaunchManager { /// /// 存储所有已加载的阵营定义,键为阵营的唯一名称,值为对应的 对象。 /// private readonly Dictionary _affiliations = new(); public string StepDescription => "正在区分派系"; /// /// 初始化阵营管理器,从 加载所有 。 /// 在首次需要阵营数据时调用。 /// public void Init() { // 如果管理器已经初始化,则直接返回,避免重复加载。 if (_affiliations.Count > 0) { return; } var affiliationList = Managers.DefineManager.Instance.QueryDefinesByType(); if (affiliationList == null || affiliationList.Length == 0) { // 记录警告,说明未能加载任何阵营定义。 Debug.LogWarning("未找到任何 AffiliationDef 或阵营列表为空。"); return; } foreach (var affiliation in affiliationList) { // 尝试将阵营定义添加到字典中。如果名称已存在,则记录错误。 if (!_affiliations.TryAdd(affiliation.defName, affiliation)) { Debug.LogError($"添加阵营 '{affiliation.defName}' 失败。已存在同名阵营。"); } } // 验证并修复加载后的阵营关系,以确保数据一致性。 ValidateAndFixRelationships(); } /// /// 清除所有已加载的阵营定义。 /// 在游戏会话结束或需要重新加载所有定义时调用。 /// public void Clear() { _affiliations.Clear(); } /// /// 根据阵营定义名称获取其默认名称。 /// /// 阵营的定义名称。 /// 阵营的默认名称。 public string GetAffiliationName(string defName) { return _affiliations[defName].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) { 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) || !_affiliations.TryGetValue(factionName2, out _)) { // 如果第一个阵营存在,但第二个不存在,返回第一个阵营的默认关系; // 否则(两个都不存在或第一个不存在),返回中立。 if (faction1 != null) return faction1.defaultRelation; // 注意:由于上面已经有一个 TryGetValue 判断, // 此时 faction1 为 null 表示 factionName1 也不存在,所以应返回中立。 return Relation.Neutral; } // 检查 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); } } } } } }