395 lines
14 KiB
C#
395 lines
14 KiB
C#
using System.Collections.Generic;
|
|
using AOT.PostProcess.BlackArea;
|
|
using Gameplay.Vehicle.Impl;
|
|
using Gameplay.Character;
|
|
using Gameplay.Unit.Data;
|
|
using Gameplay.Level;
|
|
using Gameplay.Skill;
|
|
using Gameplay.Area;
|
|
using Gameplay.Unit;
|
|
using cfg.SkillCfg;
|
|
using UnityEngine;
|
|
using PhxhSDK;
|
|
|
|
namespace Gameplay.AI
|
|
{
|
|
public class AISkillCheck : Singlenton<AISkillCheck>
|
|
{
|
|
/// <summary>
|
|
/// 预选地格
|
|
/// </summary>
|
|
private List<int> _preSelectCellIndexList = new List<int>();
|
|
|
|
/// <summary>
|
|
/// 检查过的地格
|
|
/// </summary>
|
|
private List<int> _checkedCellIndexList = new List<int>();
|
|
|
|
/// <summary>
|
|
/// 预选单位
|
|
/// </summary>
|
|
private List<GameUnit> _preSelectUnits = new List<GameUnit>();
|
|
|
|
/// <summary>
|
|
/// 需要对单位释放
|
|
/// </summary>
|
|
private bool _addUnit;
|
|
|
|
/// <summary>
|
|
/// 选择的队伍
|
|
/// </summary>
|
|
private int _selectTroopId;
|
|
|
|
/// <summary>
|
|
/// 所有技能地格
|
|
/// </summary>
|
|
private List<int> _totalSkillAreaCellIndexList;
|
|
|
|
private SkillHandle skillHandle;
|
|
|
|
public bool SkillToCellCanRelease(SkillHandle skill, int cell)
|
|
{
|
|
skillHandle = skill;
|
|
_CalcSkillCellIndex();
|
|
_PreSelectCellIndex();
|
|
_PreSelectUnits();
|
|
|
|
return !_addUnit && _preSelectCellIndexList.Contains(cell);
|
|
}
|
|
|
|
public bool SkillToTargetCanRelease(SkillHandle skill, GameUnit target)
|
|
{
|
|
skillHandle = skill;
|
|
_CalcSkillCellIndex();
|
|
_PreSelectCellIndex();
|
|
_PreSelectUnits();
|
|
|
|
/*DebugUtil.LogError("---------------------------");
|
|
foreach (var unit in _preSelectUnits)
|
|
{
|
|
DebugUtil.LogError("需要添加单位:{0},预选人数是:{1}", _addUnit, unit.GetID());
|
|
}*/
|
|
|
|
return _addUnit && _preSelectUnits.Contains(target);
|
|
}
|
|
|
|
|
|
public bool CheckCanReleaseSkill(SkillHandle skill, int cell = -1)
|
|
{
|
|
skillHandle = skill;
|
|
_CalcSkillCellIndex();
|
|
_PreSelectCellIndex();
|
|
_PreSelectUnits();
|
|
|
|
if (_addUnit && _preSelectUnits.Count > 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
private void _PreSelectUnits()
|
|
{
|
|
_preSelectUnits.Clear();
|
|
if (_addUnit)
|
|
{
|
|
for (int i = 0; i < _preSelectCellIndexList.Count; i++)
|
|
{
|
|
var cellIndex = _preSelectCellIndexList[i];
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
for (int j = 0; j < units.Count; j++)
|
|
{
|
|
var unit = units[j];
|
|
if (!unit.statusData.canBeAttack)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (unit.commonData.troopId != _selectTroopId)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!_preSelectUnits.Contains(unit))
|
|
{
|
|
_preSelectUnits.Add(unit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void _PreSelectCellIndex()
|
|
{
|
|
_preSelectCellIndexList.Clear();
|
|
_checkedCellIndexList.Clear();
|
|
|
|
switch (skillHandle.runtimeData.configData.TargetType)
|
|
{
|
|
case ETargetType.Self:
|
|
// 添加自己
|
|
_addUnit = true;
|
|
_selectTroopId = ETroopsId.Enemy;
|
|
_TryAddCell(skillHandle.owner.transData.cellIndex);
|
|
break;
|
|
case ETargetType.AnyCell:
|
|
// 范围内的所有格子
|
|
_addUnit = false;
|
|
for (int i = 0; i < _totalSkillAreaCellIndexList.Count; i++)
|
|
{
|
|
var cellIndex = _totalSkillAreaCellIndexList[i];
|
|
_TryAddCell(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case ETargetType.LockTarget:
|
|
// 添加自己的攻击目标
|
|
_addUnit = true;
|
|
_selectTroopId = ETroopsId.Self;
|
|
var lockTarget = skillHandle.owner.controlData.targetEnemy;
|
|
if (lockTarget != null)
|
|
{
|
|
_TryAddCell(lockTarget.transData.cellIndex);
|
|
}
|
|
|
|
break;
|
|
case ETargetType.SelfSide:
|
|
// 己方单位
|
|
_addUnit = true;
|
|
_selectTroopId = ETroopsId.Enemy;
|
|
var selfUnits = GameUnitManager.instance.infightUnits.GetListByTroop(ETroopsId.Enemy);
|
|
for (int i = 0; i < selfUnits.Count; i++)
|
|
{
|
|
var unit = selfUnits[i];
|
|
_TryAddCell(unit.transData.cellIndex);
|
|
}
|
|
|
|
break;
|
|
case ETargetType.EnemySide:
|
|
// 敌方单位
|
|
_addUnit = true;
|
|
_selectTroopId = ETroopsId.Self;
|
|
var enemyUnits = GameUnitManager.instance.infightUnits.GetListByTroop(ETroopsId.Self);
|
|
for (int i = 0; i < enemyUnits.Count; i++)
|
|
{
|
|
var unit = enemyUnits[i];
|
|
_TryAddCell(unit.transData.cellIndex);
|
|
}
|
|
|
|
break;
|
|
case ETargetType.EmptyCell:
|
|
// 范围内所有的空白格子
|
|
for (int i = 0; i < _totalSkillAreaCellIndexList.Count; i++)
|
|
{
|
|
var cellIndex = _totalSkillAreaCellIndexList[i];
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
if (units == null || units.Count == 0)
|
|
{
|
|
_TryAddCell(cellIndex);
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
DebugUtil.LogError("未处理的技能目标类型:" + skillHandle.runtimeData.configData.TargetType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void _TryAddCell(int cellIndex)
|
|
{
|
|
if (_checkedCellIndexList.Contains(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_checkedCellIndexList.Add(cellIndex);
|
|
|
|
if (!_totalSkillAreaCellIndexList.Contains(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!AreaManager.instance.CheckMapCellAvailable(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var mapCellData = LevelManager.Instance.CurrentLevel.Map.GetBlockData(cellIndex);
|
|
if (mapCellData == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (skillHandle.runtimeData.configData.ReleaseCheckType)
|
|
{
|
|
case EReleaseCheckType.None:
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
break;
|
|
case EReleaseCheckType.AnyCell:
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
break;
|
|
case EReleaseCheckType.CenterIsEnemy:
|
|
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_CheckHasTargetSide(cellIndex, ETroopsId.Self))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.CenterIsEmpty:
|
|
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
if (units == null || units.Count == 0)
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.CenterIsSelfSide:
|
|
if (_CheckHasTargetSide(cellIndex, ETroopsId.Enemy))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.CenterIsSelfVehicle:
|
|
if (_CheckIsSelfVehicle(cellIndex))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.CenterIsCanUpVehicle:
|
|
if (_CheckIsCanUpVehicle(cellIndex))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.AreaContainsEnemy:
|
|
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_CheckShowAreaCellContainsSide(cellIndex, ETroopsId.Self))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
case EReleaseCheckType.AreaContainsSelfSide:
|
|
if (_CheckShowAreaCellContainsSide(cellIndex, ETroopsId.Enemy))
|
|
{
|
|
_preSelectCellIndexList.Add(cellIndex);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
DebugUtil.LogError("未处理的技能释放检查类型:" + skillHandle.runtimeData.configData.ReleaseCheckType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private bool _CheckShowAreaCellContainsSide(int cellIndex, int troopId)
|
|
{
|
|
var showAreaCellIndexId = skillHandle.runtimeData.configData.ShowAreaId;
|
|
var showAreaCellIndexList = AreaManager.instance.GetCellIndexs(cellIndex, showAreaCellIndexId);
|
|
for (int i = 0; i < showAreaCellIndexList.Count; i++)
|
|
{
|
|
var showAreaCellIndex = showAreaCellIndexList[i];
|
|
if (_CheckHasTargetSide(showAreaCellIndex, troopId))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool _CheckIsCanUpVehicle(int cellIndex)
|
|
{
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
for (int i = 0; i < units.Count; i++)
|
|
{
|
|
var unit = units[i];
|
|
if (unit.gameunitType != EGameUnitType.Vehicle)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var vehicle = unit as NormalVehicle;
|
|
if (vehicle == null)
|
|
{
|
|
DebugUtil.LogError("车辆类型错误");
|
|
continue;
|
|
}
|
|
|
|
if (vehicle.CheckCanUp(skillHandle.owner))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool _CheckIsSelfVehicle(int cellIndex)
|
|
{
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
for (int i = 0; i < units.Count; i++)
|
|
{
|
|
var unit = units[i];
|
|
if (unit.commonData.troopId == ETroopsId.Enemy
|
|
&& unit.gameunitType == EGameUnitType.Vehicle)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool _CheckHasTargetSide(int cellIndex, int troopId)
|
|
{
|
|
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
|
for (int i = 0; i < units.Count; i++)
|
|
{
|
|
var unit = units[i];
|
|
if (unit.commonData.troopId == troopId)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算技能所包含的地格
|
|
/// </summary>
|
|
private void _CalcSkillCellIndex()
|
|
{
|
|
var ownerCellIndex = skillHandle.owner.transData.cellIndex;
|
|
var selectRange = Mathf.CeilToInt(skillHandle.runtimeData.configData.ReleaseArea *
|
|
skillHandle.owner.fightData.skillReleaseDistanceScale);
|
|
var attackArea = AreaManager.instance.attackAreaManager.GetAttackArea(ownerCellIndex, selectRange);
|
|
if (skillHandle.runtimeData.configData.IgnoreBlock)
|
|
{
|
|
_totalSkillAreaCellIndexList = attackArea.totalCells;
|
|
}
|
|
else
|
|
{
|
|
_totalSkillAreaCellIndexList = attackArea.canAttackCells;
|
|
}
|
|
}
|
|
}
|
|
} |