333 lines
12 KiB
C#
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;
|
|
}
|
|
|
|
}
|
|
}
|