NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Level/State/BattleState.cs

437 lines
15 KiB
C#

using System.Collections.Generic;
using Code.Scripts.Gameplay.Enviorment;
using Framework;
using Gameplay.Area;
using Gameplay.Buff;
using Gameplay.Bullet;
using Gameplay.Character;
using Gameplay.Pause;
using Gameplay.Skill;
using Gameplay.Summon;
using Gameplay.Unit;
using Gameplay.Unit.Data;
using Gameplay.Vehicle;
using Gameplay.Vehicle.Impl;
using Gameplay.Vehicle.TireMark;
using TGS;
using UnityEngine;
using Utils.Bounds;
namespace Gameplay.Level
{
public class BattleState : LevelBaseState
{
private bool _canUpdate;
protected override async void _OnEnter()
{
_canUpdate = false;
AreaManager.instance.Init();
TireMarkManager.CreateInstance();
TireMarkManager.instance.Init();
BulletManager.CreateInstance();
BuffManager.instance.Init();
await SkillManager.instance.Init();
BulletManager.instance.Init();
BoundsManager.instance.Init();
PauseManager.CreateInstance();
PauseManager.instance.Init();
EnviormentManager.CreateInstance();
EnviormentManager.instance.Init();
GameUnitManager.instance.EnterBattle();
_level.LevelTime = 0;
_level.isInBattle = true;
EventManager.Instance.Send(EventManager.EventName.LevelBattleBegin);
_canUpdate = true;
}
protected override void _OnUpdate(float deltaTime)
{
if (!_canUpdate) return;
_level.LevelTime += deltaTime;
SkillManager.instance.LogicUpdate(deltaTime);
BulletManager.instance.LogicUpdate(deltaTime);
BuffManager.instance.LogicUpdate(deltaTime);
GameUnitManager.instance.LogicUpdate(deltaTime);
AreaManager.instance.LogicUpdate(deltaTime);
PauseManager.instance.LogicUpdate(deltaTime);
TireMarkManager.instance.LogicUpdate(deltaTime);
EventManager.Instance.Send(EventManager.EventName.LevelTimeIncrease,deltaTime);
}
protected override void _OnExit()
{
_level.isInBattle = false;
PauseManager.instance.Dispose();
AreaManager.instance.Dispose();
BulletManager.instance.Dispose();
BoundsManager.instance.Dispose();
TireMarkManager.instance.Dispose();
EnviormentManager.instance.Dispose();
GameUnitManager.instance.Dispose();
}
public BattleState(Level level) : base(level)
{
}
protected override void _OnClick(Vector2 screenPosition)
{
var clickCellIndex = GroundHitHelper.CalcHitCellIndex(screenPosition);
if (clickCellIndex < 0)
{
return;
}
_OnCellClick(_level.Map.TerrainGridSystem, clickCellIndex, 0);
}
protected override void _OnCellClick(TerrainGridSystem tgs,
int cellIndex,
int buttonIndex)
{
if (InputManager.Instance.HandledThisFrame())
{
return;
}
var map = _level.Map;
if (map == null) return;
var unitList = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
OnHit(unitList, cellIndex);
}
private void OnHit(List<GameUnit> units,
int cellIndex)
{
if (units.Count <= 0)
{
var map = _level.Map;
var worldPosition = map.TerrainGridSystem.CellGetPosition(cellIndex);
var teamSelectID = TeamManager.Instance.SelectID;
if (ValueValidator.IsIdValid(teamSelectID))
{
if (TeamManager.Instance.IsInLevel(teamSelectID))
{
var unit = GameUnitManager.instance.infightUnits.Search(teamSelectID);
if (unit.gameunitType == EGameUnitType.Character)
{
if (unit.statusData.isOnVehicle)
{
//下车
_GetOutVehicle(teamSelectID, cellIndex);
return;
}
}
}
else
{
_FightInBattle(map, cellIndex, worldPosition);
return;
}
}
}
var selectUnit = _level.selectUnit;
if (selectUnit == null)
{
// 进行选中
for (int i = 0; i < units.Count; i++)
{
var unit = units[i];
if (unit.commonData.canSelect)
{
// 只选中可控制单位
_level.SelectUnit(unit);
break;
}
}
return;
}
if (units.Count <= 0)
{
// 进行移动
selectUnit.MoveTo(cellIndex, true);
}
else
{
// 如果当前选择目标是己方英雄
switch (selectUnit.gameunitType)
{
case EGameUnitType.Character:
_HandleCharacterSelect(units, selectUnit as Character.Character);
break;
case EGameUnitType.Vehicle:
_HandleVehicleSelect(units, selectUnit as NormalVehicle);
break;
default:
break;
}
}
}
private void _HandleVehicleSelect(List<GameUnit> units,
NormalVehicle vehicle)
{
// 设置目标
for (int i = 0; i < units.Count; i++)
{
var unit = units[i];
// 如果是敌人,则设置目标
if (Level.IsEnemy(vehicle, unit))
{
vehicle.MoveTo(unit);
return;
}
// 如果是己方单位,则选中
if (unit.commonData.canSelect)
{
// 只选中可控制单位
_level.SelectUnit(unit);
return;
}
}
// 如果走到这里,只能进行移动操作
vehicle.MoveTo(units[0].transData.cellIndex, true);
}
private void _HandleCharacterSelect(List<GameUnit> units,
Character.Character character)
{
for (int i = 0; i < units.Count; i++)
{
var unit = units[i];
// 如果是敌人,则设置目标
if (Level.IsEnemy(character, unit))
{
character.MoveTo(unit);
return;
}
// 目前不需要该段逻辑
// 如果是载具,则向载具移动
if (unit.gameunitType == EGameUnitType.Vehicle)
{
// 需要紧挨着载具
var vehicle = unit as NormalVehicle;
if (vehicle == null) continue;
var vehicleCellIndex = vehicle.transData.cellIndex;
var characterCellIndex = character.transData.cellIndex;
var distance = _level.Map.TerrainGridSystem.CellGetHexagonDistance(vehicleCellIndex, characterCellIndex);
if (distance <= 1)
{
// 在附近,则移动到载具
if (vehicle.CheckCanUp(character))
{
character.UpVehicle(vehicle);
}
else
{
character.MoveTo(vehicle.transData.cellIndex, true);
}
return;
}
}
// 如果是己方单位,则选中
if (unit.commonData.canSelect)
{
_level.SelectUnit(unit);
return;
}
}
// 如果走到这里,只能进行移动操作
character.MoveTo(units[0].transData.cellIndex, true);
}
//战斗中上阵
private void _PutUnitInLevel(Map map,
int cellIndex,
Vector3 worldPosition)
{
if (map == null)
{
return;
}
var teamSelectID = TeamManager.Instance.SelectID;
if (ValueValidator.IsIdValid(teamSelectID))
{
if (TeamManager.Instance.IsInLevel(teamSelectID))
{
var unit = GameUnitManager.instance.infightUnits.Search(teamSelectID);
if (unit.gameunitType == EGameUnitType.Character)
{
if (unit.statusData.isOnVehicle)
{
//下车
_GetOutVehicle(teamSelectID, cellIndex);
}
}
}
else
{
_FightInBattle(map, cellIndex, worldPosition);
}
}
}
private void _FightInBattle(Map map,
int cellIndex,
Vector3 worldPosition)
{
if (TeamManager.Instance.IsFightListLimit(TeamManager.Instance.SelectID))
{
//TODO chenyq 需要添加到stringconfig
UITipsManager.ShowTips("上阵人数达到上限!");
return;
}
// 不是准备区域
if (!_level.IsPreparingRegion(cellIndex))
{
return;
}
var crossLevel = 0;
var unitType = TeamManager.Instance.GetUnitType(TeamManager.Instance.SelectID);
switch (unitType)
{
case SingleTeamCharacterInfo.CharacType.Hero:
var characterDataInfo = TeamManager.Instance.GetCharacterDataInfo(TeamManager.Instance.SelectID)
.GetConfigInfo();
crossLevel = characterDataInfo.Cfg.MoveCrossLevel;
break;
case SingleTeamCharacterInfo.CharacType.Vehicle:
var vehicleInfo = TeamManager.Instance.GetCharacterDataInfo(TeamManager.Instance.SelectID)
.GetVehicleInfo();
crossLevel = vehicleInfo.Cfg.MoveCrossLevel;
break;
default:
DebugUtil.LogError("暂未处理的类型:{0}", unitType);
return;
}
// 检查通行级别是否可以放置
var blockData = map.GetBlockData(cellIndex);
if (!MapUtils.CanPass(crossLevel, blockData.GetTerrainTypeProperty()))
{
return;
}
var yaw = LevelUtils.SetCharaterToward(_level.GetLevelData().preparingRegionToward);
switch (unitType)
{
case SingleTeamCharacterInfo.CharacType.Hero:
_CreateCharacter(TeamManager.Instance.SelectID, worldPosition, yaw);
break;
case SingleTeamCharacterInfo.CharacType.Vehicle:
_CreateVehicle(TeamManager.Instance.SelectID, worldPosition, yaw);
break;
}
_level.SelectUnit(TeamManager.Instance.SelectID);
_level.SetSpeed(ELevelSpeed.Normal);
}
private async void _CreateCharacter(uint id,
Vector3 position,
float yaw)
{
var map = _level.Map;
if (map == null) return;
var characterInfo = CharacterDataInfoManager.Instance.GetCharacterInfo(TeamManager.Instance.SelectID);
if (characterInfo == null)
{
return;
}
var character = await GameUnitManager.instance.PrepareCharacter(characterInfo, ETroopsId.Self);
if (character == null)
{
DebugUtil.LogError("创建角色失败");
return;
}
if (!map.WorldPosition2TGSCellIndex(position, out var cellIndex))
{
DebugUtil.LogError("无法获取到单元格索引");
return;
}
GameUnitManager.instance.MoveUnitToFight(character.GetID(), cellIndex, yaw);
}
private async void _CreateVehicle(uint id,
Vector3 pos,
float yaw)
{
var vInfo = VehicleCultivateDataManager.Instance.GetVehicleCultivateData(id);
var vehicle = await GameUnitManager.instance.PrepareVehicle(vInfo, ETroopsId.Self);
if (vehicle == null)
{
DebugUtil.LogError("创建载具失败");
return;
}
if (!_level.Map.WorldPosition2TGSCellIndex(pos, out var cellIndex))
{
DebugUtil.LogError("无法获取到cellIndex: {0}", pos);
return;
}
GameUnitManager.instance.MoveUnitToFight(vehicle.GetID(), cellIndex, yaw);
}
private void _GetOutVehicle(uint uid,
int cellIndex)
{
var gameUnit = GameUnitManager.instance.infightUnits.Search(uid);
if (gameUnit != null)
{
var character = (Character.Character)gameUnit;
if (_CheckIsValidCellIndex(cellIndex, character))
{
character.transData.disableEvent = true;
character.transData.pos =
LevelManager.Instance.CurrentLevel.Map.TGSCellIndex2WorldPosition(cellIndex);
character.transData.disableEvent = false;
character.DownVehicle();
}
}
}
private bool _CheckIsValidCellIndex(int cellIndex,
Character.Character character)
{
var vehicle = character.runtimeData.belongVehicle;
var centerIndex = vehicle.transData.cellIndex;
var aroundList = AreaManager.instance.GetCellIndexsAround(centerIndex, 1);
if (aroundList.Contains(cellIndex))
{
return true;
}
return false;
}
}
}