755 lines
26 KiB
Plaintext
755 lines
26 KiB
Plaintext
AutoBattle = class("AutoBattle")
|
|
|
|
-- static method begin
|
|
-- function AutoBattle.SortTargetList(rolePosition, roleList)
|
|
-- local rolePositionXZ = Vector2(rolePosition.x, rolePosition.z)
|
|
-- local time = Time.time
|
|
-- if nil ~= AutoBattle.currentCreature then
|
|
-- AutoBattle.currentCreature:RemoveInvalidHatred()
|
|
-- end
|
|
-- LuaUtils.SortRoleList(roleList, function(role1, role2)
|
|
-- local creature1 = role1.data.custom
|
|
-- local creature2 = role2.data.custom
|
|
-- if nil ~= AutoBattle.currentCreature then
|
|
-- if AutoBattle.currentCreature:CheckHatred(creature1.id, time) then
|
|
-- return -1
|
|
-- end
|
|
-- if AutoBattle.currentCreature:CheckHatred(creature2.id, time) then
|
|
-- return 1
|
|
-- end
|
|
-- end
|
|
-- if nil ~= creature1 and nil ~= creature2 then
|
|
-- -- Full HP First
|
|
-- local maxHP1 = creature1.props.MaxHp:GetValue()
|
|
-- local HP1 = creature1.props.Hp:GetValue()
|
|
|
|
-- local maxHP2 = creature2.props.MaxHp:GetValue()
|
|
-- local HP2 = creature2.props.Hp:GetValue()
|
|
|
|
-- if HP1 == maxHP1 and HP2 ~= maxHP2 then
|
|
-- return -1
|
|
-- elseif HP1 ~= maxHP1 and HP2 == maxHP2 then
|
|
-- return 1
|
|
-- end
|
|
-- end
|
|
-- local p1 = role1.position
|
|
-- local p2 = role2.position
|
|
-- local d1 = Vector2.Distance(rolePositionXZ, Vector2(p1.x, p1.z))
|
|
-- local d2 = Vector2.Distance(rolePositionXZ, Vector2(p2.x, p2.z))
|
|
-- if d1 < d2 then
|
|
-- return -1
|
|
-- end
|
|
-- return 1
|
|
-- end)
|
|
-- end
|
|
-- static method end
|
|
|
|
local tempCreatureArray = {}
|
|
|
|
AutoBattle.SearchRandomDistance = 5
|
|
|
|
AutoBattle.currentCreature = nil
|
|
AutoBattle.searchPosition = nil
|
|
AutoBattle.searchRange = nil
|
|
AutoBattle.randomTarget = nil
|
|
AutoBattle.hatredTarget = nil
|
|
AutoBattle.hatredMinDistance = 999999999
|
|
|
|
local function TargetFilter(targetCreature, searchTargetArgs)
|
|
if nil ~= targetCreature.data and targetCreature.data:NoAutoAttack() then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
AutoBattle.TargetFilter = TargetFilter
|
|
|
|
local function SearchRandomTarget(targetCreature, skillInfo)
|
|
local dist = VectorUtility.DistanceXZ(AutoBattle.searchPosition, targetCreature:GetPosition())
|
|
if nil ~= AutoBattle.searchRange and dist > AutoBattle.searchRange then
|
|
return false
|
|
end
|
|
if AutoBattle.SearchRandomDistance > dist
|
|
and TargetFilter(targetCreature)
|
|
and skillInfo:CheckTarget(AutoBattle.currentCreature, targetCreature) then
|
|
AutoBattle.randomTarget = targetCreature
|
|
-- LogUtility.InfoFormat("<color=yellow>SearchRandomTarget: </color>{0}",
|
|
-- targetCreature.data:GetName())
|
|
return RandomUtil.Range(1, 10) < 5
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function SearchHatredTarget(targetCreature, hatredTime, skillInfo)
|
|
if TargetFilter(targetCreature)
|
|
and skillInfo:CheckTarget(AutoBattle.currentCreature, targetCreature) then
|
|
local dist = VectorUtility.DistanceXZ(AutoBattle.searchPosition, targetCreature:GetPosition())
|
|
if nil ~= AutoBattle.searchRange and dist > AutoBattle.searchRange then
|
|
return false
|
|
end
|
|
if AutoBattle.hatredMinDistance > dist then
|
|
AutoBattle.hatredTarget = targetCreature
|
|
AutoBattle.hatredMinDistance = dist
|
|
-- LogUtility.InfoFormat("<color=yellow>SearchHatredTarget: </color>{0}, {1}",
|
|
-- targetCreature.data:GetName(), dist)
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function AutoBattle.SeartTarget(creature, skillInfo)
|
|
local teamFirst = skillInfo:TeamFirst(creature)
|
|
|
|
local lockedTarget = creature:GetLockTarget()
|
|
if nil ~= lockedTarget then
|
|
if not teamFirst or lockedTarget:IsInMyTeam() then
|
|
if skillInfo:CheckTarget(creature, lockedTarget)
|
|
and TargetFilter(creature, nil) then
|
|
return lockedTarget
|
|
end
|
|
end
|
|
end
|
|
|
|
local searchRange = 40
|
|
if creature:IsAutoBattleStanding() then
|
|
searchRange = skillInfo:GetLaunchRange(creature)
|
|
AutoBattle.searchRange = searchRange
|
|
end
|
|
|
|
if not teamFirst then
|
|
AutoBattle.currentCreature = creature
|
|
AutoBattle.searchPosition = creature:GetPosition()
|
|
AutoBattle.randomTarget = nil
|
|
SceneCreatureProxy.ForEachCreature(SearchRandomTarget, skillInfo)
|
|
AutoBattle.currentCreature = nil
|
|
AutoBattle.searchPosition = nil
|
|
AutoBattle.searchRange = nil
|
|
if nil ~= AutoBattle.randomTarget then
|
|
local targetCreature = AutoBattle.randomTarget
|
|
AutoBattle.randomTarget = nil
|
|
return targetCreature
|
|
end
|
|
end
|
|
|
|
local sortComparator = teamFirst
|
|
and SkillLogic_Base.SortComparator_TeamFirstDistance
|
|
or SkillLogic_Base.SortComparator_Distance
|
|
SkillLogic_Base.SearchTargetInRange(
|
|
tempCreatureArray,
|
|
creature:GetPosition(),
|
|
searchRange,
|
|
skillInfo,
|
|
creature,
|
|
TargetFilter,
|
|
sortComparator)
|
|
local targetCreature = tempCreatureArray[1]
|
|
TableUtility.ArrayClear(tempCreatureArray)
|
|
return targetCreature
|
|
end
|
|
|
|
function AutoBattle:ctor()
|
|
-- self.skillTargetFilter = function(role)
|
|
-- local creature = role.data.custom
|
|
-- if nil == creature then
|
|
-- return true
|
|
-- end
|
|
-- local detailedType = creature:GetDetailedType()
|
|
-- if nil == detailedType then
|
|
-- return true
|
|
-- end
|
|
-- if LNpc.NpcDetailedType.MINI ~= detailedType
|
|
-- and LNpc.NpcDetailedType.MVP ~= detailedType then
|
|
-- return true
|
|
-- end
|
|
|
|
-- return false
|
|
-- end
|
|
self:Reset()
|
|
end
|
|
|
|
function AutoBattle:Reset()
|
|
self.skillIndex = nil
|
|
if nil ~= self.skillStatus then
|
|
TableUtility.TableClear(self.skillStatus)
|
|
else
|
|
self.skillStatus = {}
|
|
end
|
|
end
|
|
|
|
function AutoBattle:Update(creature, skillFilter, onlyNoTargetAutoCast, allowResearch)
|
|
self:Attack(creature, nil, skillFilter, onlyNoTargetAutoCast, allowResearch)
|
|
end
|
|
|
|
function AutoBattle:Attack(creature, targetCreature, skillFilter, onlyNoTargetAutoCast, allowResearch)
|
|
local creaturePosition = creature:GetPosition()
|
|
if nil == creaturePosition then
|
|
return false
|
|
end
|
|
|
|
if creature.data:NoAttack() then
|
|
return false
|
|
end
|
|
|
|
local ret, skillIDAndLevel, noTarget, forceLockCreature, skillInfo = self:Attack_Step1(
|
|
creature,
|
|
skillFilter,
|
|
onlyNoTargetAutoCast)
|
|
if not ret then
|
|
return false
|
|
end
|
|
-- LogUtility.InfoFormat("<color=green>AutoBattle selected: </color>{0}, {1}",
|
|
-- skillIDAndLevel, noTarget)
|
|
|
|
return self:Attack_Step2(
|
|
creature,
|
|
targetCreature,
|
|
skillIDAndLevel,
|
|
noTarget,
|
|
forceLockCreature,
|
|
skillInfo,
|
|
onlyNoTargetAutoCast,
|
|
allowResearch)
|
|
end
|
|
|
|
function AutoBattle:Attack_Step1(creature, skillFilter, onlyNoTargetAutoCast)
|
|
local skillIDAndLevel, noTarget, forceLockCreature = self:SelectSkill(creature, skillFilter, onlyNoTargetAutoCast)
|
|
if nil == skillIDAndLevel then
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
return true, skillIDAndLevel, noTarget, forceLockCreature, skillInfo
|
|
end
|
|
|
|
function AutoBattle:Attack_Step2(creature, targetCreature, skillIDAndLevel, noTarget, forceLockCreature, skillInfo, onlyNoTargetAutoCast, allowResearch)
|
|
local noSearch = false
|
|
-- if onlyNoTargetAutoCast or (not noTarget and nil ~= targetCreature) then
|
|
if onlyNoTargetAutoCast or nil ~= targetCreature then
|
|
noSearch = true
|
|
end
|
|
if nil == forceLockCreature then
|
|
forceLockCreature = targetCreature
|
|
-- hatred first
|
|
local hatredFirst = creature:IsAutoBattleProtectingTeam()
|
|
if hatredFirst and skillInfo:TargetEnemy(creature) then
|
|
-- hatred first
|
|
AutoBattle.currentCreature = creature
|
|
AutoBattle.searchPosition = creature:GetPosition()
|
|
AutoBattle.searchRange = creature:IsAutoBattleStanding() and skillInfo:GetLaunchRange(creature) or nil
|
|
AutoBattle.hatredTarget = nil
|
|
AutoBattle.hatredMinDistance = 999999999
|
|
Game.LogicManager_Hatred:ForEach(SearchHatredTarget, skillInfo)
|
|
AutoBattle.currentCreature = nil
|
|
AutoBattle.searchPosition = nil
|
|
AutoBattle.searchRange = nil
|
|
AutoBattle.hatredMinDistance = 999999999
|
|
if nil ~= AutoBattle.hatredTarget then
|
|
forceLockCreature = AutoBattle.hatredTarget
|
|
AutoBattle.hatredTarget = nil
|
|
noSearch = true
|
|
end
|
|
end
|
|
end
|
|
|
|
local forceTargetCreature = false
|
|
local targetPosition = nil
|
|
|
|
local skillTargetType = skillInfo:GetTargetType(creature)
|
|
if SkillTargetType.Point == skillTargetType then
|
|
if noTarget and nil == forceLockCreature then
|
|
targetPosition = creature:GetPosition()
|
|
else
|
|
forceTargetCreature = true
|
|
end
|
|
elseif (SkillTargetType.None == skillTargetType and not noTarget) then
|
|
forceTargetCreature = true
|
|
end
|
|
|
|
if forceTargetCreature and nil == forceLockCreature then
|
|
if noSearch then
|
|
return false
|
|
end
|
|
forceLockCreature = AutoBattle.SeartTarget(creature, skillInfo)
|
|
if nil == forceLockCreature then
|
|
-- LogUtility.InfoFormat("<color=yellow>AutoBattle No Target Creature: </color>{0}",
|
|
-- skillIDAndLevel)
|
|
return false
|
|
end
|
|
end
|
|
|
|
if nil ~= forceLockCreature
|
|
and (SkillTargetType.Creature == skillTargetType or forceTargetCreature)
|
|
and noSearch
|
|
and forceLockCreature == targetCreature
|
|
and not skillInfo:CheckTarget(creature, forceLockCreature) then
|
|
return false
|
|
end
|
|
|
|
-- LogUtility.InfoFormat("<color=green>AutoBattle Use Skill: </color>{0}, {1}, {2}",
|
|
-- skillIDAndLevel,
|
|
-- forceLockCreature and forceLockCreature.data:GetName() or "NoTarget",
|
|
-- noSearch)
|
|
|
|
if nil == targetPosition and nil ~= forceLockCreature then
|
|
targetPosition = forceLockCreature:GetPosition()
|
|
end
|
|
|
|
creature:Client_UseSkill(
|
|
skillIDAndLevel,
|
|
forceLockCreature,
|
|
targetPosition,
|
|
forceTargetCreature,
|
|
noSearch,
|
|
TargetFilter,
|
|
allowResearch)
|
|
|
|
local skillStatus = self.skillStatus[skillIDAndLevel]
|
|
if nil == skillStatus then
|
|
skillStatus = {}
|
|
self.skillStatus[skillIDAndLevel] = skillStatus
|
|
end
|
|
skillStatus.lastLaunchTime = Time.time
|
|
return true
|
|
end
|
|
|
|
function AutoBattle:SelectSkill(creature, filter, onlyNoTargetAutoCast)
|
|
local skillProxy = SkillProxy.Instance
|
|
if nil ~= skillProxy then
|
|
local skillItems = skillProxy:GetAutoBattleSkillsWithCombo()
|
|
local startIndex = 1
|
|
if nil ~= self.skillIndex then
|
|
startIndex = self.skillIndex + 1
|
|
-- LogUtility.InfoFormat("<color=yellow>SelectSkill: </color>startIndex={0}", startIndex)
|
|
end
|
|
-- print ("<color=blue>AutoBattle SelectSkill: </color>startIndex="..startIndex)
|
|
local skillItem, skillIndex, noTarget, forceLockCreature = self:LoopGetValidSkill(creature, skillItems, startIndex, filter, onlyNoTargetAutoCast)
|
|
if nil ~= skillItem then
|
|
-- LogUtility.InfoFormat("<color=blue>AutoBattle SelectSkill: </color>selectedIndex={0}", skillIndex)
|
|
if nil ~= skillIndex then
|
|
self.skillIndex = skillIndex
|
|
end
|
|
return skillItem:GetID(), noTarget, forceLockCreature
|
|
end
|
|
end
|
|
|
|
-- 2016.3.31. remove default attack
|
|
-- local attackSkillIDAndLevel = AutoBattle.GetAttackSkillIDAndLevel(role)
|
|
-- if nil == filter or filter(attackSkillIDAndLevel) then
|
|
-- return attackSkillIDAndLevel
|
|
-- end
|
|
return nil
|
|
end
|
|
|
|
function AutoBattle:IsSkillAutoBattleValid(creature, originalSkillIDAndLevel, skillIDAndLevel ,autoBattleParams)
|
|
local forceLockCreature = nil
|
|
if nil ~= autoBattleParams then
|
|
if 1 == autoBattleParams.type then
|
|
local skillStatus = self.skillStatus[originalSkillIDAndLevel]
|
|
if nil ~= skillStatus
|
|
and nil ~= skillStatus.lastLaunchTime
|
|
and Time.time < (skillStatus.lastLaunchTime+autoBattleParams.time) then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=1, time limit={1}, rest time={2}",
|
|
-- skillIDAndLevel,
|
|
-- autoBattleParams.time,
|
|
-- skillStatus.lastLaunchTime+autoBattleParams.time - Time.time)
|
|
return false
|
|
end
|
|
elseif 2 == autoBattleParams.type then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=2", skillIDAndLevel)
|
|
return false
|
|
elseif 3 == autoBattleParams.type then
|
|
local props = creature.data.props
|
|
if nil ~= props then
|
|
local maxHP = props.MaxHp:GetValue()
|
|
local HP = props.Hp:GetValue()
|
|
if HP >= autoBattleParams.value/100.0*maxHP then
|
|
-- print(string.format("<color=yellow>IsSkillAutoBattleValid: </color>skill=%d, type=3", skillIDAndLevel))
|
|
return false
|
|
end
|
|
end
|
|
elseif 5 == autoBattleParams.type then
|
|
local myTeam = TeamProxy.Instance.myTeam
|
|
if nil == myTeam then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=5, 1", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local members = myTeam:GetMembersList()
|
|
if nil == members then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=5, 2", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local skillLaunchRange = skillInfo:GetLaunchRange(creature)
|
|
local rolePosition = creature:GetPosition()
|
|
local minHPPercent = 1
|
|
local minHPCreature = nil
|
|
for i=1, #members do
|
|
local m = members[i]
|
|
local memberCreature = SceneCreatureProxy.FindCreature(m.id)
|
|
if nil ~= memberCreature and not memberCreature:IsDead() then
|
|
local targetNoBuffId = autoBattleParams.target_noBuff
|
|
local targetHasNoBuff = true
|
|
if targetNoBuffId ~= nil then
|
|
targetHasNoBuff = not memberCreature.data:HasBuffID(targetNoBuffId)
|
|
end
|
|
-- member must be around me
|
|
if targetHasNoBuff and not (VectorUtility.DistanceXZ(rolePosition, memberCreature:GetPosition()) > skillLaunchRange)
|
|
and nil ~= m.hpmax and nil ~= m.hp then
|
|
local maxHP = m.hpmax
|
|
local HP = m.hp
|
|
local HPPercent = HP / maxHP
|
|
if (nil == minHPCreature or HPPercent < minHPPercent)
|
|
and skillInfo:CheckTarget(creature, memberCreature) then
|
|
minHPPercent = HPPercent
|
|
minHPCreature = memberCreature
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if nil == minHPCreature
|
|
or minHPPercent >= autoBattleParams.teamvalue/100.0 then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=5, 3", skillIDAndLevel)
|
|
return false
|
|
end
|
|
|
|
forceLockCreature = minHPCreature
|
|
elseif 7 == autoBattleParams.type then
|
|
local myTeam = TeamProxy.Instance.myTeam
|
|
if nil == myTeam then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=7, 1", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local members = myTeam:GetMembersList()
|
|
if nil == members then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=7, 2", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local buffs = skillInfo:GetTeamBuffs(creature)
|
|
if nil == buffs or 0 >= #buffs then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=7, 3", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local onlyLockTarget = nil
|
|
if 1 == autoBattleParams.only_lock_target then
|
|
onlyLockTarget = creature:GetLockTarget()
|
|
end
|
|
|
|
local skillLaunchRange = skillInfo:GetLaunchRange(creature)
|
|
local rolePosition = creature:GetPosition()
|
|
for i=1, #members do
|
|
local m = members[i]
|
|
local memberCreature = SceneCreatureProxy.FindCreature(m.id)
|
|
if nil ~= memberCreature and not memberCreature:IsDead() then
|
|
-- member must be around me
|
|
if not (VectorUtility.DistanceXZ(rolePosition, memberCreature:GetPosition()) > skillLaunchRange)
|
|
and not memberCreature:HasBuffs(buffs)
|
|
and skillInfo:CheckTarget(creature, memberCreature)
|
|
and (nil == onlyLockTarget or onlyLockTarget == memberCreature) then
|
|
forceLockCreature = memberCreature
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if nil == forceLockCreature then
|
|
return false
|
|
end
|
|
elseif 8 == autoBattleParams.type then
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local buffs = skillInfo:GetSelfBuffs(creature)
|
|
if nil == buffs or 0 >= #buffs then
|
|
return false
|
|
end
|
|
if creature:HasBuffs(buffs) then
|
|
return false
|
|
end
|
|
elseif 9 == autoBattleParams.type then
|
|
local myTeam = TeamProxy.Instance.myTeam
|
|
if nil == myTeam then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=9, 1", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local members = myTeam:GetMembersList()
|
|
if nil == members then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=9, 2", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local buffStateEffects = autoBattleParams.state_effect
|
|
if nil == buffStateEffects or 0 >= #buffStateEffects then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=9, 3", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local skillLaunchRange = skillInfo:GetLaunchRange(creature)
|
|
local rolePosition = creature:GetPosition()
|
|
for i=1, #members do
|
|
local m = members[i]
|
|
local memberCreature = SceneCreatureProxy.FindCreature(m.id)
|
|
if nil ~= memberCreature and not memberCreature:IsDead() then
|
|
-- member must be around me
|
|
if not (VectorUtility.DistanceXZ(rolePosition, memberCreature:GetPosition()) > skillLaunchRange)
|
|
and memberCreature:HasBuffStates(buffStateEffects)
|
|
and skillInfo:CheckTarget(creature, memberCreature) then
|
|
forceLockCreature = memberCreature
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if nil == forceLockCreature then
|
|
return false
|
|
end
|
|
elseif 10 == autoBattleParams.type then
|
|
local myTeam = TeamProxy.Instance.myTeam
|
|
if nil == myTeam then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=10, 1", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local members = myTeam:GetMembersList()
|
|
if nil == members then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=10, 2", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local skillLaunchRange = skillInfo:GetLaunchRange(creature)
|
|
local rolePosition = creature:GetPosition()
|
|
for i=1, #members do
|
|
local m = members[i]
|
|
local memberCreature = SceneCreatureProxy.FindCreature(m.id)
|
|
if nil ~= memberCreature and memberCreature:IsDead()
|
|
and not (VectorUtility.DistanceXZ(rolePosition, memberCreature:GetPosition()) > skillLaunchRange)
|
|
and skillInfo:CheckTarget(creature, memberCreature) then
|
|
-- member must be around me
|
|
forceLockCreature = memberCreature
|
|
break
|
|
end
|
|
end
|
|
if nil == forceLockCreature then
|
|
return false
|
|
end
|
|
elseif 11 == autoBattleParams.type then
|
|
local props = creature.data.props
|
|
if nil ~= props then
|
|
local maxHP = props.MaxHp:GetValue()
|
|
local HP = props.Hp:GetValue()
|
|
if HP <= autoBattleParams.value/100.0*maxHP then
|
|
-- print(string.format("<color=yellow>IsSkillAutoBattleValid: </color>skill=%d, type=11", skillIDAndLevel))
|
|
return false
|
|
end
|
|
end
|
|
elseif 12 == autoBattleParams.type then
|
|
if creature:HasBuff(autoBattleParams.buffid)
|
|
and creature:GetBuffLayer(autoBattleParams.buffid) >= autoBattleParams.num then
|
|
return false
|
|
end
|
|
elseif 13 == autoBattleParams.type then
|
|
local myTeam = TeamProxy.Instance.myTeam
|
|
if nil == myTeam then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=7, 1", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local members = myTeam:GetMembersList()
|
|
if nil == members then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type=7, 2", skillIDAndLevel)
|
|
return false
|
|
end
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
local onlyLockTarget = nil
|
|
if 1 == autoBattleParams.only_lock_target then
|
|
onlyLockTarget = creature:GetLockTarget()
|
|
end
|
|
|
|
local skillLaunchRange = skillInfo:GetLaunchRange(creature)
|
|
local rolePosition = creature:GetPosition()
|
|
for i=1, #members do
|
|
local m = members[i]
|
|
local memberCreature = SceneCreatureProxy.FindCreature(m.id)
|
|
if nil ~= memberCreature and not memberCreature:IsDead() then
|
|
-- member must be around me
|
|
if not (VectorUtility.DistanceXZ(rolePosition, memberCreature:GetPosition()) > skillLaunchRange)
|
|
and memberCreature:GetBuffLayer(autoBattleParams.buffid) < autoBattleParams.num
|
|
and skillInfo:CheckTarget(creature, memberCreature)
|
|
and (nil == onlyLockTarget or onlyLockTarget == memberCreature) then
|
|
forceLockCreature = memberCreature
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if nil == forceLockCreature then
|
|
return false
|
|
end
|
|
--備戰精英
|
|
elseif 99 == autoBattleParams.type then
|
|
local combatEliteValid = self:IsCombatEliteValid(creature, skillIDAndLevel);
|
|
if combatEliteValid ~= true then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillAutoBattleValid: </color>skill={0}, type={1}, {2}", skillIDAndLevel, autoBattleParams and autoBattleParams.type or -1, forceLockCreature and forceLockCreature.name or "nil")
|
|
return true, forceLockCreature
|
|
end
|
|
|
|
function AutoBattle:IsCombatEliteValid(creature, skillIDAndLevel)
|
|
local skills = SkillProxy.Instance.GetCombatEliteOptionSkills();
|
|
local combatEliteValid = false;
|
|
|
|
for i=1,#skills do
|
|
local skillData = skills[i];
|
|
|
|
local autoBattleValid = false
|
|
for i=1, #skillData.AutoCondition do
|
|
local p = skillData.AutoCondition[i]
|
|
local valid, targetCreature = self:IsSkillAutoBattleValid(creature, skillIDAndLevel, skillData.id, p)
|
|
if valid then
|
|
autoBattleValid = true
|
|
break
|
|
end
|
|
end
|
|
if autoBattleValid then
|
|
combatEliteValid = true
|
|
break
|
|
end
|
|
end
|
|
|
|
return combatEliteValid;
|
|
end
|
|
|
|
|
|
function AutoBattle:IsSkillItemValid(creature, skillItem, filter, onlyNoTargetAutoCast)
|
|
if nil == skillItem then
|
|
-- LogUtility.Info("<color=yellow>IsSkillItemValid: </color>skillItem is nil")
|
|
return false
|
|
end
|
|
local skillIDAndLevel = skillItem:GetID()
|
|
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillIDAndLevel)
|
|
|
|
local noTarget = false
|
|
local forceLockCreature = nil
|
|
local autoBattlePriority = 0
|
|
local autoBattleParams = skillInfo:GetAutoCondition(creature)
|
|
if nil ~= autoBattleParams and 0 < #autoBattleParams then
|
|
local autoBattleValid = false
|
|
for i=1, #autoBattleParams do
|
|
local p = autoBattleParams[i]
|
|
local valid, targetCreature = self:IsSkillAutoBattleValid(creature, skillIDAndLevel, skillIDAndLevel, p)
|
|
if valid then
|
|
autoBattleValid = true
|
|
noTarget = (1 == p.no_target)
|
|
forceLockCreature = targetCreature
|
|
if nil ~= p.priority then
|
|
autoBattlePriority = p.priority
|
|
end
|
|
break
|
|
end
|
|
end
|
|
if not autoBattleValid then
|
|
-- LogUtility.Info("<color=yellow>IsSkillItemValid: </color>autoBattleValid=false")
|
|
return false
|
|
end
|
|
end
|
|
if(skillItem:IsAutoShortCutLocked()) then
|
|
return false
|
|
end
|
|
if not SkillProxy.Instance:SkillCanBeUsed(skillItem) then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillItemValid: </color>skill={0}, SkillCanBeUsed=false", skillIDAndLevel)
|
|
return false
|
|
end
|
|
if nil ~= filter and not filter(skillIDAndLevel) then
|
|
-- LogUtility.InfoFormat("<color=yellow>IsSkillItemValid: </color>skill={0}, filter=false", skillIDAndLevel)
|
|
return false
|
|
end
|
|
|
|
if nil == forceLockCreature
|
|
and onlyNoTargetAutoCast
|
|
and not skillInfo:NoTargetAutoCast(creature) then
|
|
return false
|
|
end
|
|
|
|
return true, noTarget, forceLockCreature, autoBattlePriority
|
|
end
|
|
|
|
function AutoBattle:LoopGetValidSkill(creature, skillItems, startIndex, filter, onlyNoTargetAutoCast)
|
|
local attackSkillIDAndLevel = creature.data:GetAttackSkillIDAndLevel()
|
|
local attackSkillItem = nil
|
|
local attackSkillIndex = nil
|
|
local attackSkillNoTarget = false
|
|
local attackSkillForceLockCreature = nil
|
|
|
|
local selectedSkillItem = nil
|
|
local selectedIndex = nil
|
|
local selectedNoTarget = false
|
|
local selectedForceLockCreature = nil
|
|
local selectedPriority = -1
|
|
|
|
if nil ~= skillItems and 0 < #skillItems then
|
|
local skillItemCount = #skillItems
|
|
if startIndex <= skillItemCount then
|
|
for i = startIndex, skillItemCount do
|
|
local skillItem = skillItems[i]
|
|
local skillID = skillItem:GetID()
|
|
local valid, noTarget, forceLockCreature, priority = self:IsSkillItemValid(creature, skillItem, filter, onlyNoTargetAutoCast)
|
|
-- LogUtility.InfoFormat("<color>Try Select Skill(in {0}): </color>{1}{2}",
|
|
-- skillItemCount,
|
|
-- LogUtility.StringFormat("i={0},valid={1},noTarget={2},",i,valid,noTarget),
|
|
-- LogUtility.StringFormat("forceLockCreature={0},priority={1}",forceLockCreature,priority))
|
|
if valid then
|
|
if attackSkillIDAndLevel ~= skillID then
|
|
if not creature.data:NoSkill() then
|
|
if selectedPriority < priority then
|
|
selectedSkillItem = skillItem
|
|
selectedIndex = i
|
|
selectedNoTarget = noTarget
|
|
selectedForceLockCreature = forceLockCreature
|
|
selectedPriority = priority
|
|
end
|
|
-- return skillItem, i, noTarget, forceLockCreature
|
|
end
|
|
else
|
|
attackSkillItem = skillItem
|
|
attackSkillIndex = i
|
|
attackSkillNoTarget = noTarget
|
|
attackSkillForceLockCreature = forceLockCreature
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local endIndex = math.min(startIndex, skillItemCount)
|
|
if 0 < endIndex and 1 < startIndex then
|
|
for i = 1, endIndex do
|
|
local skillItem = skillItems[i]
|
|
local skillID = skillItem:GetID()
|
|
local valid, noTarget, forceLockCreature, priority = self:IsSkillItemValid(creature, skillItem, filter, onlyNoTargetAutoCast)
|
|
-- LogUtility.InfoFormat("<color>Try Select Skill(in {0}): </color>{1}{2}",
|
|
-- skillItemCount,
|
|
-- LogUtility.StringFormat("i={0},valid={1},noTarget={2},",i,valid,noTarget),
|
|
-- LogUtility.StringFormat("forceLockCreature={0},priority={1}",forceLockCreature,priority))
|
|
if valid then
|
|
if attackSkillIDAndLevel ~= skillID then
|
|
if not creature.data:NoSkill() then
|
|
if selectedPriority < priority then
|
|
selectedSkillItem = skillItem
|
|
selectedIndex = i
|
|
selectedNoTarget = noTarget
|
|
selectedForceLockCreature = forceLockCreature
|
|
selectedPriority = priority
|
|
end
|
|
-- return skillItem, i, noTarget, forceLockCreature
|
|
end
|
|
else
|
|
attackSkillItem = skillItem
|
|
attackSkillIndex = i
|
|
attackSkillNoTarget = noTarget
|
|
attackSkillForceLockCreature = forceLockCreature
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if nil ~= selectedSkillItem then
|
|
return selectedSkillItem, selectedIndex, selectedNoTarget, selectedForceLockCreature
|
|
end
|
|
|
|
-- return attackSkillItem, attackSkillIndex, attackSkillNoTarget, forceLockCreature
|
|
return attackSkillItem, nil, attackSkillNoTarget, forceLockCreature
|
|
end
|