local CombatImpl = require("combat.CombatImpl")
local TargetMode = require("combat.TargetMode")
local CombatCalc = require("combat.CombatCalc")
local CombatObj = require("combat.CombatObj")
local RoleDefine = require("role.RoleDefine")
local CombatBuff = require("combat.CombatBuff")
local CombatDefine = require("combat.CombatDefine")
local BeSkill = require("combat.BeSkill")
local Util = require("common.Util")
local SkillExcel = require("excel.skill").skill
local CmdExcel = require("excel.skill").cmd
local ProjectLogic = require("platform.ProjectLogic")
-- local BufferExcel = require("excel.buffer")
local weaponSkillConfig = require("excel.weapon").skill


local function calcHp(attacker,target,calcType,rate,limit,isAddHp,param, flag)
	local hp = CombatCalc.calcHp(attacker,target,calcType,rate, isAddHp, flag)
	if param and param.targetCnt then
		hp = hp / param.targetCnt
	end
	if limit then
		if hp > limit then
			hp = limit
		end
	end
	return hp
end


function GetSkillConfig(skillId)
	return weaponSkillConfig[skillId] or SkillExcel[skillId]
end

--如果该技能属于专属武器加强的技能, 则用专属武器配置表中的配置
function GetFinalSkillConfig(obj, skillId)
	local targetId = skillId
	if obj and obj.weaponEffectIdList and obj.weaponEffectIdList[skillId] then
		targetId = obj.weaponEffectIdList[skillId]
	end

	return GetSkillConfig(targetId)
end

-- 技能释放条件检测表
COND_CMD = {}

-- 技能释放代价表
COST_CMD = {}


-- 技能释放条件检查
function COND_CMD.attrCheck(obj, skillId)
	local skillConfig = GetSkillConfig(skillId)
	local skillCond = skillConfig.cond

	local attrType = skillCond[2]
	local attrCondVal = skillCond[3] * 100
	local nowAttrVal = CombatObj.getValue(obj, attrType)

	if nowAttrVal <= attrCondVal then
		return false
	end

	return true
end

-- 扣除技能释放的消耗, 暂时写死，胡须再看看怎么优化
function COST_CMD.attrCheck(obj, skillConfig)
	local skillCond = skillConfig.cond
	local rate = skillCond[3] * 100

	local hurt = calcHp(obj, {}, 2, rate)

	if hurt ~= 0 then
		local d = CombatObj.updateHp(obj,-hurt,nil,true, obj.pos,CombatObj.SKILL_HP_TYPE)
		if d ~= 0 then
			CombatImpl.setExtraHit(obj,-hurt,CMD2ID["hurt"])
			CombatObj.onHpCB(obj, d, obj.pos)
		end
	end
end

-- 技能释放条件检测
function SkillCondCheck(obj, skillId)
	local skillConfig = GetSkillConfig(skillId)
	local skillCond = skillConfig.cond

	if not skillCond or not next(skillCond) then
		return true
	end

	if COND_CMD[skillCond[1]] then
		return COND_CMD[skillCond[1]](obj, skillId)
	end

	return false
end


-- 等释放技能完后的处理
function ExtraHandle(obj, args)
	if not args then
		return
	end

	local hanleType = args[1]
	if hanleType == 1 then
		CombatBuff.AddHPByXishouBuff(obj, args[2], -args[3])
	elseif hanleType == 2 then
		CombatBuff.DelBuffByCmd(obj, args[2], 1)
	end
end


