local FirstPersonEventDispatcher = require"Battle/Logic/Event/FirstPersonEventDispatcher" local EventSystem = require("Event/EventSystem") local TargetSystem = require "Battle/Logic/Entity/System/TargetSystem" --技能 - 衔接相关 local SkillBaseSystem = {} local private = {} local table_insert=table.insert local table_remove=table.remove local FP_Const_Vector2_Zero=FP.Const.Vector2_Zero local FP_Const_Zero=FP.Const.Zero local LessEquals=FP.LessEquals local LuaConst=LuaConst local pairs=pairs local ESkillKeyPosition = LuaConst.ESkillKeyPosition local DODGE_KEYPOS = LuaConst.ESkillKeyPosition.Dodge local SkillDecoratorType = LuaConst.SkillDecoratorType local HERO_COMMON_CD_KEYPOS_LIST = LuaConst.HERO_COMMON_CD_KEYPOS_LIST local SkillDecorator = { [SkillDecoratorType.QuitReplaceSkillByCount] = require("Battle/Logic/Entity/SkillDecorator/SkillDecoratorQuitReplaceSkillByCount"), [SkillDecoratorType.ExtraCD] = require("Battle/Logic/Entity/SkillDecorator/SkillDecoratorExtraCD"), [SkillDecoratorType.TimingUseSkill] = require("Battle/Logic/Entity/SkillDecorator/SkillDecoratorTimingUseSkill"), [SkillDecoratorType.TimingUseSomeSkill] = require("Battle/Logic/Entity/SkillDecorator/SkillDecoratorTimingUseSomeSkill"), } --自己的BelongTo是否等于自己的ID function SkillBaseSystem.IsBelongToSelf(skillData) return skillData.BelongTo == skillData.ID end function SkillBaseSystem.IsNormalAttack(skillData) local result = false local belongToSkillData = DataSheetManager.SkillData:GetDataByID(skillData.BelongTo) --不需要通过entity获取,因为下面访问的数据预期不可能被重写 if belongToSkillData then --目前普攻不好判断,只能暂时用skillData.KeyPosition == 1 判断 result = belongToSkillData.KeyPosition == 1 end return result end function SkillBaseSystem.IsNormalAttackBySkillIndex(entity,skillIndex) local skillData = entity.components.skillBase.GetSkillDataBySkillIndex(skillIndex) if skillData then return SkillBaseSystem.IsNormalAttack(skillData) else return false end end function SkillBaseSystem.IsAdjutantSkill(skillData) return skillData.Type == LuaConst.SkillType.AdjutantMusou end function SkillBaseSystem.IsDodgeSkill(skillData) return skillData.KeyPosition == DODGE_KEYPOS end function SkillBaseSystem.IsMusouSkill(skillData) return skillData.Type == LuaConst.SkillType.MusouAttack end --获取当前正在使用无双或者副将技的单位数量 function SkillBaseSystem.GetUsingMusouOrAdjutantSkillEntityCount() local count = 0 for i,entity in ipairs(LogicUpdateManager.EntityList_Normal) do if entity:IsAdjutant() and entity:IsActive() then count = count + 1 end end for i,entity in ipairs(LogicUpdateManager.EntityList_Sync) do if entity:IsHero() then local skillData = entity.components.skillBase.CurSkillData if skillData and SkillBaseSystem.IsMusouSkill(skillData) then count = count + 1 end end end return count end --[[ Tick --]] function SkillBaseSystem.OnLogicUpdate(entity) local timeScale = entity.components.timeScale:GetCurTimeScale() if LessEquals(timeScale, 0) then -- 目的是为了防止CurSkillSwitchList被疯狂塞入数据 return end local comp_SkillBase = entity.components.skillBase if not comp_SkillBase then return end local lastPassTime = comp_SkillBase.CurLastPassTime local passTime = comp_SkillBase.CurPassTime local curSkill = comp_SkillBase.CurSkillData if curSkill then if passTime and passTime >= FP_Const_Zero then if curSkill.TimeScaleStartTime >= FP_Const_Zero then if lastPassTime < curSkill.TimeScaleStartTime and passTime >= curSkill.TimeScaleStartTime then SystemManager.OnAddTimeScale(entity, curSkill.ID, curSkill.TimeScale, 0, LuaConst.TimeScaleBreakType.HitBreak,curSkill.TimeScaleChannel) end if lastPassTime < curSkill.TimeScaleEndTime and passTime >= curSkill.TimeScaleEndTime then SystemManager.OnDeleteTimeScale(entity, curSkill.ID, curSkill.TimeScale) end end -- 添加 CurSkillSwitchList,当前技能衔接 --for key,skillSwitch in pairs(curSkill.SkillSwitch_Table) do --old for i,skillSwitch in ipairs(comp_SkillBase:GetSkillSwitchTable(curSkill.ID)) do --new if lastPassTime < skillSwitch.SwitchStartTime and passTime >= skillSwitch.SwitchStartTime and comp_SkillBase.CurModelSkillIDs[skillSwitch.SwitchPutOut] then table_insert(comp_SkillBase.CurSkillSwitchList,skillSwitch) end end end end --删除CurSkillSwitchList for i = #comp_SkillBase.CurSkillSwitchList ,1, -1 do local skillSwitch = comp_SkillBase.CurSkillSwitchList[i] local endTime = skillSwitch.SwitchStartTime + skillSwitch.SwitchDuration if lastPassTime <= endTime and passTime > endTime then table_remove(comp_SkillBase.CurSkillSwitchList ,i) --2022年3月1日新增:如果缓存的按键从 CurSkillSwitchList 里删掉了, 那么也要清除缓存按键。 这样做防止缓存按键在一些极端条件下不被清除导致玩家操作被缓存按键一直覆盖而卡住操作(比如狂点郭嘉1技能就会导致缓存不被清除,从而导致所有按键都按不了了) if skillSwitch.SwitchPutIn == comp_SkillBase.CacheSkillKeyPos then comp_SkillBase.CacheSkillKeyPos = -1 end end end end function SkillBaseSystem.OnAfterSkillLogicUpdate(entity) local comp_SkillBase = entity.components.skillBase local curSkill = comp_SkillBase.CurSkillData if curSkill then local lastPassTime = comp_SkillBase.CurLastPassTime local passTime = comp_SkillBase.CurPassTime if passTime and passTime >= FP_Const_Zero then -- CanSwitchAll,通用后摇 if lastPassTime < curSkill.SwitchAllTime and passTime >= curSkill.SwitchAllTime then SystemManager.ChangeToSwitchAll(entity ,true) SystemManager.OnDeleteTimeScale(entity, curSkill.ID, curSkill.TimeScale) end end if curSkill.Type == LuaConst.SkillType.Enegy then local updateData = comp_SkillBase.CurUpdateDataGroup[curSkill.BelongTo] if updateData and updateData.Enegy <= FP.Const.Zero then SystemManager.InterruptSkill(entity) end end end end --[[ 设置技能的 摇杆位置 --记录摇杆的位置 ]]-- function SkillBaseSystem.SetSkillJoystickPos(entity,pos) entity.components.skillBase.SkillJoystickPos = pos end --[[ 设置技能估计固定的目标点 --]] function SkillBaseSystem.OnSetSkillAimPos(entity,pos) entity.components.skillBase.AimPos = pos end --[[ 设置技能子弹的目标点 --]] function SkillBaseSystem.SetSkillMissilePos(entity,pos) entity.components.skillBase.MissileAimPos = pos end --[[ 设置技能的旋转缩放的目标朝向 ( 参数 dir 一定要新构造的一个新的FP,这个方法调用的频率很低,产生的FP很少的 ) --]] function SkillBaseSystem.SetSkillRSAimDir(entity,dir, offsetAngle) if offsetAngle and offsetAngle ~= 0 and offsetAngle ~= FP_Const_Zero then dir:Reset(FP.V2.GetOffsetToAngle(offsetAngle, dir)) end entity.components.skillBase.RSAimDir = dir end --[[ 进入攻击 --]] function SkillBaseSystem.OnAttackEnter(entity) local comp_SkillBase = entity.components.skillBase if not comp_SkillBase then return end comp_SkillBase.CanSwitchAll = false local curSkill = comp_SkillBase.CurSkillData if curSkill and curSkill.SwitchAllTime == FP.Const.Zero then --瞬时技能 --瞬时技能在AI处理的时候会有一点麻烦,所以在这里需要特殊记录 entity.components.record:AddInstantSkillAttackEnterRecord(curSkill.ID, LogicUpdateManager._clientHandleFrame) end if curSkill and curSkill.MSRecordAimType == LuaConst.EMSRecordAimType.NO_RECORD then comp_SkillBase.MSAimPos = nil end local target = entity.components.target.Target if target then comp_SkillBase.RecordAttackTargetPos = target.components.move.LogicPos:cloneV2() if curSkill and curSkill.MSRecordAimType == LuaConst.EMSRecordAimType.TARGET_POS then comp_SkillBase.MSAimPos = target.components.move.LogicPos:cloneV2() end -- 记录旋转缩放的朝向 if curSkill and curSkill.RSStartTime ~= FP.Const.NegOne then local aimDir = target:GetLogicPos() - entity:GetLogicPos() -- 不用缓存了,这个内存虽有分配,但很小且使用次数很少 SystemManager.SetSkillRSAimDir(entity,aimDir, curSkill.RSOffsetAngle) end end if curSkill then if curSkill.MSRecordAimType == LuaConst.EMSRecordAimType.LAST_SLAVE_POS then local lastSlave = entity:GetLastSlave() if lastSlave then comp_SkillBase.MSAimPos = LuaShoveManager.TrimAimPosByObstacleAndPriority(entity, lastSlave:GetLogicPos()) end elseif curSkill.MSRecordAimType == LuaConst.EMSRecordAimType.POS_TRACE_ENTITY then if entity.components.record.posTraceEntity then comp_SkillBase.MSAimPos = LuaShoveManager.TrimAimPosByObstacleAndPriority(entity, entity.components.record.posTraceEntity:GetLogicPos()) end end end comp_SkillBase:CallSkillDecoratorFuncBySkillID(comp_SkillBase.CurrentSkillID, "OnAttackEnter") end function SkillBaseSystem.AfterAttackEnter(entity, skillData) entity.components.skillBase:ClearSkillJoystickInfo() entity.components.record:AfterAttackEnter(skillData) end --设置为后摇状态 -- timeIsUpSwitch : 是否是时间自然到了的后摇 function SkillBaseSystem.ChangeToSwitchAll(entity , timeIsUpSwitch, interruptType) local comp_SkillBase = entity.components.skillBase if not comp_SkillBase then return end local curSkill = comp_SkillBase.CurSkillData if not comp_SkillBase.CanSwitchAll and curSkill and timeIsUpSwitch then BattleEventSystem.OnEntityTimeUpSkillSwitchAll(entity, curSkill) end comp_SkillBase.CanSwitchAll = true --这个设置要晚于上面的 if not comp_SkillBase.CanSwitchAll 的判断 if comp_SkillBase.CacheSkillKeyPos == nil or comp_SkillBase.CacheSkillKeyPos <= 0 then --(2022年8月3日)之前只有AttackEnter的时机会清理,AttackEnter结束后还会输入双摇杆,此时没有清理 --导致前一个技能的双摇杆输入污染后一个技能,所以保险起见在技能结束时也清理一遍 --仅在没有cachePos时才清理,因为cachePos大于0时,表示输入了下一个技能,此时的双摇杆数据是下一个技能的操作数据,不应该清空 comp_SkillBase:ClearSkillJoystickInfo() end if curSkill then local passTime = comp_SkillBase.PassTime if passTime and passTime >= FP_Const_Zero then SystemManager.DeleteTimeScale(entity, curSkill.ID, curSkill.TimeScale) end comp_SkillBase.MissileAimPos = nil comp_SkillBase.SkillJoystickPos = nil comp_SkillBase.CurSkillInterrupted = interruptType or LuaConst.SkillInterruptType.None if not( timeIsUpSwitch and (curSkill.AutoNextConditionStr == "1" or curSkill.AutoNextConditionStr == "pointerUp") ) then -- 自动连技能不清理双摇杆的移动目标位置,同属技能的MSAimPos也不清理 comp_SkillBase.AimPos = nil comp_SkillBase.RSAimDir = nil comp_SkillBase.MSAimPos = nil end comp_SkillBase.RecordAttackTargetPos = nil --处理公共CD local commonCD = curSkill.CommonCD if commonCD and FP.Greater(commonCD,0) and FP.Less(comp_SkillBase:GetCurCommonCD(),commonCD) then -- 公共CD取较大者 comp_SkillBase:SetCurCommonCD(commonCD, curSkill) if entity == BattleDataGetter.GetMainPlayerManipulatingEntity() then local _skillDataTemp local _updateDataTemp for i,keyPos in ipairs(HERO_COMMON_CD_KEYPOS_LIST) do _skillDataTemp = comp_SkillBase:GetSkillDataByKeyPosition(keyPos) if _skillDataTemp then if _skillDataTemp ~= curSkill then _updateDataTemp = comp_SkillBase.CurUpdateDataGroup[_skillDataTemp.BelongTo] if _updateDataTemp.CD < comp_SkillBase.CurCommonCD then if not _skillDataTemp.IgnoreCommonCD then EventSystem.Dispatch(EventID.Player_SkillCoolDown, keyPos, comp_SkillBase.CurCommonCD, comp_SkillBase.CurCommonCD) end end end end end end end comp_SkillBase:CallSkillDecoratorFuncBySkillID(curSkill.ID, "OnSwitchAll") end end function SkillBaseSystem.OnOnAttackQuit(entity) local comp_SkillBase = entity.components.skillBase if not comp_SkillBase then return end local curSkillData = comp_SkillBase.CurSkillData -- gws:如果蓄力技能被其他技能打断,需要将蓄力时间清零从而让蓄力技能进入CD。 if curSkillData and curSkillData.Type == LuaConst.SkillType.Serial and curSkillData.AutoNextConditionStr == "pointerUp" then local updateData = comp_SkillBase.CurUpdateDataGroup[curSkillData.BelongTo] if updateData and updateData.ProgressTime then updateData.ProgressTime:Reset() end end comp_SkillBase:CallSkillDecoratorFuncBySkillID(comp_SkillBase.CurrentSkillID, "OnAttackQuit") end --[[ function SkillBaseSystem.ChangeToSwitchAllFinish(entity,timeIsUpSwitch) -- 只要不是 时间自然到 ,就把技能切为空 if not timeIsUpSwitch then entity.components.skillBase:SetCurSkillID(-1) end end--]] function SkillBaseSystem.OnFilterAttack(entity, command) --主将需要判断是否骑马攻击;这个部分也可以在上下马+跑动idle切换的时候设置按钮值,但是UI可能存在坑,就在这个搞了 if entity._logicInitData.CharacterType == LuaConst.CharacterType.Hero then local skillKeyPos = -1 if command.SkillIndex > 0 then skillKeyPos = SystemManager.GetSkillKeyPositionBySkillIndex(entity,command.SkillIndex) end if skillKeyPos == LuaConst.NormalSkillKeyPos then if entity.components.buff:CheckHasBuffState(LuaConst.SpecialBuffs.InRiding) then if entity._logicInitData.HorseModelData.IsSpecialShaped then SystemManager.OffHorse(entity) else if command.MoveDir ~= FP_Const_Vector2_Zero then command.SkillIndex = SystemManager.GetSkillIndexByKeyPosition(entity,LuaConst.HorseRunSkillKeyPos) else command.SkillIndex = SystemManager.GetSkillIndexByKeyPosition(entity,LuaConst.HorseIdleSkillKeyPos) end end end end end local skillBaseComponent = entity.components.skillBase local skillID ,useAiAimPos = private.GetWantReleaseSkillIDBySkillIndex(entity,command.SkillIndex) local skillData = skillID>0 and entity:GetSkillData(skillID) or nil if command.SpecialCommand == LuaConst.SpecialCommandType.JoystickSetTargetAndUseSkill then local skillJoyStickID = private.GetSkillIDBySkillIndex(command.SkillIndex, skillBaseComponent) local skillJoyStickData = entity.components.skillBase:GetSkillJoystickData(skillJoyStickID) if skillJoyStickData then local target = entity.components.target.joystickTarget if not target then if skillData and skillData.ChooseType == LuaConst.ESkillChooseType.LOWEST_HP_HERO_IF_NO_JOYSTICK then target = TargetSystem.GetTargetBySkill(entity, skillID) end if not target then local entityPos = entity.components.move.LogicPos local joystickPos = entityPos:cloneV2() joystickPos.x:Add(command.SkillJoystickPosX) joystickPos.z:Add(command.SkillJoystickPosZ) --使用双摇杆通用方法获取target target = TargetManager.GetTargetByJoystick(entity, skillJoyStickData, joystickPos, nil, true) end end --new↑ SystemManager.SetTarget(entity,target) entity.ExpEntity:OnCmdJoystickSetTargetAndUseSkill(command, skillJoyStickData, entity) else if entity.components.target.joystickTarget then entity.components.target:SetJoystickTarget(nil) entity.ExpEntity:TryStopJoystickAimEffect() --正常情况,比如吕布变身后1技能瞄人的时候变身结束 --logging.error(LTAG.ERROR, "HYW : SkillBaseSystem.OnFilterAttack JoystickSetTargetAndUseSkill SpecialCommand处理时 skillJoyStickData 为 nil !! command.SkillIndex : ", command.SkillIndex, " skillID : ", skillID, " 不影响流程,测试可忽略") end end end if useAiAimPos and command.AISkillAimPos then SystemManager.OnSetSkillAimPos(entity, command.AISkillAimPos) SystemManager.SetSkillMissilePos(entity,command.AISkillAimPos) end --检测该技能能释放(是否存在、CD、能量等) if skillID >= 0 then if not skillData or not skillBaseComponent:CanUseSkill(skillData) then skillID = -1 end end --new 子技能机制 ↓ if skillID > 0 then if skillData and skillData.SubSkills and #skillData.SubSkills > 0 then local isUsing = false if skillBaseComponent.CurSkillData then for i,subSkillId in ipairs(skillData.SubSkills) do if skillBaseComponent.CurSkillData.ID == subSkillId then isUsing = true skillID = -1 break end end end if not isUsing then if command.SpecialCommand >= LuaConst.SpecialCommandType.SubSkillIndex1 and command.SpecialCommand <= LuaConst.SpecialCommandType.SubSkillIndex5 then skillID = skillData.SubSkills[command.SpecialCommand - LuaConst.SpecialCommandType.SubSkillIndex1 + 1] or -1 else skillID = -1 end end end end --new↑ return skillID end function SkillBaseSystem.OnSwitchHero(entity, fromEntity, dontBackground) if not dontBackground then entity.components.skillBase.NeedReleaseGetInSkill = true SystemManager.AddBuff(entity,LuaConst.SpecialBuffs.GetInSkillBuff, entity) -- 作用:防止死亡点同时有多个伤害巨高的子弹,导致新上的主将未放出生技能时就被打掉血了 -- 被隐藏的人,清理蓄力(连续)技能。 local comp_SkillBase = fromEntity.components.skillBase for cid, group in pairs(comp_SkillBase.AllUpdateDataGroup) do -- pairs safe 只清理数据,故安全 for _, updateData in pairs(group) do -- pairs safe 只清理数据,故安全 if updateData.ProgressTime then updateData.ProgressTime:Reset() -- 提醒:加逻辑处理代码,此处有pairs,千万注意 end end end end end function SkillBaseSystem.OnChangeModel(entity) local curskill = entity.components.skillBase.CurSkillData if curskill then SystemManager.OnDeleteTimeScale(entity, curskill.ID, curskill.TimeScale) end end function SkillBaseSystem.OnBreak(entity) local comp_SkillBase = entity.components.skillBase if not comp_SkillBase then return end SystemManager.ChangeToSwitchAll(entity, false, LuaConst.SkillInterruptType.StopEffect) comp_SkillBase:ClearCurSkillCacheInfo() end function SkillBaseSystem.OnChangeAvatar(entity, recover, withBornSkill, isFree, isInheritSkillCD, inheritSkillKeyPosList) local comp_SkillBase = entity.components.skillBase local comp_Base = entity.components.base SystemManager.ChangeToSwitchAll(entity, false, LuaConst.SkillInterruptType.BreakEffect) comp_SkillBase:ClearCurSkillCacheInfo() SkillBaseSystem.SetSkillListByCharacterData(entity,comp_Base.CurCharacterData, isFree, isInheritSkillCD, inheritSkillKeyPosList) comp_SkillBase.NeedReleaseGetInSkill = withBornSkill and not recover end function SkillBaseSystem.RevertToOriginSkillList(entity) SkillBaseSystem.SetSkillListByCharacterData(entity,entity.components.base.CurCharacterData) end --禁用技能键位(目前沉默依赖这个机制) function SkillBaseSystem.BanKeyPositions(entity, sourceEntity, keyPosList) entity.components.skillBase:SetBanKeyPosList(sourceEntity, keyPosList) -- 主视角事件统一用 FirstPersonEventDispatcher 派发 FirstPersonEventDispatcher.Player_BanKeyPositions(entity, keyPosList) end function SkillBaseSystem.CancelBanKeyPosition(entity,sourceEntity) entity.components.skillBase:SetBanKeyPosList(sourceEntity, nil) -- 主视角事件统一用 FirstPersonEventDispatcher 派发 FirstPersonEventDispatcher.Player_CancelBanKeyPosition(entity) end function SkillBaseSystem.SetSkillListByCharacterID(entity,characterID) local characterData = DataSheetUtil.GetCharacterData(entity:GetCharacterType(),characterID) if characterData then SkillBaseSystem.SetSkillListByCharacterData(entity,characterData) else logging.error(LTAG.ERROR, "HYW : 找不到CharacterType为", entity:GetCharacterType(), " ID为", characterID, " 的CharacterData") end end function SkillBaseSystem.SetSkillListByCharacterData(entity,characterData, noMagicWeaponSkill, isInheritSkillCD, inheritSkillKeyPosList) local oldSkillCDDic = isInheritSkillCD and SkillBaseSystem.GetCurSkillCDDic(entity) or nil entity.components.skillBase:SetCurrentSkillDataList(entity, characterData, noMagicWeaponSkill) SkillBaseSystem.ResetCurAllSkillCDByCDDic(entity, oldSkillCDDic, inheritSkillKeyPosList) entity.components.skillBase:ClearCurSkillCacheInfo() -- 主视角事件统一用 FirstPersonEventDispatcher 派发 FirstPersonEventDispatcher.Player_SetSkillList(entity) end function SkillBaseSystem.OnRevive(entity) local comp_SkillBase = entity.components.skillBase local comp_Base = entity.components.base SkillBaseSystem.SetSkillListByCharacterData(entity,comp_Base.CurCharacterData) SystemManager.ChangeToSwitchAll(entity) comp_SkillBase:SetCurSkillID(-1) end function SkillBaseSystem.ReplaceNormalSkillBySkillID(entity, newSkillID) local skillBaseComp = entity.components.skillBase local replaced = skillBaseComp:ReplaceNormalSkillBySkillID(newSkillID) -- 数据尝试切换 if replaced then skillBaseComp:RecalculateAutoFightSkillDataListAndAnimDistance(skillBaseComp.CurSkillDataList) -- 自动战斗数据替换 skillBaseComp:RefreshCurModelSkillIDs() -- 缓存字典替换 --按钮切换 local replaceSkillData = entity:GetSkillData(newSkillID) EventSystem.Dispatch(EventID.Player_ReplaceSkill, entity, replaceSkillData) end end --[[ 获取要释放的技能ID --]] function private.GetWantReleaseSkillIDBySkillIndex(entity,skillIndex) local comp_SkillBase = entity.components.skillBase local curSkill = comp_SkillBase.CurSkillData local btnSkillType = nil --是否有点击按钮触发的技能(这代码比较丑,但是因为策划需求功能,又不想填表,所以这里用丑一点的代码解决) local result = -1 local useAiAimPos = false local autoNextSkillHoldToward = false repeat --入场技 if comp_SkillBase.NeedReleaseGetInSkill then comp_SkillBase.NeedReleaseGetInSkill = false result = entity.components.base.CurCharacterData.GetInSkill or -1 break end --按钮位置是否被禁用 local keyPos = -1 if skillIndex > 0 then keyPos = SystemManager.GetSkillKeyPositionBySkillIndex(entity,skillIndex) end if comp_SkillBase:IsKeyPosBanned(keyPos) then break end local skillId = private.GetSkillIDBySkillIndex(skillIndex, comp_SkillBase) local isSkillSwitch = false -- 按键缓存 if keyPos > 0 then for key,skillSwitch in ipairs(comp_SkillBase.CurSkillSwitchList) do if skillSwitch.SwitchPutIn == keyPos then comp_SkillBase.CacheSkillKeyPos = keyPos break elseif skillId > 0 and skillSwitch.SwitchPutIn == -skillId then --新增机制:针对技能做switch comp_SkillBase.CacheSkillKeyPos = -skillId isSkillSwitch = true break end end end local cachePos = comp_SkillBase.CacheSkillKeyPos if cachePos > 0 or isSkillSwitch then --技能间的衔接 for key,skillSwitch in ipairs(comp_SkillBase.CurSkillSwitchList) do if skillSwitch.SwitchPutIn == cachePos then local passTime = comp_SkillBase.CurPassTime if passTime >= skillSwitch.SwitchMinPlayTime then --是否到可释放的时间 useAiAimPos = true local isSerial ,skillId = private.TryGetSerialSkill(skillSwitch.SwitchPutOut ,comp_SkillBase) if isSerial then btnSkillType = 1 result = skillId break end btnSkillType = 2 result = skillSwitch.SwitchPutOut break else result = -1 break end end end if result > 0 then local skillData = entity:GetSkillData(result) if comp_SkillBase:CanUseSkill(skillData) then --只有能释放技能时,才执行打断 SystemManager.ChangeToSwitchAll(entity, false, LuaConst.SkillInterruptType.BreakEffect) end end else if curSkill then if comp_SkillBase.CanSwitchAll then if curSkill.AutoNextConditionStr == "1" or curSkill.AutoNextConditionStr == "pointerUp" then result = curSkill.AutoNextID autoNextSkillHoldToward = curSkill.NextSkillHoldTowards entity.components.record.LastAutoNextSkillId = result else btnSkillType = 3 useAiAimPos = true if keyPos > 0 then result = private.GetSkillIDByKeyPos(comp_SkillBase,keyPos) else result = private.GetSkillIDBySkillIndex(skillIndex,comp_SkillBase) end end break end result = -1 break else --开始就用的技能 btnSkillType = 4 if keyPos > 0 then result = private.GetSkillIDByKeyPos(comp_SkillBase,keyPos) else result = private.GetSkillIDBySkillIndex(skillIndex,comp_SkillBase) end useAiAimPos = true break end end until true if result > 0 and btnSkillType then -- if entity.components.record.BtnSkillId ~= result then -- logging.error(LTAG.ERROR, "HYW : ", result, " , ", btnSkillType, " EntityID : ", entity.EntityID) -- end entity.components.record.BtnSkillId = result else -- if entity.components.record.BtnSkillId ~= -1 then -- logging.error(LTAG.ERROR, "HYW : ", -1) -- end entity.components.record.BtnSkillId = -1 end comp_SkillBase:SetAutoNextSkillHoldToward(autoNextSkillHoldToward) return result ,useAiAimPos end --[[ 尝试获取连续技能 isQueue:填true时,表示仅查询,不会报错 --]] function private.TryGetSerialSkill(skillid ,skillBaseComponent, isQueue) local skillData = skillBaseComponent.Entity:GetSkillData(skillid) if skillData then return private.TryGetSerialSkillByData(skillData,skillBaseComponent) else if not isQueue then logging.error(LTAG.ERROR , "[战斗策划] :发现要尝试放一个找不到的技能ID:", skillid) end return false,-1 end end function private.TryGetSerialSkillByData(skillData,skillBaseComponent) if skillData.Type == LuaConst.SkillType.Serial then local skillUpdateData = skillBaseComponent.CurUpdateDataGroup[skillData.BelongTo] if skillUpdateData then if skillUpdateData.CurSerialNextSkillID then return true , skillUpdateData.CurSerialNextSkillID end end end return false ,skillData.ID end function private.GetSkillIDBySkillIndex(skillIndex,skillBaseComponent) local skillId = -1 local skillData = skillBaseComponent:GetSkillDataBySkillIndex(skillIndex) if skillData then skillId = skillData.ID local isSerial isSerial,skillId = private.TryGetSerialSkillByData(skillData,skillBaseComponent) end return skillId end --[[ 根据技能按键获取技能ID --]] function private.GetSkillIDByKeyPos(skillBaseComponent,keyPos) if keyPos <= 0 then return -1 end local skillId = -1 for i,skill in ipairs(skillBaseComponent.CurSkillDataList) do if skill.KeyPosition == keyPos then skillId = skill.ID break end end local isSerial --new↓ if skillId > 0 then isSerial,skillId = private.TryGetSerialSkill(skillId, skillBaseComponent, true) end --new↑ return skillId end function SkillBaseSystem.GetSkillIDByKeyPosOfEntity(entity,keyPos) return private.GetSkillIDByKeyPos(entity.components.skillBase,keyPos) end function SkillBaseSystem.OnDrive(driverEntity,carEntity) local driveData = carEntity.components.drive:GetDriveData() if driveData == nil then -- 如果没有驾驶数据,则在释放技能时不先索敌 carEntity.components.skillBase:SetSearchTargetWhenSkill(driverEntity._logicInitData.IsPlayer) -- 释放技能前先索敌 end end function SkillBaseSystem.OnOffDrive(driverEntity,carEntity) carEntity.components.skillBase:SetSearchTargetWhenSkill(carEntity._logicInitData.IsPlayer) -- 释放技能前先索敌 end --region 变身继承技能CD -- 获取entity的当前技能的CD字典(key =KeyPosition , value = CD ) function SkillBaseSystem.GetCurSkillCDDic(entity) local curCDDic = {} local skillBaseComp = entity.components.skillBase local CurSkillDataList = skillBaseComp.CurSkillDataList for _,skill in pairs(CurSkillDataList) do -- pairs safe local keyPos = skill.KeyPosition if keyPos > 0 then local updateData = skillBaseComp.CurUpdateDataGroup[skill.ID] if updateData then local skillCD = updateData.CD if skillCD and skillCD > FP_Const_Zero then curCDDic[keyPos] = FP.newV1(0):Reset(updateData.CD) end end end end return curCDDic end -- oldSkillCDDic 为空则不设置 function SkillBaseSystem.ResetCurAllSkillCDByCDDic(entity, skillCDDic, inheritSkillKeyPosList) if skillCDDic then local skillBaseComp = entity.components.skillBase local CurSkillDataList = skillBaseComp.CurSkillDataList for _,skill in pairs(CurSkillDataList) do -- pairs safe (只设置数据,不进行其他逻辑) local keyPos = skill.KeyPosition if keyPos > 0 then local shouldReset = true if inheritSkillKeyPosList then shouldReset = false for i,inheritKeyPos in ipairs(inheritSkillKeyPosList) do if inheritKeyPos == keyPos or inheritKeyPos == -1 then shouldReset = true break end end else shouldReset = true end if shouldReset then local updateData = skillBaseComp.CurUpdateDataGroup[skill.ID] updateData.CD:Reset(skillCDDic[keyPos]) if updateData.CD > skill.SkillCD then updateData.CD:Reset(skill.SkillCD) end end end end end end --endregion 变身继承技能CD --region 技能额外功能(装饰) function SkillBaseSystem.GetSkillDecoratorByType(type) return SkillDecorator[type] end function SkillBaseSystem.AddSkillDecorator(entity, skillID, skillDecoratorType, ...) local skillBaseComp = entity.components.skillBase skillBaseComp:AddSkillDecorator(skillID, skillDecoratorType, nil, {...}) end function SkillBaseSystem.RemoveSkillDecoratorByType(entity, skillID, skillDecoratorType) local skillBaseComp = entity.components.skillBase local decoratorDic = skillBaseComp.DecoratorDic if decoratorDic then local decoratorList = decoratorDic[skillID] if decoratorList then for i,decorator in ipairs(decoratorList) do if decorator.type == skillDecoratorType then decorator:Dispose() table.remove(decoratorList, i) table.removebyvalue(skillBaseComp.DecoratorList, decorator) break end end end end end --endregion 技能额外功能(装饰) return SkillBaseSystem