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.Common; using Gameplay.Pause; using Gameplay.Skill; using Gameplay.Summon; 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.CreateInstance(); AreaManager.instance.Init(); TireMarkManager.CreateInstance(); TireMarkManager.instance.Init(); BulletManager.CreateInstance(); SummonManager.CreateInstance(); await VehicleManager.Inst.InitForBattle(); SummonManager.instance.Init(); BuffManager.instance.Init(); await SkillManager.instance.Init(); BulletManager.instance.Init(); BoundsManager.instance.Init(); PauseManager.CreateInstance(); PauseManager.instance.Init(); EnviormentManager.CreateInstance(); EnviormentManager.instance.Init(); await _level.CharacterManager.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); SummonManager.instance.LogicUpdate(deltaTime); VehicleManager.Inst.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(); SummonManager.instance.Dispose(); BulletManager.instance.Dispose(); BoundsManager.instance.Dispose(); TireMarkManager.instance.Dispose(); EnviormentManager.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 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 = GameUnitMapper.Inst.GetUnitById(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 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 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 = GameUnitMapper.Inst.GetUnitById(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(map.TGSCellIndex2BlockPosition(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 _level.CharacterManager.CreateCharacter(characterInfo, ETroopsId.Self, position, yaw); if (character != null) { character.PrepareReady(); await character.EnterBattle(); } } private async void _CreateVehicle(uint id, Vector3 pos, float yaw) { var cInfo = TeamManager.Instance.GetCharacterDataInfo(id); var vehicleId = cInfo.GetVehicleInfo().Cfg.ID; var fakeSkillLevel = 1; var vehicle = await VehicleManager.Inst.CreateVehicle(id, vehicleId, fakeSkillLevel, ETroopsId.Self); if (vehicle == null) { return; } vehicle.transData.pos = pos; vehicle.transData.yaw = yaw; } private void _GetOutVehicle(uint uid, int cellIndex) { var gameUnit = GameUnitMapper.Inst.GetUnitById(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; } } }