function setSkill(obj,config,skinConfig)
	config = skinConfig or config	
	local skillList = {}
	local skillConfig
	local normalAtkID = config.normalAtkID
	local temp = {}
	--普通技能
	if normalAtkID then
		--skillConfig = SkillExcel[normalAtkID]
		skillConfig = GetFinalSkillConfig(obj, normalAtkID)
		normalAtkID = skillConfig.id

		skillList[#skillList + 1] = {normalAtkID,skillConfig.cd[1] or 0,skillConfig.cd[2] or 0}--skillID,开始使用回合，冷切回合
		temp[normalAtkID] = true
	end

	--主动技能
	for _,skillID in ipairs(config.skillList) do
		--skillConfig = SkillExcel[skillID]
		--使用新的ID
		skillConfig = GetFinalSkillConfig(obj, skillID)
		skillID = skillConfig.id

        if not temp[skillID] and skillConfig and skillConfig.need <= obj.quality then
		   skillList[#skillList + 1] = {skillID,skillConfig.cd[1] or 0,skillConfig.cd[2] or 0}--skillID,开始使用回合，冷切回合
           temp[skillID] = true
        end
	end

	if #skillList > 1 then
		table.sort(skillList,function(a,b)
			return a[3] > b[3]
		end)
	end
	obj.skillList = skillList
end


CMD2ID = {}
function initAfterHot()
	for k,v in pairs(CMD2ID) do
		CMD2ID[k] = nil
	end
	for k,v in pairs(CmdExcel) do
		CMD2ID[v.cmd] = k
	end
end

function getCMD2ID(cmd) 
	return CMD2ID[cmd]
end
GroupSkillCnt = 0--技能包触发技能次数
local function realUse(obj, skillID, fanjiTargets,otherArgs)
	--local skillConfig = SkillExcel[skillID]
	local skillConfig = GetSkillConfig(skillID)
	CombatImpl.nowAttacker	= obj
	if skillConfig  then
        
        --重置部分属性
		CombatCalc.initAttacker(obj)

		local targets = TargetMode.getTargets(obj, skillConfig.targetMode, fanjiTargets, nil, true,skillConfig.type == CombatDefine.SKILL_TYPE1,skillID, true)

		-- local fentanBuffObjs = {}

		local len = #targets
		if len < 1 then return end
        for i=1, len do
           local defobj = targets[i]

		--    if defobj.addByfentan then
        --        fentanBuffObjs[defobj.pos] = defobj.id
        --    end
           CombatCalc.initAttacker(defobj)
        end

		GroupSkillCnt = GroupSkillCnt + 1
        -- 复活技能不走这里
        if skillConfig.cmd ~= "revive" then
		   CombatImpl.addFrame()
		   CombatImpl.setSkillID(obj, skillID)
		   CombatImpl.setSaySkill(obj.pos,skillConfig.id,skillConfig.contentType)
	    end

		attack(obj, targets, skillConfig)
		
		local newTargets = {}
		-- for _, lObj in ipairs(targets) do
		-- 	if not lObj.addByfentan and not fentanBuffObjs[lObj.pos] then
		-- 		newTargets[#newTargets+1] = lObj
		-- 	end
		-- end

		for _, lObj in ipairs(targets) do
			if not lObj.addByfentan then
				newTargets[#newTargets+1] = lObj
			end
		end

		if not fanjiTargets and skillConfig.otherArgs.addBuffBeforeCmd then
			CombatBuff.onHit(obj,newTargets,skillConfig)
		end

		--额外作用
		local cmdTargets, cmdChangeArgs
		if CMD[skillConfig.cmd] then
		   cmdTargets, cmdChangeArgs = CMD[skillConfig.cmd](obj, skillConfig, newTargets)
		end

		if not fanjiTargets then
			if not skillConfig.otherArgs.addBuffBeforeCmd then
				CombatBuff.onHit(obj,newTargets,skillConfig,cmdTargets,otherArgs, cmdChangeArgs)
			end
		end
		BeSkill.onHit(obj,newTargets,skillID)

		if fanjiTargets then
			for _, v in ipairs(fanjiTargets) do
				if true == CombatBuff.isLianjie1(v) then
					CombatBuff.CombatBuff_handleLianjie(v, obj)
				end
			end
		end

		CombatImpl.totalAtkCnt = CombatImpl.totalAtkCnt + 1
	end
	CombatImpl.nowAttacker	= nil
end

function use(obj, skillID, fanjiTargets)
	--local skillConfig = SkillExcel[skillID]
	local skillConfig = GetSkillConfig(skillID)
	GroupSkillCnt = 0
	if skillConfig.type == CombatDefine.SKILL_TYPE5 then
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			--local config = SkillExcel[v]
			local config = GetSkillConfig(v)
			local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
			if #targets > 0 then
				realUse(obj, v,fanjiTargets)
				return
			end
		end
	elseif skillConfig.type == CombatDefine.SKILL_TYPE6 then
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			--local config = SkillExcel[v]
			local config = GetSkillConfig(v)
			local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
			if #targets > 0 then
				realUse(obj, v,fanjiTargets,{noFirst = (k ~= 1)})
			end
		end

		-- 扣除技能消耗
		local skillCond = skillConfig.cond
		if COST_CMD[skillCond[1]] then
			COST_CMD[skillCond[1]](obj, skillConfig)
		end
	elseif skillConfig.type == CombatDefine.SKILL_TYPE7 then
		local r = math.random(1,10000)
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			if r <= v[1] then
				--local config = SkillExcel[v[2]]
				local config = GetSkillConfig(v[2])
				local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
				if #targets > 0 then
					realUse(obj, v[2], fanjiTargets)
				end
				return
			else
				r = r - v[1]
			end
		end 
	else
		realUse(obj, skillID,fanjiTargets)
	end
end

local hitList = {}
local flagList = {}
function attack(obj, targets, skillConfig)
	if not skillConfig.hurtRate[1] then obj.isAllCalcHp = true return end

    local totalHurt = 0 
    local limitHurt = 0
    local fenTanHurt = 0
	-- 分摊技能操作
    if  skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1  then
        for index = 1, #targets do
		   local target = targets[index]
		   if target.hp > 0 then
              local hurt, flag = CombatCalc.calcHurt(obj, index, targets, skillConfig)
			  fenTanHurt = hurt
              limitHurt = CombatObj.getValue(obj,RoleDefine.ATK) * skillConfig.otherArgs.hurtFenTan[2]
              if fenTanHurt >= limitHurt then
                 fenTanHurt = limitHurt
              end
              flagList[index] = flagList[index] or 0
              flagList[index] = flag
           end
        end
    end

    local len = 0
    obj.isAllCalcHp = nil
    if #targets == 0 then
       obj.isAllCalcHp = true
    end

	-- local fentanObjList = {}
	-- for _, obj in ipairs(targets) do
	-- 	if obj.fentq then
	-- 		fentanObjList[obj.pos] = obj.fentq
	-- 	end
	-- end


	for index = 1, #targets do
		local target = targets[index]

		if target.hp > 0 then
			BeSkill.beforeHit(obj,target)

			-- if fentanObjList[target.pos] then
			-- 	target.fentq = fentanObjList[target.pos]
			-- end

            local hurt,flag = nil
            if fenTanHurt == 0 then
			   hurt,flag = CombatCalc.calcHurt(obj, index, targets, skillConfig)
               target.isShanBi = Util.getBit(flag, CombatDefine.FLAG_SHANBI)
            else
               hurt = fenTanHurt 
               flag = flagList[index]
            end

            -- 闪避不处理目标被动技能
            obj.isAllCalcHp = index == #targets
			target.attackSkillID = skillConfig.id
			local hpValue,srcValue = 0,0

			local extraHandleTb
			if hurt > 0 then
				hpValue,srcValue, extraHandleTb = CombatObj.updateHp(target, -hurt,nil,true, obj.pos,CombatObj.SKILL_HP_TYPE)

				if hpValue < 0 and CombatBuff.isStatus(target, {"chenshui"}) then
					CombatBuff.DelBuffByCmd(target, "chenshui", 999)
				end

				CombatObj.onHpCB(target,hpValue,obj.pos,skillConfig.id)
			end

			CombatImpl.setSkillHit(target,srcValue,nil,flag,obj,skillConfig.id)

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end


            if target.isShanBi ~= 1 then
               len = len + 1
               hitList[len] = target
               BeSkill.afterHit(obj,target)

				-- if fentanObjList[target.pos] then
				-- 	target.fentq = fentanObjList[target.pos]
				-- end
            end
			target.attackSkillID = nil
		end
	end

    -- 处理命中列表
    for index = 1, #targets do
       targets[index] = nil
    end

    for index = 1, len do
		targets[index] = hitList[index]
    end
end



CMD = {}
function CMD.hp(obj,skillConfig,skillTargets)
	local ret = {}
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if args[4] and r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3], skillTargets)
	local targetCnt = #targets
	local hp
	local limit
	if args[5] and args[5] > 0 then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	if not obj.isPet and args[6] and args[6] > 0 then
		limit = args[6] * CombatObj.getHpMax(obj) / 10000
	end

	local hpAddRate = CombatObj.getValue(obj,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
	for _,target in ipairs(targets) do
		if not target.bufferCmd["noHp"] then
			hp = calcHp(obj,target,calcType,rate,limit,true)
			hp = hp * (1 + hpAddRate)
			hp = hp < 0 and 1 or hp

            if hp > 0 and obj.isAllCalcHp == true then
                if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end

				local restoreMul = BeSkill.GetBeSkillRestoretHPMul(target) or 1
				hp = hp * restoreMul

				local d, _, extraHandleTb = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                local showHp = hp
                if hp > 0 and d < 0 then
                   showHp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, showHp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
            end 

			if hp < 0 then
				if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                if hp > 0 and d < 0 then
                   hp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, hp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)
			end
			ret[#ret+1] = target
		end
	end
	return ret
end


function CMD.shixueHP(obj,skillConfig,skillTargets, hitObj)
	local ret = {}
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if args[4] and r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3], skillTargets)
	local hp
	local limit
	if args[5] and args[5] > 0 then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	if not obj.isPet and args[6] and args[6] > 0 then
		limit = args[6] * CombatObj.getHpMax(obj) / 10000
	end

	local targetBuffInfo
	local res, _, buffIdx = CombatBuff.isStatus(obj, {"noShixue"})

	local bl = true
	if res and buffIdx then
		local objBuffList = CombatBuff.getBuffer(obj)
		targetBuffInfo = objBuffList[buffIdx]

		if hitObj and targetBuffInfo and targetBuffInfo.attackPos == hitObj.pos then
			bl = false
		end
	end

	local hpAddRate = CombatObj.getValue(obj,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
	for _,target in ipairs(targets) do
		if not target.bufferCmd["noHp"] and bl then
			hp = calcHp(obj,target,calcType,rate,limit,true)
			hp = hp * (1 + hpAddRate)
			hp = hp < 0 and 1 or hp

            if hp > 0 and obj.isAllCalcHp == true then
                if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                local showHp = hp
                if hp > 0 and d < 0 then
                   showHp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, showHp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)
            end 

			if hp < 0 then
				if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d, _, extraHandleTb = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                if hp > 0 and d < 0 then
                   hp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, hp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
			ret[#ret+1] = target
		end
	end
	return ret
end

function CMD.speedHp(obj,skillConfig,skillTargets)
	if not (skillTargets and skillTargets[1]) then
		return
	end
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if args[4] and r > args[4] then 
		return
	end
	
	local calcType = args[1]
	local rate = args[2]
	local target = skillTargets[1]
	local ret = {}
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local hpAddRate = CombatObj.getValue(obj,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
	
	local aSpeed = CombatImpl.getValue(obj,RoleDefine.SPEED)
	local bSpeed = CombatImpl.getValue(target,RoleDefine.SPEED)
	local checkSpeed = aSpeed - bSpeed
	if args[3] == 1 then
		checkSpeed = -checkSpeed
	end
	if checkSpeed > 0 then
		local targets = TargetMode.getTargets(obj, args[3], skillTargets)
		for _,target in ipairs(targets) do
			hp = calcHp(obj,target,calcType,rate,limit,true)
			hp = hp * (1 + hpAddRate)
			hp = hp < 0 and 1 or hp
			if hp ~= 0 and not target.bufferCmd["noHp"] then
				if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d, _, extraHandleTb = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                if hp > 0 and d < 0 then
                   hp = hp * (-1)
                end
				CombatImpl.setExtraHit(target,hp,CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
			ret[#ret+1] = target
		end
	end
	return ret
end

function CMD.statusHp(obj,skillConfig,skillTargets)
	if not skillTargets then
		return
	end
	local isAdd = false
	local args = obj.isPet and obj.args or skillConfig.args
	for _,v in ipairs(skillTargets) do
		if CombatBuff.isStatus(v,args[4]) then
			isAdd = true
			break
		end 
	end
	if not isAdd then return end
	
	
	local calcType = args[1]
	local rate = args[2]
	local ret = {}
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local targets = TargetMode.getTargets(obj, args[3], skillTargets)
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit,true)
		hp = hp < 0 and 1 or hp
		if hp ~= 0 and not target.bufferCmd["noHp"] then
			if target.side == CombatDefine.DEFEND_SIDE then
				hp = CombatImpl.commonArgs.hpLimit or hp
			end
			local d, _, extraHandleTb = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
            if hp > 0 and d < 0 then
               hp = hp * (-1)
            end
			CombatImpl.setExtraHit(target,hp,CMD2ID["hp"])
			CombatObj.onHpCB(target,d, obj.pos)

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
		ret[#ret+1] = target
	end
	return ret
end

function CMD.hurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			-- if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			-- end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end


function CMD.hurtSelf(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtSelf"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.behurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		if calcType ~= 17 then
			hp = calcHp(target,obj,calcType,rate,limit)
		else
			hp = calcHp(obj, target,calcType,rate,limit)
		end
		
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["behurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.hurtwalun(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtwalun"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.posHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	
    local posList = args[6]
	if posList == nil then
		return
	end

	for _,target in ipairs(targets) do
		local bfind = false
		for k, v in pairs(posList) do
			if v == target.pos then
				bfind = true
				break
			end
		end
		
	    if bfind  then
			hp = calcHp(obj,target,calcType,rate,limit, false)
			if hp ~= 0 then
				local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end
	return ret
end

function CMD.hurtxia(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.hurtmingli(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtmingli"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.hurtmingli2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtmingli2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.hurtguangci(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtguangci"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.jobHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local job = args[4]
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local ret = {}
	for _,target in ipairs(skillTargets) do
		if target.job == job then
			hp = calcHp(obj,target,calcType,rate,limit)
			if hp and hp ~= 0 then
				local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["jobHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end	
	return ret
end


function CMD.statusHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local status = args[4]
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local ret = {}
	for _,target in ipairs(skillTargets) do
		if CombatBuff.isStatus(target, status)  then
			hp = calcHp(obj,target,calcType,rate,limit)
			if hp and hp ~= 0 then
				local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["jobHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end	
	return ret
end

function CMD.hpHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local hpRate = args[3]/10000
	local ret = {}
	for _,target in ipairs(skillTargets) do
		local hpLimit = CombatObj.getHpMax(target) * hpRate
		if target.hp >= hpLimit then
			hp = calcHp(obj,target,calcType,rate)
			if hp and hp ~= 0 then
				local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["hpHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end	
	return ret
end

function CMD.fanji(obj,skillConfig,skillTargets)
	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if CombatBuff.isStatus(obj,{"xuanyun","shihua","bingdong", "xuanyun2", "chenshui", "donghe", "gandian"}) then return end
	if obj.side == skillTargets[1].side then
		return
	end
	if obj.hp > 0 then
		local r = math.random(0,10000)
		if r < skillConfig.args[2] then
			for i=#skillTargets, 1, -1 do
				if BeSkill.isNoFanji(skillTargets[i]) then
					table.remove(skillTargets, i)
				end
			end

			if #skillTargets == 0 then
				return
			end

			CombatImpl.fanjiList[#CombatImpl.fanjiList + 1] = {obj,skillConfig.args[1],skillTargets}
		end
	end
end

function CMD.qingsuan(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local rate = args[1]
	local limit
	if args[4] then
		limit = args[4] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	local targets = TargetMode.getTargets(obj, args[2],skillTargets)
	local ret = {}
	for _,target in ipairs(targets) do
		local baseValue = CombatBuff.qingsuan(target)
		if baseValue > 0 then
			local hurt = baseValue * rate / 10000
			if limit and hurt > limit then
				hurt = limit
			end
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			CombatImpl.setExtraHit(target,-hurt,CMD2ID["qingsuan"])
			CombatObj.onHpCB(target,d, obj.pos)
			ret[#ret+1] = target

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.jiekong(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[2] then
		return
	end
	local targets = TargetMode.getTargets(obj, args[1],skillTargets)
	local ret = {}
	for _,target in ipairs(targets) do
		CombatBuff.jiekong(target)
		ret[#ret+1] = target
	end
	return ret
end

function CMD.groupcmd(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	for k,v in ipairs(skillConfig.args) do
		local cmd = v[1]
		local conf = {args = v[2]}
		if CMD[cmd] then
			CMD[cmd](obj,conf,skillTargets)
		end
	end
	return {}
end

function CMD.randcmd(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local total = 0
	for k,v in ipairs(skillConfig.args) do
		total = total + v[3]
	end
	local r = math.random(0,total)
	for k,v in ipairs(skillConfig.args) do
		if r <= v[3] then
			local cmd = v[1]
			local conf = {args = v[2]}
			if CMD[cmd] then
				CMD[cmd](obj,conf,skillTargets)
			end
			break
		else
			r = r - v[1]
		end
	end	

	return {}
end

function CMD.qusan(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end

	local qusanType = args[1]
	local calcType = args[5] and args[5][1]
	local rate = args[5] and args[5][2]
    local buffers = args[8] and args[8][1]

	local targets = TargetMode.getTargets(obj, args[2],skillTargets)
	local ret = {}
	local qusanTotalNum = 0


	if args[7] then
		limit = args[7] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		local cnt = CombatBuff.qusan(target, qusanType,args[4])
		qusanTotalNum = qusanTotalNum + cnt
		if limit then
			limit = limit * cnt
		end

        if buffers and cnt > 0 then
           local targets = TargetMode.getTargets(obj, args[8][2],skillTargets)
           CombatBuff.qusanAddBuff(obj, targets, buffers)
        end

		ret[#ret+1] = target
		if calcType and rate and cnt > 0 then
			local hp = calcHp(obj,target,calcType,rate * cnt, limit, nil, nil, args[6])
			if hp ~= 0 then
				local d,_, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["qusan"])
					CombatObj.onHpCB(target,d, obj.pos)
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end

	local tb = { skillConfig.cmd,  qusanTotalNum }
	return ret, tb
end


function CMD.qusan2(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end

	local qusanType = args[1]
	local qusanSubNum = args[4] or 0 -- 剩余可驱散数量
	if qusanSubNum <= 0 then
		return
	end

	local targets = TargetMode.getTargets(obj, args[2], skillTargets)
	local ret = {}
	local qusanTotalNum = 0 -- 当前已经驱散数量

	for _,target in ipairs(targets) do
		qusanSubNum = qusanSubNum - qusanTotalNum
		if qusanSubNum <= 0 then
			break
		end

		local cnt = CombatBuff.qusan(target, qusanType, qusanSubNum)
		qusanTotalNum = qusanTotalNum + cnt
		ret[#ret+1] = target
	end

	local tb = { skillConfig.cmd,  qusanTotalNum }
	return ret, tb
end

--[[
teamQusanHp: 队友按施法者攻击力比例回血 -> 驱散队友负面 -> 自身按驱散总数*最大生命比例回血
args[1] 驱散类型(1负面 2增益)
args[2] 队友目标选择
args[3] 触发概率(万分比)
args[4] 每个队友驱散debuff数量(nil/0为不限)
args[5] 队友回血 {calcType, rate} 如{1,5000}为施法者攻击力50%
args[6] 自身回血 {calcType, rate} 如{2,700}为每个驱散量*最大生命7%(可选，未配置则不回血)
]]
function CMD.teamQusanHp(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end

	local qusanType = args[1]
	local teamCalcType = args[5] and args[5][1]
	local teamRate = args[5] and args[5][2]
	local selfCalcType = args[6] and args[6][1]
	local selfRate = args[6] and args[6][2]

	local targets = TargetMode.getTargets(obj, args[2], skillTargets)
	local ret = {}
	local qusanTotalNum = 0

	if teamCalcType and teamRate then
		local hpAddRate = CombatObj.getValue(obj, RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
		for _,target in ipairs(targets) do
			if not target.bufferCmd["noHp"] then
				local hp = calcHp(obj, target, teamCalcType, teamRate, nil, true)
				hp = hp * (1 + hpAddRate)
				hp = hp < 0 and 1 or hp
				if hp > 0 then
					local restoreMul = BeSkill.GetBeSkillRestoretHPMul(target) or 1
					hp = hp * restoreMul
					local d, _, extraHandleTb = CombatObj.updateHp(target, hp, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
					local showHp = hp
					if hp > 0 and d < 0 then
						showHp = hp * (-1)
					end
					CombatImpl.setExtraHit(target, showHp, CMD2ID["hp"])
					CombatObj.onHpCB(target, d, obj.pos)
					if extraHandleTb then
						ExtraHandle(target, extraHandleTb)
					end
				end
			end
		end
	end

	for _,target in ipairs(targets) do
		local cnt = CombatBuff.qusan(target, qusanType, args[4])
		qusanTotalNum = qusanTotalNum + cnt
		ret[#ret+1] = target
	end

	if selfCalcType and selfRate and selfRate > 0 and qusanTotalNum > 0 and not obj.bufferCmd["noHp"] then
		local hp = calcHp(obj, obj, selfCalcType, selfRate * qusanTotalNum, nil, true)
		local hpAddRate = CombatObj.getValue(obj, RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
		hp = hp * (1 + hpAddRate)
		hp = hp < 0 and 1 or hp
		if hp > 0 then
			local restoreMul = BeSkill.GetBeSkillRestoretHPMul(obj) or 1
			hp = hp * restoreMul
			local d, _, extraHandleTb = CombatObj.updateHp(obj, hp, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
			local showHp = hp
			if hp > 0 and d < 0 then
				showHp = hp * (-1)
			end
			CombatImpl.setExtraHit(obj, showHp, CMD2ID["hp"])
			CombatObj.onHpCB(obj, d, obj.pos)
			if extraHandleTb then
				ExtraHandle(obj, extraHandleTb)
			end
		end
	end

	local tb = { skillConfig.cmd, qusanTotalNum }
	return ret, tb
end

function CMD.hurtwalun2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtwalun2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end


function CMD.hurtxia2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end


function CMD.hurtxia3(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia3"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

function CMD.attributehurt(obj, skillConfig, skillTargets)
	if not skillTargets or nil == _G.next(skillTargets) then
		return
	end
	local args = skillConfig.args
	if not args then
		print("[attributehurt] 不存在对应配置直接返回")
		return
	end

	local nAttrID = args[1]	-- 属性ID
	local nRate = args[2]	-- 属性倍数
	local nEnemyAttrID = args[3]	-- 敌方属性
	local nNowHurt = CombatObj.getValue(obj, RoleDefine.ATK)
	local nAttrValue = CombatObj.getValue(obj, nAttrID)
	local nValue = nAttrValue * nRate
	local nMaxHurt = CombatObj.getValue(obj, RoleDefine.ATK) * 10
	-- print("[attributehurt] 计算出来的进攻方属性加成 nValue = "..nValue.." 获取到的 属性ID = "
	-- 		..nAttrID.." 属性值 "..nAttrValue.." 倍率 "..nRate.." 攻击力的10倍 = "..nMaxHurt)


	local ret = {}
	for _, tEnemyObj in ipairs(skillTargets) do
		local nEnemyValue = CombatObj.getValue(tEnemyObj, nEnemyAttrID)
		local nBeginHurt = nValue / nEnemyValue
		local nEndHurt = nBeginHurt * nNowHurt
		nEndHurt = math.min(nMaxHurt, nEndHurt)
		-- print("[attributehurt] 计算出来的最终伤害 nEndHurt = "..nEndHurt.." 获取到的敌方 属性ID = "
		-- 	..nEnemyAttrID.." 敌方属性值 "..nEnemyValue.." 开始 nBeginHurt "..nBeginHurt)

		local d, _, extraHandleTb = CombatObj.updateHp(tEnemyObj, -nEndHurt, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
		if d ~= 0 then
			CombatImpl.setExtraHit(tEnemyObj, -nEndHurt, CMD2ID["attributehurt"])
			CombatObj.onHpCB(tEnemyObj, d, obj.pos, skillConfig.id)
			ret[#ret+1] = tEnemyObj
		end

		if extraHandleTb then
			ExtraHandle(tEnemyObj, extraHandleTb)
		end
	end
	
	return ret
end

NO_SKILL_CHECK_COMBO_LIST = {
	["hp"] = 1,
	["revive"] = 1,
	["baohu"] = 1,
}
function skillIsHpOrRevive(obj, argSkillID)
    --local argSkillConf = SkillExcel[argSkillID]
	local argSkillConf = GetSkillConfig(argSkillID)
    if  not argSkillConf  then return end

    -- 带有伤害
    if argSkillConf.hurtRate[1] then return end

    if argSkillConf.continuous and argSkillConf.continuous == 1 then return true end

    if NO_SKILL_CHECK_COMBO_LIST[argSkillConf.cmd] then
       return true
    end

    local bRet = false
    if argSkillConf.cmd == "groupcmd" then
        for k,v in ipairs(argSkillConf.args) do
		   local cmd = v[1]
           if cmd == "hurt" then return end
           if NO_SKILL_CHECK_COMBO_LIST[cmd] then
              bRet = true
           end
        end
    end

    -- 技能包
    if argSkillConf.type == CombatDefine.SKILL_TYPE5 or 
       argSkillConf.type == CombatDefine.SKILL_TYPE6 or
       argSkillConf.type == CombatDefine.SKILL_TYPE7 then
        for k,v in ipairs(argSkillConf.otherArgs.skillList) do
		  local config = SkillExcel[v]
          -- 带有伤害
		  if config and config.hurtRate[1] then return end

          if config then
             if NO_SKILL_CHECK_COMBO_LIST[config.cmd] or config.continuous == 1 then
                bRet = true
             end
          
          
            for k,v in ipairs(config.buffers) do
		       --local bufConfig = BufferExcel.buffer[v[1]]
			   local bufConfig = CombatBuff.GetBuffConfig(v[1])
               -- 带有伤害
               if bufConfig and NO_SKILL_CHECK_COMBO_LIST[bufConfig.cmd] then
                  bRet = true
               end 
	        end
		  end
	   end

       for k,v in ipairs(argSkillConf.buffers) do
		  --local bufConfig = BufferExcel[v[1]]
		  local bufConfig = CombatBuff.GetBuffConfig(v[1])
            -- 带有伤害
          if bufConfig and NO_SKILL_CHECK_COMBO_LIST[bufConfig.cmd] then
             bRet = true
          end 
	   end
   end

   return bRet
end


function CMD.combo(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(obj, argSkillID) then
           return
       end

       if skillIsHpOrRevive(obj, skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end

	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
	-- 	return
	-- end

	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
		return true
	end
end

--
function CMD.comboFight(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(obj, argSkillID) then
           return
       end

       if skillIsHpOrRevive(obj, skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
		return true
	end
end

function CMD.combo1(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(obj, skillConfig) then
           return
       end

       if skillIsHpOrRevive(obj, skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
	-- 	return
	-- end


	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],2}
		return true
	end
end

function CMD.combo2(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(obj, argSkillID) then
           return
       end

       if skillIsHpOrRevive(obj, skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
	-- 	return
	-- end

	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],3}
		return true
	end
end


function CMD.comboNormal(obj, skillConfig, skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getNormalSkill(obj)
       if skillIsHpOrRevive(obj, argSkillID) then
           return
       end

       if skillIsHpOrRevive(obj, skillConfig.id) then
           return
       end
    end

	if CombatImpl.comboType > 0 then return end

    if CombatImpl.isFanji then
        if GroupSkillCnt > 2 then return end
    else
        if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
    end
	
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then	
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 2, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1}
	end
end

function CMD.attrcomboAgain(obj, skillConfig, skillTargets)
	local tComboCof = nil
	for _, v in ipairs(skillConfig.args) do
		if v[1] == 2 then
			tComboCof = v
			break
		end
	end

	if not tComboCof then
		print("[CMD.attrcomboAgain] 不存在连击配置")	
		return
	end

	--table.print_lua_table(tComboCof)

	-- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
		local argSkillID = tComboCof[3] or CombatImpl.getSkillID(obj)
		if skillIsHpOrRevive(obj, argSkillID) then
			return
		end
 
		if skillIsHpOrRevive(obj, skillConfig.id) then
			return
		end
	end

	local nSkillID = tComboCof[3] or CombatImpl.getSkillID(obj)
	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	-- if CombatImpl.isFanji or (CombatImpl.comboType > 0 and CombatImpl.comboType ~= 999) then
	-- 	return
	-- end

	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	--print("[CMD.attrcomboAgain] nSkillID = "..nSkillID)
	if r < tComboCof[2] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, tComboCof[3], nSkillID, tComboCof[5] or 1, tComboCof[6]}
		return true
	end
end


function CMD.zhuiji(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
		local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
		if skillIsHpOrRevive(obj, argSkillID) then
			return
		end

		if skillIsHpOrRevive(obj, skillConfig.id) then
			return
		end
    end

	local objTag = obj.uuid or obj.id
	if CombatImpl.useZhuijiObjList[obj.pos] and (CombatImpl.useZhuijiObjList[obj.pos][objTag] or 0) >= 1 then
		return
	end

	-- if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 999, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
		return true
	end
end

function CMD.baohu(obj,skillConfig,skillTargets)
	local d, _, extraHandleTb = CombatObj.updateHp(obj,obj.baohuHurt,nil,nil, obj.pos,CombatObj.BUFFER_HP_TYPE)
	if d ~= 0 then
		local attrs = {}
		attrs[RoleDefine.BAOHU_COMBAT] = skillTargets[1].pos
		CombatImpl.setExtraHit(obj,d,CMD2ID["baohu"],attrs)
		CombatObj.onHpCB(obj,d, skillTargets[1].pos)
	end

	if extraHandleTb then
		ExtraHandle(obj, extraHandleTb)
	end
end

function CMD.yinbaoZuzhou(obj,skillConfig,skillTargets)
	CombatBuff.yinbaoZuzhou(obj, skillTargets, skillConfig)
end

--指定普攻目标模式
function CMD.normalTarget(obj,skillConfig)
	obj.normalTarget = {status = {}}
	if skillConfig.args.status then
		for k,v in ipairs(skillConfig.args.status) do
			obj.normalTarget.status[k] = v
		end
	end
end

--诅咒附加伤害
function CMD.zuzhouHurt(obj, skillConfig, skillTargets)
    if not obj.args then return end
    local confArgs = skillConfig.args
	local targets = TargetMode.getTargets(obj, confArgs[1], skillTargets)
	local zuzhouHurt = obj.args * confArgs[2] / 10000
	for _,target in ipairs(targets) do
		if zuzhouHurt ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-zuzhouHurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-zuzhouHurt,CMD2ID["zuzhouHurt"])
				CombatObj.onHpCB(target,d, obj.pos)
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
    obj.args = nil
end

-- 根据诅咒数增加伤害
function CMD.zuzhouTrueHurt(obj, skillConfig, skillTargets)
	local confArgs = skillConfig.args
	local nAtt = CombatObj.getValue(obj,RoleDefine.ATK)
	local baseHurt = nAtt * confArgs[1] / 10000
	for _,target in ipairs(skillTargets) do
		local isStatus, cmd, ind = CombatBuff.isStatus(target, {"zuzhou"})
		if isStatus then
			local nZuZhouNum = #target.bufferCmd["zuzhou"]
			local nHurt = baseHurt * nZuZhouNum
			if nHurt > 0  then
				local d, _, extraHandleTb = CombatObj.updateHp(target, -nHurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-nHurt,CMD2ID["zuzhouTrueHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
				end

				if extraHandleTb then
					ExtraHandle(target, extraHandleTb)
				end
			end
		end
	end
end

function CMD.dnexhurt(obj,skillConfig,skillTargets)
    local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end

	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)

	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK)
	end


	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end

--拥有指定buff后的额外效果
function CMD.targetBuffExtraEffect(obj,skillConfig,skillTargets)
	local args = skillConfig.args
	if not args then
		return
	end

	local targetBuffCmd = args[1]
	local targetBuffCnt = args[2]
	if not targetBuffCmd or not targetBuffCnt then
		return
	end

	local nowTargetBuffCnt = CombatBuff.getBuffCnt(obj, targetBuffCmd)
	if nowTargetBuffCnt < targetBuffCnt then
		return
	end

	local targetMode = args[3]
	local targets = TargetMode.getTargets(obj, targetMode, skillTargets)


	local hurt, limitVale
	local calcType, rate = args[4], args[5]


	local maxNum = args[6] or 1
	local nowNum = math.floor(nowTargetBuffCnt / targetBuffCnt)
	if nowNum < maxNum then
		maxNum = nowNum
	end

	local limitAttrType = args[7]
	local limitAttrRate = args[8]
	if limitAttrType and limitAttrRate then
		limitVale = limitAttrRate * CombatObj.getValue(obj, limitAttrType)
	end

	table.shuffle(targets)
	for idx, target in ipairs(targets) do
		if idx > maxNum then
			break
		end
		hurt = calcHp(obj, target, calcType, rate, limitVale)
		if hurt ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hurt,nil,true, obj.pos,CombatObj.SKILL_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hurt,CMD2ID["targetBuffExtraEffect"])
				CombatObj.onHpCB(target,d, obj.pos)
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end

	CombatBuff.DelBuffByCmd(obj, targetBuffCmd, nowTargetBuffCnt)
end

--debuff 和 buff 数量差的额外伤害
function CMD.buffDiffHurt(obj,skillConfig,skillTargets)
	local args = skillConfig.args
	if not args then
		return
	end

	local buffType1 = args[1]   --buff类型1, 对应配置表buff中qusan分页中的type
	local buffType2 = args[2]   --buff类型2, 对应配置表buff中qusan分页中的type
	local targetMode = args[3]
	local calcType, rate = args[4], args[5]
	local limitAttrType, limitAttrMul = args[6], args[7]

	local maxHurt = CombatObj.getValue(obj, limitAttrType) * limitAttrMul

	local targets = TargetMode.getTargets(obj, targetMode, skillTargets)

	for _, targetObj in ipairs(targets) do
		local buffCnt1 = CombatBuff.getCombatBufferCnt(targetObj, buffType1)
		local buffCnt2 = CombatBuff.getCombatBufferCnt(targetObj, buffType2)
		if buffCnt1 >  buffCnt2 then
			local hurt = calcHp(obj, targetObj, calcType, rate)
			hurt = hurt * (buffCnt1 - buffCnt2)
			if hurt > maxHurt then
				hurt = maxHurt
			end

			local d, _, extraHandleTb = CombatObj.updateHp(targetObj, -hurt, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(targetObj, -hurt, CMD2ID["buffDiffHurt"])
				CombatObj.onHpCB(targetObj, d, obj.pos)
			end

			if extraHandleTb then
				ExtraHandle(targetObj, extraHandleTb)
			end
		end

	end
end


-- 与其中一个符合条件的队友交换血量， 交换成功后，恢复自身一定血量
function CMD.exchangeHP(obj,skillConfig,skillTargets)
	local args = skillConfig.args
	if not args then
		return
	end

	local targetMode = args[3]
	local targets = TargetMode.getTargets(obj, targetMode, skillTargets)
	local targetObj = targets[1]
	if targetObj then
		-- 不能是自己
		if targetObj.pos == obj.pos then
			return
		end

		-- 不能满血
		local attrID = targetMode[4] or RoleDefine.HP -- 默认是HP
		local targetObjSubRate = CombatObj.getValue(targetObj, attrID)
		if targetObjSubRate >= 10000 then
			return
		end


		local targetHP = targetObj.hp
		local attackerHp  = obj.hp
		local subHP = attackerHp - targetHP

		-- 施放者血量不能最低
		if subHP > 0 then
			-- 给目标加血量差值
			local d, _, extraHandleTb = CombatObj.updateHp(targetObj, subHP, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)

			if d ~= 0 then
				CombatImpl.setExtraHit(targetObj, subHP,  CMD2ID["hp"])
				CombatObj.onHpCB(targetObj, d, obj.pos)
			end

			if extraHandleTb then
				ExtraHandle(targetObj, extraHandleTb)
			end

			-- 给施放者扣血量差值
			d, _, extraHandleTb = CombatObj.updateHp(obj, -subHP, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(obj, -subHP,  CMD2ID["hurtSelf"])
				CombatObj.onHpCB(obj, d, obj.pos)
			end

			if extraHandleTb then
				ExtraHandle(targetObj, extraHandleTb)
			end

			-- 给施放者恢复一定血量
			local calcType = args[1]
			local rate = args[2]
			local hp = calcHp(obj,targetObj, calcType, rate, nil, true)

			d, _, extraHandleTb = CombatObj.updateHp(obj,hp, nil, true, obj.pos, CombatObj.EXTRA_HP_TYPE)
			local showHp = hp
			if hp > 0 and d < 0 then
			   showHp = hp * (-1)
			end
			CombatImpl.setExtraHit(obj, showHp, CMD2ID["hp"])
			CombatObj.onHpCB(obj,d, obj.pos)

			if extraHandleTb then
				ExtraHandle(targetObj, extraHandleTb)
			end

		end
	end
end

-- 神威灵装被动-真伤附加
function CMD.trueDamegeAddtional(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		local offsetInfo = BeSkill.GetTrueDamegeOffset(target)
		if offsetInfo then
			local offsetHurt = calcHp(obj,target,offsetInfo[1],offsetInfo[2],limit)
			hp = math.max(hp - offsetHurt, 0)
		end

		if hp ~= 0 then
			local d, _, extraHandleTb = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["trueDamegeAddtional"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end

			if extraHandleTb then
				ExtraHandle(target, extraHandleTb)
			end
		end
	end
	return ret
end