223 lines
6.7 KiB
C#
223 lines
6.7 KiB
C#
using System;
|
|
using Gameplay;
|
|
using Framework;
|
|
using Gameplay.AI;
|
|
using UnityEngine;
|
|
using Gameplay.Unit;
|
|
using Gameplay.Level;
|
|
using Gameplay.BT.Variables;
|
|
using BehaviorDesigner.Runtime.Tasks;
|
|
using Action = BehaviorDesigner.Runtime.Tasks.Action;
|
|
|
|
public class BTMoveAround : Action
|
|
{
|
|
public SharedBattleInfo SharedBattleInfo;
|
|
private GameUnit owner;
|
|
private GameUnit target;
|
|
private Map map;
|
|
|
|
private EStage _stage = EStage.None;
|
|
private int _stageTargetCellIndex = -1;
|
|
private int _targetCellIndex = -1;
|
|
private int attackDistance;
|
|
|
|
private Vector2Int targetV2;
|
|
private Vector2Int ownerV2;
|
|
|
|
private uint _lastTarget;
|
|
|
|
private bool moveToTarget;
|
|
|
|
private enum EStage
|
|
{
|
|
None,
|
|
Stage1,
|
|
Stage2,
|
|
}
|
|
|
|
public override void OnStart()
|
|
{
|
|
owner = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.ownerId);
|
|
target = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.theChosenOneId);
|
|
|
|
map = LevelManager.Instance.CurrentLevel.Map;
|
|
_stageTargetCellIndex = -1;
|
|
_targetCellIndex = -1;
|
|
}
|
|
|
|
public override TaskStatus OnUpdate()
|
|
{
|
|
if (SharedBattleInfo.Value.theChosenOneId != Constants.INVALID_UINT_ID)
|
|
{
|
|
if (owner?.controlData.targetEnemy == null && _stage == EStage.Stage2)
|
|
{
|
|
// 继续追击目标
|
|
var enemy = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.theChosenOneId);
|
|
if (enemy != null && !enemy.statusData.isDead)
|
|
{
|
|
if (_targetCellIndex != enemy.transData.cellIndex)
|
|
{
|
|
target = enemy;
|
|
_targetCellIndex = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SharedBattleInfo.Value.theChosenOneId = Constants.INVALID_UINT_ID;
|
|
return TaskStatus.Failure;
|
|
}
|
|
}
|
|
|
|
if (HasTargetMoved())
|
|
{
|
|
RememberTarget();
|
|
|
|
switch (_stage)
|
|
{
|
|
case EStage.None:
|
|
_stageTargetCellIndex = GetStageTargetCell();
|
|
_stage = EStage.Stage1;
|
|
AIUtils.CheckAndMove(owner, _stageTargetCellIndex);
|
|
break;
|
|
|
|
case EStage.Stage1:
|
|
_stageTargetCellIndex = GetStageTargetCell();
|
|
AIUtils.CheckAndMove(owner, _stageTargetCellIndex);
|
|
break;
|
|
|
|
case EStage.Stage2:
|
|
_stageTargetCellIndex = target.transData.cellIndex;
|
|
AIUtils.CheckAndMove(owner, target.transData.cellIndex);
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
return TaskStatus.Running;
|
|
}
|
|
|
|
if (HasStageArrived() && !AIUtils.IsNeedStop(owner))
|
|
{
|
|
switch (_stage)
|
|
{
|
|
case EStage.Stage1:
|
|
_stage = EStage.Stage2;
|
|
_stageTargetCellIndex = target.transData.cellIndex;
|
|
AIUtils.CheckAndMove(owner, target.transData.cellIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TaskStatus.Running;
|
|
}
|
|
|
|
return TaskStatus.Failure;
|
|
}
|
|
|
|
private int GetStageTargetCell()
|
|
{
|
|
attackDistance = target.fightData.attackDistance / 2;
|
|
targetV2 = map.TGSCellIndex2BlockPosition(target.transData.cellIndex);
|
|
ownerV2 = map.TGSCellIndex2BlockPosition(owner.transData.cellIndex);
|
|
|
|
var correctPos = targetV2;
|
|
if (targetV2.y > ownerV2.y && targetV2.x > ownerV2.x) //左下
|
|
{
|
|
var x = targetV2.x + attackDistance;
|
|
var y = targetV2.y + attackDistance + 1;
|
|
|
|
while (x >= map.MapData.Height)
|
|
{
|
|
x--;
|
|
}
|
|
|
|
while (y >= map.MapData.Width)
|
|
{
|
|
y--;
|
|
}
|
|
|
|
correctPos = new Vector2Int(x, y);
|
|
// DebugUtil.Log("在目标的左下方,获取到的正确位置是:{0}", correctPos);
|
|
}
|
|
|
|
if (targetV2.y > ownerV2.y && targetV2.x < ownerV2.x) //左上
|
|
{
|
|
var x1 = targetV2.x - attackDistance;
|
|
var y1 = targetV2.y + attackDistance + 1;
|
|
while (x1 < 0)
|
|
{
|
|
x1++;
|
|
}
|
|
|
|
while (y1 >= map.MapData.Width)
|
|
{
|
|
y1--;
|
|
}
|
|
|
|
correctPos = new Vector2Int(x1, y1);
|
|
// DebugUtil.LogError("在目标的左上方,获取到的正确位置是:{0}", correctPos);
|
|
}
|
|
|
|
if (targetV2.y < ownerV2.y && targetV2.x > ownerV2.x) //右下
|
|
{
|
|
var x = targetV2.x + attackDistance;
|
|
var y = targetV2.y - attackDistance + 1;
|
|
while (x >= map.MapData.Height)
|
|
{
|
|
x--;
|
|
}
|
|
|
|
while (y < 0)
|
|
{
|
|
y++;
|
|
}
|
|
|
|
correctPos = new Vector2Int(x, y);
|
|
// DebugUtil.LogError("在目标的右下方,获取到的正确位置是:{0}", correctPos);
|
|
}
|
|
|
|
if (targetV2.y < ownerV2.y && targetV2.x < ownerV2.x) //右上
|
|
{
|
|
var x1 = targetV2.x - attackDistance;
|
|
var y2 = targetV2.y - attackDistance + 1;
|
|
while (x1 < 0)
|
|
{
|
|
x1++;
|
|
}
|
|
|
|
while (y2 < 0)
|
|
{
|
|
y2++;
|
|
}
|
|
|
|
correctPos = new Vector2Int(x1, y2);
|
|
// DebugUtil.LogError("在目标的右上方,获取到的正确位置是:{0}", correctPos);
|
|
}
|
|
|
|
var targetCellIndex = map.BlockPosition2TGSCellIndex(correctPos);
|
|
if (!AIUtils.CheckCellCanPass(map, owner, targetCellIndex))
|
|
{
|
|
targetCellIndex = AIUtils.GetCanReachCellAround(map, owner, targetCellIndex);
|
|
if (targetCellIndex == -1)
|
|
targetCellIndex = owner.transData.cellIndex;
|
|
}
|
|
|
|
return targetCellIndex;
|
|
}
|
|
|
|
private bool HasTargetMoved()
|
|
{
|
|
return _targetCellIndex != target.transData.cellIndex;
|
|
}
|
|
|
|
private void RememberTarget()
|
|
{
|
|
_targetCellIndex = target.transData.cellIndex;
|
|
}
|
|
|
|
private bool HasStageArrived()
|
|
{
|
|
return _stageTargetCellIndex == owner?.transData.cellIndex;
|
|
}
|
|
} |