NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Bullet/BulletManager.cs

554 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AOT.PostProcess.BlackArea;
using Gameplay.PostProcess.BlackArea;
using Gameplay.Summon;
using Gameplay.Unit;
using PhxhSDK;
using UnityEngine;
namespace Gameplay.Bullet
{
using cfg.BuffCfg;
using cfg.BulletCfg;
using Character;
using Framework;
using Buff;
using Skill;
using Area;
using Common;
using cfg.SkillCfg;
public class BulletManager
{
private static BulletManager _instance;
public static BulletManager instance
{
get
{
if (_instance == null)
{
DebugUtil.LogError("Bullet尚未初始化,请先初始化");
return null;
}
return _instance;
}
}
public static BulletManager CreateInstance()
{
if (_instance != null)
{
DebugUtil.LogError("请勿重复创建BulletManager");
return _instance;
}
_instance = new BulletManager();
return _instance;
}
public GameObject rootObj;
private readonly List<ViewBullet> _bullets;
private readonly List<ViewBullet> _readyBullets;
private readonly Dictionary<string, int> _loadCount;
private BulletManager()
{
_bullets = new List<ViewBullet>();
_readyBullets = new List<ViewBullet>();
_loadCount = new Dictionary<string, int>();
}
public void Init()
{
rootObj = new GameObject("BulletManager");
}
public void RecordLoadCount(string path)
{
if (_loadCount.ContainsKey(path))
{
_loadCount[path]++;
}
else
{
_loadCount.Add(path, 1);
}
}
public void Dispose()
{
// 进行资源清理
foreach (var kv in _loadCount)
{
var path = kv.Key;
var count = kv.Value;
for (var i = 0; i < count; ++i)
{
AssetManager.Instance.Unload(path);
}
}
_bullets.Clear();
_readyBullets.Clear();
_loadCount.Clear();
rootObj.Destroy();
_instance = null;
}
public void LogicUpdate(float dt)
{
for (var i = 0; i < _readyBullets.Count; ++i)
{
var bullet = _readyBullets[i];
bullet.Init();
}
_bullets.AddRange(_readyBullets);
_readyBullets.Clear();
for (var i = 0; i < _bullets.Count; ++i)
{
var bullet = _bullets[i];
// 技能特殊暂停
if (SkillManager.instance.needSkillPaused
&& bullet.sender != SkillManager.instance.inSkillingUnit)
{
continue;
}
bullet.LogicUpdate(dt);
if (bullet.needRemove)
{
_bullets.RemoveAt(i);
i--;
}
}
}
/// <summary>
/// 普通攻击走特殊处理
/// </summary>
/// <param name="sender"></param>
/// <param name="receiver"></param>
public void DoNormalShoot(GameUnit sender,
GameUnit receiver)
{
// _ = AudioManager.Instance.PlayAudio(1001, sender.transData.pos);
// 理论上可以走立马销毁的子弹逻辑,但是这里处理成直接addbuff,减少性能消耗
// 造成伤害
var normalDamageBuff = BuffManager.instance.CreateBuffById(sender, InnerBuffID.NORMAL_DAMAGE);
BuffManager.instance.AddBuff(receiver, normalDamageBuff);
// 打击士气
var moraleDamageBuff = BuffManager.instance.CreateBuffById(sender, InnerBuffID.MORALE_DAMAGE);
BuffManager.instance.AddBuff(receiver, moraleDamageBuff);
}
public ViewBullet EmitBullet(int bulletId,
GameUnit targetUnit,
GameUnit sender)
{
var bulletConfig = GetConfigById(bulletId);
if (bulletConfig == null)
{
DebugUtil.LogError("不存在的子弹配置:{0}", bulletId);
return null;
}
ViewBullet result = null;
switch (bulletConfig.BulletType)
{
case EBulletType.DIRECT_DAMAGE:
// 直接造成伤害
AddBuffs2Unit(targetUnit, sender, bulletConfig);
break;
case EBulletType.POS_LOCK:
// 锁地板
result = _EmitLockPosBullet(targetUnit.transData.cellIndex, sender, bulletConfig);
break;
case EBulletType.UNIT_LOCK:
// 锁单位
result = _EmitLockUnitBullet(targetUnit, sender, bulletConfig);
break;
default:
DebugUtil.LogError("暂未实现的子弹类型:{0}", bulletConfig.BulletType);
break;
}
if (result != null)
{
_readyBullets.Add(result);
}
return result;
}
public ViewBullet EmitBulletFromSummon(int bulletId, int cellIndex, BaseSummon summon)
{
return EmitBullet(bulletId, cellIndex, summon.creator);
}
public ViewBullet EmitBulletFromSummon(int bulletId, GameUnit target, BaseSummon summon)
{
return EmitBullet(bulletId, target, summon.creator);
}
public ViewBullet EmitBullet(int bulletId,
int cellIndex,
GameUnit sender)
{
var bulletConfig = GetConfigById(bulletId);
if (bulletConfig == null)
{
DebugUtil.LogError("不存在的子弹配置:{0}", bulletId);
return null;
}
ViewBullet result = null;
switch (bulletConfig.BulletType)
{
case EBulletType.DIRECT_DAMAGE:
// 直接造成伤害
AddBuffs2CellIndex(cellIndex, sender, bulletConfig);
break;
case EBulletType.POS_LOCK:
// 锁地板
result = _EmitLockPosBullet(cellIndex, sender, bulletConfig);
break;
case EBulletType.UNIT_LOCK:
// 锁单位
result = _EmitLockUnitBullet(cellIndex, sender, bulletConfig);
break;
default:
DebugUtil.LogError("暂未实现的子弹类型:{0}", bulletConfig.BulletType);
break;
}
if (result != null)
{
_readyBullets.Add(result);
}
return result;
}
private ViewBullet _EmitLockUnitBullet(GameUnit targetUnit,
GameUnit sender,
DataBullet bulletConfig)
{
var bullet = new ViewBullet(bulletConfig, sender);
if (!_CheckBulletFilter(sender, targetUnit, bulletConfig))
{
bullet.LockPos(targetUnit.transData.cellIndex);
return bullet;
}
bullet.LockUnit(targetUnit);
return bullet;
}
private ViewBullet _EmitLockUnitBullet(int targetCellIndex,
GameUnit sender,
DataBullet bulletConfig)
{
var bullet = new ViewBullet(bulletConfig, sender);
var units = AreaManager.instance.GetUnitsByCellIndex(targetCellIndex);
var isLocked = false;
for (var i = 0; i < units.Count; ++i)
{
var unit = units[i];
if (!_CheckBulletFilter(sender, unit, bulletConfig))
{
continue;
}
bullet.LockUnit(unit);
isLocked = true;
break;
}
if (!isLocked)
{
// 如果没有目标,锁地板
DebugUtil.LogError("目标错误.保护处理,锁定当前地板");
bullet.LockPos(targetCellIndex);
}
return bullet;
}
public void PreSelectUnits(int cellIndex,
int bulletId, GameUnit sender,
List<GameUnit> selectUnits)
{
var bulletConfig = GetConfigById(bulletId);
if (bulletConfig == null) return;
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
for (var i = 0; i < units.Count; ++i)
{
var unit = units[i];
if (_CheckBulletFilter(sender, unit, bulletConfig))
{
selectUnits.Add(unit);
}
}
}
private ViewBullet _EmitLockPosBullet(int targetCellIndex,
GameUnit creator,
DataBullet bulletConfig)
{
var bullet = new ViewBullet(bulletConfig, creator);
bullet.LockPos(targetCellIndex);
return bullet;
}
public void AddBuffs2Unit(GameUnit unit,
GameUnit creator,
DataBullet bulletConfig)
{
var sender = creator;
if (!_CheckBulletFilter(sender, unit, bulletConfig))
{
return;
}
_CreateNoLineBullet(bulletConfig, creator, unit);
if (bulletConfig.LightDuring > 0)
{
var cellIndex = unit.transData.cellIndex;
BlackAreaManager.instance.LightUpCell(cellIndex, bulletConfig.LightDuring);
}
}
public void AddBuffs2CellIndex(int targetCellIndex,
GameUnit creator,
DataBullet bulletConfig)
{
var areaId = bulletConfig.AreaId;
if (areaId == -1)
{
// 做全局处理
var units = GameUnitManager.instance.infightUnits.unitList;
for (var i = 0; i < units.Count; ++i)
{
var unit = units[i];
AddBuffs2Unit(unit, creator, bulletConfig);
}
}
else
{
var cellIndexs = AreaManager.instance.GetCellIndexs(targetCellIndex, areaId);
for (var i = 0; i < cellIndexs.Count; ++i)
{
var cellIndex = cellIndexs[i];
// 根据filterType 和 cellIndex进行处理
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
for (var j = 0; j < units.Count; ++j)
{
var unit = units[j];
AddBuffs2Unit(unit, creator, bulletConfig);
}
}
}
}
private bool _CheckBulletFilter(GameUnit sender,
GameUnit beHitter,
DataBullet bulletConfig)
{
var onlyCharacterCheck = _CheckOnlyCharacter(beHitter, bulletConfig);
if (!onlyCharacterCheck)
{
return false;
}
var troopCheck = _CheckTroopSide(sender, beHitter, bulletConfig.FilterType);
if (!troopCheck)
{
return false;
}
var jobCheck = _CheckJobSide(beHitter, bulletConfig);
if (!jobCheck)
{
return false;
}
var pretentCheck = _CheckPretentAvaliable(beHitter, bulletConfig);
if (!pretentCheck)
{
return false;
}
var moraleCheck = _CheckMoraleState(beHitter, bulletConfig);
if (!moraleCheck)
{
return false;
}
var buffGroupCheck = _CheckHasBuffGroup(beHitter, bulletConfig);
if (!buffGroupCheck)
{
return false;
}
return true;
}
private bool _CheckPretentAvaliable(GameUnit beHitter, DataBullet bulletConfig)
{
if (bulletConfig.CanUseOnPretent)
{
return true;
}
if (beHitter.statusData.isPretend)
{
return false;
}
return true;
}
private bool _CheckMoraleState(GameUnit beHitter, DataBullet bulletConfig)
{
if (bulletConfig.MoraleFilter.Count == 0)
{
return true;
}
var behitCharacter = beHitter as Character;
if (behitCharacter == null)
{
return false;
}
var moraleState = behitCharacter.runtimeData.moraleState;
if (bulletConfig.MoraleFilter.Contains(moraleState))
{
return true;
}
return false;
}
private bool _CheckHasBuffGroup(GameUnit beHitter, DataBullet bulletConfig)
{
if (bulletConfig.ExistBuffGroupIdFilter.Count == 0)
{
return true;
}
var buffManager = beHitter.buffManager;
if (buffManager == null)
{
return false;
}
for (var i = 0; i < bulletConfig.ExistBuffGroupIdFilter.Count; ++i)
{
var buffGroupId = bulletConfig.ExistBuffGroupIdFilter[i];
if (buffManager.HasBuffGroup(buffGroupId))
{
return true;
}
}
return false;
}
private bool _CheckOnlyCharacter(GameUnit beHitter, DataBullet bulletConfig)
{
var require = bulletConfig.OnlyCharacter;
if (!require)
{
return true;
}
var behitCharacter = beHitter as Character;
if (behitCharacter == null)
{
return false;
}
return true;
}
private bool _CheckJobSide(GameUnit beHitter,
DataBullet bulletConfig)
{
if (bulletConfig.JobFilters == null || bulletConfig.JobFilters.Count == 0)
{
return true;
}
// 只针对character
var behitCharacter = beHitter as Character;
if (behitCharacter == null)
{
return false;
}
var behitJob = behitCharacter.runtimeData.configData.job;
if (bulletConfig.JobFilters.Contains(behitJob))
{
return true;
}
return false;
}
private bool _CheckTroopSide(GameUnit sender,
GameUnit beHitter,
ETargetType filterType)
{
switch (filterType)
{
case ETargetType.SelfSide:
if (sender.commonData.troopId == beHitter.commonData.troopId)
{
return true;
}
return false;
case ETargetType.EnemySide:
if (sender.commonData.troopId != beHitter.commonData.troopId)
{
return true;
}
return false;
case ETargetType.Self:
if (sender == beHitter)
{
return true;
}
return false;
default:
DebugUtil.LogError("_CheckBulletFilter 暂未实现的filterType:{0}", filterType);
return false;
}
}
private void _CreateNoLineBullet(DataBullet bulletConfig,
GameUnit creator,
GameUnit beHitter)
{
var buffIdList = bulletConfig.BuffList;
for (var i = 0; i < buffIdList.Count; ++i)
{
var buffId = buffIdList[i];
var addBuff = BuffManager.instance.CreateBuffById(creator, buffId);
if (addBuff == null)
{
continue;
}
BuffManager.instance.AddBuff(beHitter, addBuff);
}
}
public DataBullet GetConfigById(int id)
{
return TableManager.Instance.Tables.BulletConfig.Get(id);
}
}
}