NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Area/SkillAreaSelecter.cs

333 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameplay.Common;
namespace Gameplay.Area
{
using Framework;
using Character;
using Effect;
using Level;
using Skill;
using TMPro;
using UnityEngine;
public class SkillAreaSelecter
{
public bool isOnSelecting;
public GameUnit unit;
public SkillHandle skillHandle;
private int _areaId;
private readonly RaycastHit[] _raycastHits;
private readonly List<int> _cacheCellIndexList;
private int _lastCenterCellIndex;
private List<int> _totalCellIndexList;
private Color _bgAreaColor;
private readonly Color _selectColor;
// private Color _selectCenterColorY;
// private Color _selectCenterColorN;
private readonly Color _hintColor;
private readonly Color _hintColor2;
private TGS.Territory _cacheTerritory;
private GameObject _cacheObjBoarder;
private bool _isCenterCellValid;
private EffectPlayingData _skillAreaEffect;
private static readonly int Color1 = Shader.PropertyToID("_Color");
private static readonly int SecondColor = Shader.PropertyToID("_SecondColor");
public SkillAreaSelecter()
{
_raycastHits = new RaycastHit[10];
_cacheCellIndexList = new List<int>();
_totalCellIndexList = new List<int>();
_hintColor = ColorUtility.TryParseHtmlString("#C1C336", out Color color) ? color : Color.red;
_selectColor = ColorUtility.TryParseHtmlString("#FF9600", out Color color1) ? color1 : Color.red;
_selectColor.a = 0.45f;
_hintColor2 = ColorUtility.TryParseHtmlString("#c26b36", out Color color2) ? color2 : Color.red;
_hintColor2.a = 0;
}
public void Init()
{
}
public void Dispose()
{
if (_skillAreaEffect != null)
{
_skillAreaEffect.Destroy();
_skillAreaEffect = null;
}
}
public void ShowArea(SkillHandle inSkillHandle)
{
if (isOnSelecting)
{
DebugUtil.LogError("错误的调用: 已经在技能预选中");
return;
}
_isCenterCellValid = false;
isOnSelecting = true;
skillHandle = inSkillHandle;
unit = inSkillHandle.owner;
_areaId = inSkillHandle.runtimeData.configData.ShowAreaId;
_lastCenterCellIndex = -1;
_cacheCellIndexList.Clear();
var map = LevelManager.Instance.CurrentLevel.Map;
var playerCellIndex = unit.transData.cellIndex;
var seletRange = inSkillHandle.runtimeData.configData.ReleaseArea;
_totalCellIndexList = map.TerrainGridSystem.CellGetNeighboursWithinRange(playerCellIndex, -1, seletRange, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
_totalCellIndexList.Add(playerCellIndex);
_bgAreaColor = new Color(1, 1, 1, 0.5f);
// _selectCenterColorY = Color.green;
// _selectCenterColorN = Color.red;
map.SetBlocksColor(_totalCellIndexList, true, _bgAreaColor);
if (inSkillHandle.runtimeData.configData.ShowEffectId > 0)
{
var pos = unit.transData.pos;
_skillAreaEffect = EffectManager.instance.PlayEffectById(inSkillHandle.runtimeData.configData.ShowEffectId, pos);
}
// 生成技能边框区域
_cacheTerritory = map.TerrainGridSystem.TerritoryCreate(_totalCellIndexList);
var obj = map.TerrainGridSystem.ForceDrawTerritoryDrawInteriorBorder(_cacheTerritory, 0, 1, _hintColor, _hintColor2);
var getMat = obj.transform.GetChild(0).GetComponent<MeshRenderer>().material;
getMat.SetColor(Color1, _hintColor);
getMat.SetColor(SecondColor, _hintColor2);
_cacheObjBoarder = obj;
}
private void _HideAreaBoarder()
{
var map = LevelManager.Instance.CurrentLevel.Map;
var territoryIndex = map.TerrainGridSystem.TerritoryGetIndex(_cacheTerritory);
map.TerrainGridSystem.TerritoryDestroy(territoryIndex);
_cacheObjBoarder.Destroy();
}
public void EndShow(bool realUse)
{
if (!isOnSelecting)
{
DebugUtil.LogError("错误的调用: 不在技能预选状态");
return;
}
if (!skillHandle.canRelease)
{
DebugUtil.LogError("技能CD没好,强制取消释放");
realUse = false;
}
_HideAreaBoarder();
var map = LevelManager.Instance.CurrentLevel.Map;
if (_skillAreaEffect != null)
{
_skillAreaEffect.Destroy();
_skillAreaEffect = null;
}
isOnSelecting = false;
map.SetBlocksColor(_cacheCellIndexList, false, _bgAreaColor);
map.SetBlocksColor(_totalCellIndexList, false, _bgAreaColor);
if (realUse && _isCenterCellValid)
{
// 从lastCellIndex进行释放
var eventData = new EventDataUseSkill()
{
sender = unit,
pointCellIndex = _lastCenterCellIndex,
};
EventManager.Instance.Send(EventManager.EventName.UI_USE_SKILL, eventData);
}
}
public void LogicUpdate(float dt)
{
if (!isOnSelecting)
{
return;
}
var mousePos = InputManager.Instance.GetTouchPosition();
var camera = Camera.main;
if (camera == null) return;
var ray = camera.ScreenPointToRay(mousePos);
var layerMask = LayerMask.GetMask("Ground");
var raycast = Physics.RaycastNonAlloc(ray, _raycastHits, 1000, layerMask);
var map = LevelManager.Instance.CurrentLevel.Map;
if (raycast <= 0) return;
var firstHit = _raycastHits[0];
var hitPoint = firstHit.point;
if (!map.WorldPosition2TGSCellIndex(hitPoint, out var cellIndex)) return;
var skillConfig = skillHandle.runtimeData.configData;
if (!_totalCellIndexList.Contains(cellIndex))
{
// 计算出最近的点并进行设置
var minDistance = float.MaxValue;
var newCellIndex = cellIndex;
for (var i = 0; i < _totalCellIndexList.Count; ++i)
{
var bgIndex = _totalCellIndexList[i];
var distance = map.TerrainGridSystem.CellGetHexagonDistance(cellIndex, bgIndex);
if (distance < minDistance)
{
minDistance = distance;
newCellIndex = bgIndex;
}
}
cellIndex = newCellIndex;
}
if (skillConfig.SkillActionId == 2)
{
// 2号技能不需要中心点
cellIndex = unit.transData.cellIndex;
}
if (cellIndex != _lastCenterCellIndex)
{
if (_lastCenterCellIndex != -1)
{
// 将之前的变回
for (var i = 0; i < _cacheCellIndexList.Count; ++i)
{
var index = _cacheCellIndexList[i];
var isInBg = _totalCellIndexList.Contains(index);
map.SetBlockColor(index, isInBg, _bgAreaColor);
}
_cacheCellIndexList.Clear();
}
_lastCenterCellIndex = cellIndex;
// 更新技能影响区域
AreaManager.instance.GetCellIndexs(cellIndex, _areaId, _cacheCellIndexList);
map.SetBlocksColor(_cacheCellIndexList, true, _selectColor);
// map.SetBlockColor(cellIndex, true, _isCenterCellValid ? _selectCenterColorY : _selectCenterColorN);
var centerWorldPos = map.TGSCellIndex2WorldPosition(cellIndex);
if (_skillAreaEffect != null)
{
_skillAreaEffect.transform.position = centerWorldPos;
}
}
// 中心点单独设置
_isCenterCellValid = _CheckCenterAvilable(cellIndex);
}
private bool _CheckCenterAvilable(int centerCellIndex)
{
var skillConfig = skillHandle.runtimeData.configData;
switch (skillConfig.SkillActionId)
{
// 常规
case 1:
return _CheckSkillAction1(centerCellIndex);
case 2:
return _CheckSkillAction2(centerCellIndex);
default:
DebugUtil.LogError("暂未处理的技能类型:{0}", skillConfig.SkillActionId);
return false;
}
}
private bool _CheckSkillAction2(int centerCellIndex)
{
var skillConfig = skillHandle.runtimeData.configData;
var onwerTroopId = unit.commonData.troopId;
// 查找所有敌人
var units = GameUnitMapper.Inst.unitList;
var map = LevelManager.Instance.CurrentLevel.Map;
for (int i = 0; i < units.Count; i++)
{
var searchUnit = units[i];
if (searchUnit.statusData.isDead) continue;
if (searchUnit.commonData.troopId != onwerTroopId)
{
var distance = map.TerrainGridSystem.CellGetHexagonDistance(centerCellIndex, searchUnit.transData.cellIndex);
if (distance== -1) continue;
if (distance <= skillConfig.ReleaseArea)
{
return true;
}
}
}
return false;
}
private bool _CheckSkillAction1(int centerCellIndex)
{
var units = AreaManager.instance.GetUnitsByCellIndex(centerCellIndex);
var targetType = skillHandle.runtimeData.configData.TargetType;
switch (targetType)
{
case cfg.SkillCfg.ETargetType.EnemySide:
{
var isEnemy = false;
for (var i = 0; i < units.Count; ++i)
{
var u = units[i];
if (u.commonData.troopId != unit.commonData.troopId)
{
isEnemy = true;
break;
}
}
return isEnemy;
}
case cfg.SkillCfg.ETargetType.Self:
{
var isSelf = false;
for (var i = 0; i < units.Count; ++i)
{
var u = units[i];
if (u == unit)
{
isSelf = true;
break;
}
}
return isSelf;
}
case cfg.SkillCfg.ETargetType.EmptyCell:
{
var isEmpty = units.Count == 0;
return isEmpty;
}
case cfg.SkillCfg.ETargetType.AnyCell:
{
return true;
}
}
DebugUtil.LogError($"暂未处理的targetType:{targetType}");
return false;
}
}
}