using System.Collections.Generic; using Framework; using Gameplay.Area; using Gameplay.Character; using Gameplay.Common; using Gameplay.Effect; using Gameplay.Level; using Gameplay.Unit.Data; using Gameplay.Vehicle.Impl; using LTGame; using TGS; namespace Gameplay.Vehicle.State { public class VehicleStateDestroy : BaseVehicleState { private bool _lastCanControl; private EffectPlayingData _destroyEffectData; public VehicleStateDestroy(NormalVehicle owner) : base(owner, EVehicleState.Destroy) { } protected override void _OnEnter(NBaseState exitState, object param) { base._OnEnter(exitState, param); _PlayDeadAudio(); _PlayDeadEffect(); owner.vAnim.targetAnim = "dead"; owner.statusData.isDead = true; _lastCanControl = owner.commonData.canControl; owner.commonData.canControl = false; if (LevelManager.Instance.CurrentLevel.selectUnit == owner) { LevelManager.Instance.CurrentLevel.UnSelectUnit(); } // 如果所处地面是水面,则全部死亡 var map = LevelManager.Instance.CurrentLevel.Map; var cellIndex = owner.transData.cellIndex; var cellData = map.GetBlockData(cellIndex); // TODO: 这里只有string类型 if (cellData.GetTerrainTypeProperty().name == "水面") { _DeadCharacters(); } else { _DownCharacters(); } EventManager.Instance.Send(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, owner); EventManager.Instance.Send(EventManager.EventName.INFIGHT_UNIT_DEAD_OVER, owner); var isEnemy = owner.commonData.troopId != ETroopsId.Self; if (isEnemy) { isFinished = true; nextState = EVehicleState.FadeOut; } } private void _PlayDeadEffect() { if (owner.configData.deadEffectId == 0) return; _destroyEffectData = EffectManager.instance.PlayEffectById(owner.configData.deadEffectId, owner.transform.position, owner.transform.rotation); _destroyEffectData.autoDestroy = false; } private void _PlayDeadAudio() { if (string.IsNullOrEmpty(owner.configData.audioData.deadAudioId)) { return; } AudioManager.Instance.PlayAudio(owner.configData.audioData.deadAudioId, AudioCriManager.EPlayType.Sound, owner.Node.GameObject); } private void _DeadCharacters() { for (int i = 0; i < owner.containsUnits.Count; i++) { var unit = owner.containsUnits[i]; switch (unit.gameunitType) { case EGameUnitType.Character: if (unit is Character.Character character) character.ForceDead(); break; default: DebugUtil.LogError("不支持的单位类型: {0}", unit.gameunitType); break; } } // 清空载具内的单位 owner.containsUnits.Clear(); } private void _DownCharacters() { // 将载具内的单位全部下方到战场上 var requireCellCount = owner.containsUnits.Count; // 先搜寻周围的格子 var map = LevelManager.Instance.CurrentLevel.Map; var centerCellIndex = owner.transData.cellIndex; const int maxSearchRange = 10; var searchResult = new List(); for (int i = 0; i < maxSearchRange; i++) { // TODO: 只有这里用到了这个方法 var aroundList = map.TerrainGridSystem.CellGetNeighboursWithinRange(centerCellIndex, i, i + 1, includeInvisibleCells: false, canCrossCheckType: CanCrossCheckType.Default); for (int j = 0; j < aroundList.Count; j++) { var aroundCellIndex = aroundList[j]; if (AreaManager.instance.GetUnitsByCellIndex(aroundCellIndex).Count > 0) { continue; } if (map.GetRuntimeBlockProperty(aroundCellIndex, out var runtimeBlockProperty)) { if (!runtimeBlockProperty.selectable) { continue; } if (runtimeBlockProperty.banAttack) { continue; } } else { continue; } searchResult.Add(aroundCellIndex); if (searchResult.Count >= requireCellCount) { break; } } if (searchResult.Count >= requireCellCount) { break; } } if (searchResult.Count < requireCellCount) { DebugUtil.LogError("搜寻了10层都没有足够的格子"); return; } // 没有足够的格子 for (int i = 0; i < owner.containsUnits.Count; i++) { var unit = owner.containsUnits[i]; var character = unit as Character.Character; if (character == null) { DebugUtil.LogError("不支持的单位类型: {0}", unit.gameunitType); continue; } if (character.fullFSM.currentState.id == EFullState.UpVehicle) { // 在上车过车中,则直接下车 continue; } // 设置下车位置 var cellIndex = searchResult[i]; var worldPos = map.TerrainGridSystem.CellGetPosition(cellIndex); unit.transData.disableEvent = true; unit.transData.pos = worldPos; unit.transData.disableEvent = false; } var count = owner.containsUnits.Count; for (int i = 0; i < count; i++) { var unit = owner.containsUnits[0]; switch (unit.gameunitType) { case EGameUnitType.Character: if (unit is Character.Character character) character.DownVehicle(); break; default: DebugUtil.LogError("不支持的单位类型: {0}", unit.gameunitType); break; } } // 清空载具内的单位 owner.containsUnits.Clear(); } protected override void _OnExit(NBaseState exitState, object param) { base._OnExit(exitState, param); owner.statusData.isDead = false; owner.commonData.canControl = _lastCanControl; if (_destroyEffectData != null) { _destroyEffectData.Destroy(); _destroyEffectData = null; } } } }