301 lines
8.7 KiB
C#
301 lines
8.7 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|