using System.Collections.Generic; using Gameplay.Area; using Gameplay.Character; using Gameplay.Character.Helper; using Gameplay.Character.Skill; using Gameplay.Common; using Gameplay.Effect; using Gameplay.Level; using Gameplay.Pool; using Gameplay.Skill; using Gameplay.Summon; using Gameplay.Unit; using Gameplay.Unit.Data; using Gameplay.Vehicle.Impl; using LTGame; using PhxhSDK; using UnityEngine; namespace Gameplay.Vehicle.State { public class VehicleStateSkill: BaseVehicleState, ISkillState { private readonly List _skillActions; private SkillHandle _skillHandle; public SkillHandle GetSkillHandle() { return _skillHandle; } private int _skillActionId; public int GetSkillActionId() { return _skillActionId; } // 这个是专门给特殊技能逻辑2用的 #region 特殊使用 private List _cacheEnemys; public List GetCacheEnemyUnits() { return _cacheEnemys; } public int cacheIndex { get; set; } #endregion public bool readyPauseEnd { get; set; } public bool readySkillEnd { get; set; } public GameUnit GetOwner() { return owner; } private GameObject _cacheGroundEffect; private float _oldSpeed; public VehicleStateSkill(NormalVehicle owner): base(owner, EVehicleState.Skill) { _skillActions = new List(); _cacheEnemys = new List(); } protected override void _OnEnter(NBaseState exitState, object param) { base._OnEnter(exitState, param); // 取消选中 LevelManager.Instance.CurrentLevel.UnSelectUnit(); _oldSpeed = LevelManager.Instance.CurrentLevel.GetSpeed(); LevelManager.Instance.CurrentLevel.SetSpeed(ELevelSpeed.DEFAULT_SPEED); readyPauseEnd = false; readySkillEnd = false; owner.statusData.isInSkilling = true; // 只有己方单位使用技能需要暂停 if (owner.commonData.troopId == ETroopsId.Self) { owner.statusData.needSkillPaused = true; // 将自己添加进全屏效果 SkillManager.instance.screenEffect.AttachUnit(owner); EffectManager.instance.forceSetLayer = LayerDefine.Skill; } //TODO: 播放技能动作 var skillUnit = SkillManager.instance.GetUnitSkillManager(owner); _skillHandle = skillUnit.positiveSkill; _skillActionId = _skillHandle.runtimeData.configData.SkillActionId; // 根据逻辑序列进行处理 _PrepareActions(); _PlayGroundEffect(); } private void _PlayGroundEffect() { if (!owner.statusData.needSkillPaused) { return; } var skillConfig = _skillHandle.runtimeData.configData; if (!skillConfig.IsEmitToFloor) { return; } var showAreaId = skillConfig.ShowAreaId; var showCellIndexs = AreaManager.instance.GetCellIndexs(owner.controlData.skillCellIndex, showAreaId); _cacheGroundEffect = CharacterSkillHelper.CreateSkillGroundHighLight(showCellIndexs); } private void _PrepareActions() { // 根据逻辑序列进行处理 _skillActions.Clear(); var logicData = _skillHandle.runtimeData.logicData; if (logicData == null) return; var emitCount = 0; for (var i = 0; i < logicData.actionList.Count; ++i) { var actionData = logicData.actionList[i]; var action = CharacterSkillHelper.CreateAction(actionData); if (action == null) { DebugUtil.LogError("未找到对应的action:" + actionData.actionType); continue; } action.actionData = actionData.Clone(); action.skill = this; action.triggerTime = actionData.triggerTime; if (action.actionData.actionType == ESkillActionType.EMIT_BULLET || action.actionData.actionType == ESkillActionType.EMIT_BULLET_SELECT) { emitCount++; // 转接id _RebindId(action); } else if (action.actionData.actionType == ESkillActionType.CREATE_SUMMON || action.actionData.actionType == ESkillActionType.EMIT_BULLET_TO_SELF) { // 转接id _RebindId(action); } action.Prepare(); _skillActions.Add(action); } switch (_skillActionId) { case 1: case 3: case 4: case 5: case 6: CharacterSkillHelper.RotateToTargetCell(owner); break; case 2: // 特殊技能逻辑,用于一个技能针对多个目标 _HandleSpecialLogic2(emitCount); break; default: DebugUtil.LogError("暂未处理的logicActionId:" + _skillActionId); break; } } private void _HandleSpecialLogic2(int emitCount) { // 筛选出目标 cacheIndex = 0; _cacheEnemys.Clear(); var areaId = _skillHandle.runtimeData.configData.InfluenceAreaId; var areaIndexs = AreaManager.instance.GetCellIndexs(owner.controlData.skillCellIndex, areaId); var allEnemys = _SearchEnemysByCellIndexs(areaIndexs); if (allEnemys.Count > emitCount) { // 随机选emitCount个,去重 _cacheEnemys = PhxhSDK.Utils.GetRandomElementFromList(allEnemys, emitCount); } else if (allEnemys.Count == emitCount) { // 全部选 _cacheEnemys = allEnemys; } else { // 全部选,并且随机补充 _cacheEnemys.AddRange(allEnemys); var needCount = emitCount - allEnemys.Count; for (int i = 0; i < needCount; i++) { var randomEnemy = PhxhSDK.Utils.RandomFromList(allEnemys); _cacheEnemys.Add(randomEnemy); } } // 旋转到第一个目标 if (_cacheEnemys.Count > 0) { CharacterSkillHelper.RotateToTargetEnemy(owner, _cacheEnemys[0]); } } private void _RebindId(CharacterSkillAction action) { var idIndex = action.actionData.id; if (idIndex >= _skillHandle.runtimeData.configData.ReferIds.Count) { idIndex = _skillHandle.runtimeData.configData.ReferIds.Count - 1; } action.actionData.id = _skillHandle.runtimeData.configData.ReferIds[idIndex]; } private List _SearchEnemysByCellIndexs(List cellIndexs) { var result = new List(); var selfTroopId = owner.commonData.troopId; for (int i = 0; i < cellIndexs.Count; i++) { var searchCellIndex = cellIndexs[i]; var searchUnits = AreaManager.instance.GetUnitsByCellIndex(searchCellIndex); for (int j = 0; j < searchUnits.Count; j++) { var searchUnit = searchUnits[j]; if (searchUnit.gameunitType != EGameUnitType.Character) continue; if (searchUnit.statusData.isDead) continue; if (searchUnit.commonData.troopId != selfTroopId) { result.Add(searchUnit); } } } return result; } protected override void _OnRunning() { base._OnRunning(); for (var i = 0; i < _skillActions.Count; ++i) { var action = _skillActions[i]; action.LogicUpdate(passTime); if (action.isTriggered) { _skillActions.RemoveAt(i); i--; } } if (_skillActions.Count <= 0 || readyPauseEnd) { owner.statusData.needSkillPaused = false; EffectManager.instance.forceSetLayer = -1; } if (_skillActions.Count <= 0 || readySkillEnd) { isFinished = true; nextState = EFullState.Empty; } } protected override void _OnExit(NBaseState exitState, object param) { base._OnExit(exitState, param); owner.statusData.isInSkilling = false; _skillActions.Clear(); owner.statusData.needSkillPaused = false; EffectManager.instance.forceSetLayer = -1; _skillHandle.TriggerSkillEnd(); if (_cacheGroundEffect != null) { Object.Destroy(_cacheGroundEffect); _cacheGroundEffect = null; } // 恢复速度 LevelManager.Instance.CurrentLevel.SetSpeed(_oldSpeed); } } }