local Base = require("Battle/Logic/AI/Decision/Decision_Base") local Decision_UseRandomSkill = class("Decision_UseRandomSkill", Base) local SkillMissileSystem = require"Battle/Logic/Entity/System/SkillMissileSystem" local RANDOM_SKILL_INDEX_RECORD_KEY = "randomSkillIndex" local EWeightCutType = { RECOVER_WHEN_ALL_USED = 1, --如果有N个技能随机,那么得N个技能都放过一次,才会恢复权重 RECOVER_WHEN_OTHER_USED = 2, --只要放过其他技能,那么减权的技能就会恢复权重 } --[[ 初始化 --]] function Decision_UseRandomSkill:initialize(entity) --类型 self.Type = LuaConst.DecisionType.UseRandomSkill --瞬时 self.IsOnce = false end function Decision_UseRandomSkill:GetSkillIndexByKey(key, entity) if key < 0 then --负数表示是KeyPosition return entity.components.skillBase:GetSkillIndexByKeyPosition(-key) else return key end end function Decision_UseRandomSkill:GetRandomSkillIndex(decisionData, entity) local index = nil local intPairListCount = #decisionData.intPairList if decisionData.intPairList and intPairListCount > 0 then local weightSum = nil local intPairList = nil if decisionData.weightCutType == nil then --减权类型为空,则不减权,直接取 decisionData 里配置的静态参数 weightSum = decisionData.intPairValueSum intPairList = decisionData.intPairList else --减权类型不为空,走新增的减权机制,需要取动态权重(在有权重修改record的情况下) local decisionEntityRecord = entity.components.aiBase:GetEntityRecord(decisionData.ID) if decisionEntityRecord and decisionEntityRecord.dynamicIntPairList then intPairList = decisionEntityRecord.dynamicIntPairList weightSum = decisionEntityRecord.dynamicWeightSum else --如果没有减权记录,则直接用decisionData的 weightSum = decisionData.intPairValueSum intPairList = decisionData.intPairList end end if weightSum <= 0 then --如果都没配权重,那么每个项的权重都认为是1,直接随机一个index即可 index = self:GetSkillIndexByKey(intPairList[LogicRandom.GetIntegerValue(nil, 1, intPairListCount ,1012)].key, entity) else local rand = LogicRandom.GetIntegerValue(nil, 1, weightSum ,1013) local sum = 0 for i,intPair in ipairs(intPairList) do sum = sum + intPair.value if sum >= rand then index = self:GetSkillIndexByKey(intPair.key, entity) break end end end else logging.error(LTAG.ERROR, "HYW : decision : ", decisionData.ID, " 数据异常,无法随机技能index") end if not index then index = -1 end return index end function Decision_UseRandomSkill:GetSkillIndexRecord(entity,decisionData) return entity.components.aiBase:GetDecisionRecord(decisionData,RANDOM_SKILL_INDEX_RECORD_KEY) end --[[ 能否进入 执行条件:能释放技能 --]] function Decision_UseRandomSkill:CanEnter(entity, decisionData, command) local can = false local skillBaseComponent = entity.components.skillBase local index = self:GetRandomSkillIndex(decisionData, entity) if index > 0 then -- ↓ new 访问统一接口 Decision_Base:CanAiUseSkill local skillData = skillBaseComponent:GetSkillDataBySkillIndex(index) if skillData then can = self:CanAiUseSkill(entity, skillBaseComponent, skillData, ConditionManager.GetConditionDataTree(skillData.AutoBattleCondition)) else can = false end if can then entity.components.aiBase:SetDecisionRecord(decisionData, RANDOM_SKILL_INDEX_RECORD_KEY, index) entity.components.aiBase:SetDecisionRecord(decisionData, "skillData", skillData) end -- ↑ new -- ↓ old 现在改为了访问统一接口 Decision_Base:CanAiUseSkill -- local skillData = skillBaseComponent:GetSkillDataBySkillIndex(index) -- if skillData then -- can = skillBaseComponent:CanUseSkill(skillData) -- if can then -- entity.components.aiBase:SetDecisionRecord(decisionData, RANDOM_SKILL_INDEX_RECORD_KEY, index) -- end -- end -- else -- logging.error(LTAG.ERROR, "HYW : 获取随机技能失败 decisionData.ID : ", decisionData.ID, " CharacterID : ", entity._logicInitData.CharacterID, " index : ", index) -- old↑ end return can end --[[ 能否退出 完成条件:技能后摇时间到 --]] function Decision_UseRandomSkill:CanExit(entity, decisionData, command) local skillBaseComponent = entity.components.skillBase if skillBaseComponent.CanSwitchAll then if skillBaseComponent.CurSkillData then local index = self:GetSkillIndexRecord(entity,decisionData) if index then if skillBaseComponent.CurSkillData.AutoNextID > 0 then return false else local skillData = skillBaseComponent:GetSkillDataBySkillIndex(index) if decisionData.weightCutType ~= nil then local decisionEntityRecord = entity.components.aiBase:GetEntityRecord(decisionData.ID) or {} if decisionEntityRecord.dynamicIntPairList and #decisionEntityRecord.dynamicIntPairList > 1 then for i,pair in ipairs(decisionEntityRecord.dynamicIntPairList) do if self:GetSkillIndexByKey(pair.key, entity) == index then table.remove(decisionEntityRecord.dynamicIntPairList, i) decisionEntityRecord.dynamicWeightSum = decisionEntityRecord.dynamicWeightSum - pair.value break end end else decisionEntityRecord.dynamicIntPairList = decisionEntityRecord.dynamicIntPairList or {} decisionEntityRecord.dynamicIntPairList[1] = nil --删掉可能存在的最后一个元素 decisionEntityRecord.dynamicWeightSum = 0 for i,pairFromData in ipairs(decisionData.intPairList) do if self:GetSkillIndexByKey(pairFromData.key, entity) ~= index then table.insert(decisionEntityRecord.dynamicIntPairList, pairFromData) decisionEntityRecord.dynamicWeightSum = decisionEntityRecord.dynamicWeightSum + pairFromData.value end end entity.components.aiBase:SetEntityRecord(decisionData.ID, decisionEntityRecord) end entity.components.aiBase:SetEntityRecord(decisionData.ID, decisionEntityRecord) end return skillData.BelongTo == skillBaseComponent.CurSkillData.BelongTo end else logging.error(LTAG.ERROR, "HYW : Decision Record数据异常, @Decision_UseRandomSkill Decision_UseRandomSkill:CanExit") return true end else return true end end return false end --[[ 进入该Decision --]] function Decision_UseRandomSkill:DecisionIn(entity, decisionData) Base.DecisionIn(self,entity, decisionData) if decisionData.IntParam2 == 0 then return end local pos = FP.newV2(decisionData.IntParam3 / 10,decisionData.IntParam4 / 10) SystemManager.OnSetSkillAimPos(entity, pos) SystemManager.SetSkillMissilePos(entity, pos) end --[[ 退出该Decision --]] function Decision_UseRandomSkill:DecisionOut(entity, decisionData) Base.DecisionOut(self,entity, decisionData) if decisionData.IntParam2 == 0 then return end SystemManager.OnSetSkillAimPos(entity, nil) SystemManager.SetSkillMissilePos(entity, nil) end --[[ 输出指令 --]] local temp_v2 = FP.newV2(0,0) function Decision_UseRandomSkill:SetCommand(entity, decisionData, command) if decisionData.IntParam1 == 1 then if self:ShouldBlockAI() then return command end end local skillData = entity.components.aiBase:GetDecisionRecord(decisionData, "skillData") local index = self:GetSkillIndexRecord(entity,decisionData) if index then --↓下面这段代码是为了修复太史慈使用Decision_UseRandomSkill释放蓄力技会出现永久蹲的问题而增加的 --因为太史慈蓄力技第二段的持续时间为无限长,所以需要做特殊处理才能让太史慈顺畅释放技能而不卡住 if entity:IsHero() then --这个IsHero是不必要的,但是下面这段新增代码影响的AI太多了,所以就加一个限制仅为Hero,减少测试范围 local curSkillData = entity.components.skillBase.CurSkillData if curSkillData then if skillData and curSkillData.ID ~= skillData.ID and curSkillData.BelongTo == skillData.ID then if curSkillData.AutoNextConditionStr == "pointerUp" then if curSkillData.Type == LuaConst.SkillType.Serial and curSkillData.ParamInt1 >= 1 then local nexSerialSkill = entity:GetSkillData(curSkillData.ParamInt1) if nexSerialSkill.Type == LuaConst.SkillType.Serial then index = entity.components.skillBase:GetSkillIndexBySkillID(curSkillData.BelongTo)---- 为了马超蓄力技能能释放最大段数 else index = entity.components.skillBase:GetSkillIndexBySkillID(curSkillData.ParamInt1) end else index = entity.components.skillBase:GetSkillIndexBySkillID(curSkillData.AutoNextID) end end end end end --↑↑↑↑↑↑↑ if skillData and #skillData.SubSkills > 0 then command.SpecialCommand = LuaConst.SpecialCommandType.SubSkillIndex1 end command.SkillIndex = index local target = entity.components.target.Target if target then local skillJoystickData = entity.components.skillBase:GetSkillJoystickData(skillData.ID) if skillJoystickData and SkillMissileSystem.GetJoystickCtrlMissileType(skillJoystickData) then temp_v2:Reset(target:GetLogicPos()) entity.components.aiBase:SetAISkillJoystickPos(temp_v2) end end else logging.error(LTAG.ERROR, "HYW : Decision Record数据异常, @Decision_UseRandomSkill Decision_UseRandomSkill:SetCommand decisionData.ID : ", decisionData.ID) end return command end return Decision_UseRandomSkill