using System.Collections.Generic; using Gameplay.Building; using Gameplay.Pool; using Gameplay.Summon; using Gameplay.Unit; using Gameplay.Unit.Data; using Gameplay.Vehicle.Impl; namespace Gameplay.Buff { using cfg.BuffCfg; using Framework; using Bullet; using Character; using Skill; public class BuffManager { private const int EXPECTED_MAX_UNITS = 50; private const int EXPECTED_MAX_SIDES = 4; private static BuffManager _instance; public static BuffManager instance { get { if (_instance == null) { DebugUtil.LogError("Buff尚未初始化,请先初始化"); return null; } return _instance; } } public static BuffManager CreateInstance() { if (_instance != null) { DebugUtil.LogError("请勿重复创建BuffManager"); return _instance; } _instance = new BuffManager(); return _instance; } private Dictionary _unitDict; private List _unitList; private Dictionary _sideBuffManagerDict; // 缓存最后访问的管理器以优化查找 private UnitBuffManager _lastAccessedManager; private GameUnit _lastAccessedUnit; private BuffManager() { _unitDict = new Dictionary(EXPECTED_MAX_UNITS); _unitList = new List(EXPECTED_MAX_UNITS); _sideBuffManagerDict = new Dictionary(EXPECTED_MAX_SIDES); } public void Init() { DebugUtil.Log("[Init]------BuffManager"); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove); } public void Dispose() { DebugUtil.Log("[Dispose]------BuffManager"); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove); // 清理缓存 _lastAccessedManager = null; _lastAccessedUnit = null; _unitDict.Clear(); _unitList.Clear(); _sideBuffManagerDict.Clear(); _unitDict = null; _unitList = null; _sideBuffManagerDict = null; _instance = null; } private void _OnUnitReady(GameUnit unit) { var troopId = unit.commonData.troopId; var sideBuffManager = GetSideBuffManager(troopId); sideBuffManager.AddToUnit(unit); } private void _OnUnitRemove(GameUnit unit) { var troopId = unit.commonData.troopId; var sideBuffManager = GetSideBuffManager(troopId); sideBuffManager.RemoveFromUnit(unit); } public static DataBuff GetBuffConfigById(int id) { return TableManager.Instance.Tables.BuffConfig.Get(id); } public BaseBuff CreateBuffById(GameUnit creator, int id) { var buffConfig = GetBuffConfigById(id); if (buffConfig == null) { return null; } return CreateBuffByConfig(creator, buffConfig); } public BaseBuff CreateBuffByConfig(GameUnit creator, DataBuff buffConfig) { var buff = BuffFactory.CreateBuff(buffConfig.BuffType); if (buff == null) { return null; } buff.Ctor(creator, buffConfig); return buff; } public static void ReturnBuff(T buff) where T : BaseBuff { ObjPoolManager.instance.Return(buff); } public void AddBuff(GameUnit unit, BaseBuff buff) { if (buff == null || unit == null) { return; } UnitBuffManager unitManager; // 使用缓存避免字典查找 if (_lastAccessedUnit == unit) { unitManager = _lastAccessedManager; } else if (_unitDict.TryGetValue(unit, out unitManager)) { // 更新缓存 _lastAccessedUnit = unit; _lastAccessedManager = unitManager; } else { // 此unit已经从战场中移除 return; } switch (unit.gameunitType) { case EGameUnitType.Character: case EGameUnitType.Vehicle: case EGameUnitType.Summon: case EGameUnitType.Building: unitManager.AddBuff(buff); break; default: DebugUtil.LogError("暂未实现的gameunit类型:{0}", unit.gameunitType); break; } } private void InitUnitCommon(GameUnit unit) { if (_unitDict.ContainsKey(unit)) { DebugUtil.LogError($"FATAL ERROR: 不应该出现两个相同的{unit.GetType().Name}"); return; } var unitManager = new UnitBuffManager(unit); _unitDict.Add(unit, unitManager); _unitList.Add(unitManager); // 更新缓存 _lastAccessedUnit = unit; _lastAccessedManager = unitManager; } public void InitCharacter(Character c) { InitUnitCommon(c); if (!_unitDict.TryGetValue(c, out var unitManager)) { return; } // 默认全局buff var autoRecoverMoraleBuff = CreateBuffById(c, InnerBuffID.AUTO_RECOVER_MORALE); unitManager.AddBuff(autoRecoverMoraleBuff); // 添加默认被动buff var passiveBuffIds = c.runtimeData.configData.passiveBuffIds; unitManager.AddBuffByIds(passiveBuffIds); // 双向绑定 c.buffManager = unitManager; } public void InitBuild(UnitBuild build) { InitUnitCommon(build); if (!_unitDict.TryGetValue(build, out var unitManager)) { return; } // 双向绑定 build.buffManager = unitManager; } public void InitVehicle(NormalVehicle vehicle) { InitUnitCommon(vehicle); if (!_unitDict.TryGetValue(vehicle, out var unitManager)) { return; } // 双向绑定 vehicle.buffManager = unitManager; } public void InitSummon(BaseSummon summon) { InitUnitCommon(summon); if (!_unitDict.TryGetValue(summon, out var unitManager)) { return; } // 双向绑定 summon.buffManager = unitManager; } public void RemoveCharacter(Character c) { if (!_unitDict.ContainsKey(c)) { DebugUtil.LogError("FATAL ERROR: 不应该出现不存在的character"); return; } var unitManager = _unitDict[c]; _unitDict.Remove(c); _unitList.Remove(unitManager); } public SideBuffManager GetSideBuffManager(int troopId) { if (_sideBuffManagerDict.TryGetValue(troopId, out var sideBuffManager)) { return sideBuffManager; } sideBuffManager = new SideBuffManager(troopId); _sideBuffManagerDict.Add(troopId, sideBuffManager); return sideBuffManager; } public void LogicUpdate(float dt) { // 快速返回 if (_unitList == null || _unitList.Count == 0) { return; } // 缓存列表大小和暂停状态 int count = _unitList.Count; bool isPaused = SkillManager.instance.needSkillPaused; for (var i = 0; i < count; ++i) { var unit = _unitList[i]; if (isPaused) { unit.UpdateOnlyRemoveAdd(); } else { unit.LogicUpdate(dt); } } } } }