NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Buff/BuffManager.cs

301 lines
8.7 KiB
C#
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

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<GameUnit, UnitBuffManager> _unitDict;
private List<UnitBuffManager> _unitList;
private Dictionary<int, SideBuffManager> _sideBuffManagerDict;
// 缓存最后访问的管理器以优化查找
private UnitBuffManager _lastAccessedManager;
private GameUnit _lastAccessedUnit;
private BuffManager()
{
_unitDict = new Dictionary<GameUnit, UnitBuffManager>(EXPECTED_MAX_UNITS);
_unitList = new List<UnitBuffManager>(EXPECTED_MAX_UNITS);
_sideBuffManagerDict = new Dictionary<int, SideBuffManager>(EXPECTED_MAX_SIDES);
}
public void Init()
{
DebugUtil.Log("[Init]------BuffManager");
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove);
}
public void Dispose()
{
DebugUtil.Log("[Dispose]------BuffManager");
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Unregister<GameUnit>(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>(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);
}
}
}
}
}