local X = {}
local bDebugMode = false
local bot = GetBot()
_G.W2Time = _G.W2Time or {}
_G.W2Time[bot] = _G.W2Time[bot] or 999999

local J = require( GetScriptDirectory()..'/FunLib/jmz_func' )
local Minion = dofile( GetScriptDirectory()..'/FunLib/aba_minion' )
local sTalentList = J.Skill.GetTalentList( bot )
local sAbilityList = J.Skill.GetAbilityList( bot )
local sOutfitType = J.Item.GetOutfitType( bot )

local tTalentTreeList = {
						['t25'] = {10, 0},
						['t20'] = {0, 10},
						['t15'] = {10, 0},
						['t10'] = {0, 10},
}

local tAllAbilityBuildList = {
    {1,2,1,3,1,6,1,2,2,2,6,3,3,3,6},
}

local nAbilityBuildList = J.Skill.GetRandomBuild( tAllAbilityBuildList )

local nTalentBuildList = J.Skill.GetTalentBuild( tTalentTreeList )

local tOutFitList = {}

tOutFitList['outfit_carry'] = {

	"item_bristleback_outfit",
	"item_soul_ring",
	"item_yasha",
	"item_black_king_bar",
	"item_radiance",
	"item_travel_boots",
	"item_sange_and_yasha",
	"item_basher",
	"item_assault",
    "item_abyssal_blade",
	"item_travel_boots_2",
	"item_aghanims_shard",
}

tOutFitList['outfit_tank'] = tOutFitList['outfit_carry']
tOutFitList['outfit_mid'] = tOutFitList['outfit_carry']
tOutFitList['outfit_mage'] = tOutFitList['outfit_carry']
tOutFitList['outfit_priest'] = tOutFitList['outfit_carry']

X['sBuyList'] = tOutFitList[sOutfitType]

X['sSellList'] = {
	"item_power_treads",
	"item_quelling_blade",

	"item_black_king_bar",
	"item_magic_wand",
	
	"item_travel_boots",
	"item_power_treads",
}

if J.Role.IsPvNMode() or J.Role.IsAllShadow() then X['sBuyList'], X['sSellList'] = { 'PvN_melee_carry' }, {} end

nAbilityBuildList, nTalentBuildList, X['sBuyList'], X['sSellList'] = J.SetUserHeroInit( nAbilityBuildList, nTalentBuildList, X['sBuyList'], X['sSellList'] )

X['sSkillList'] = J.Skill.GetSkillList( sAbilityList, nAbilityBuildList, sTalentList, nTalentBuildList )

X['bDeafaultAbility'] = true
X['bDeafaultItem'] = true

function X.MinionThink( hMinionUnit )

	if Minion.IsValidUnit( hMinionUnit )
	then
		Minion.IllusionThink( hMinionUnit )
	end

end

local abilityQ = bot:GetAbilityByName( sAbilityList[1] )
local abilityW = bot:GetAbilityByName( sAbilityList[2] )
local abilityW2 = bot:GetAbilityByName( 'alchemist_unstable_concoction_throw' )
local abilityE = bot:GetAbilityByName( sAbilityList[3] )
local abilityD = bot:GetAbilityByName( sAbilityList[4] )
local abilityR = bot:GetAbilityByName( sAbilityList[6] )
local W2Time = _G.W2Time[bot]

local castQDesire, castQLocation
local castWDesire
local castW2Desire, castW2Target
--local castEDesire, castETarget
local castDDesire, castDTarget
local castRDesire

local nKeepMana, nMP, nHP, nLV, hEnemyList, hAllyList, botTarget, sMotive
local aetherRange = 0

function X.SkillsComplement()

	if J.CanNotUseAbility( bot ) or bot:IsInvisible() then return end

	nKeepMana = 350
	aetherRange = 0
	nLV = bot:GetLevel()
	nMP = bot:GetMana()/bot:GetMaxMana()
	nHP = bot:GetHealth()/bot:GetMaxHealth()
	botTarget = J.GetProperTarget( bot )
	hEnemyList = bot:GetNearbyHeroes( 1600, true, BOT_MODE_NONE )
	hAllyList = J.GetAlliesNearLoc( bot:GetLocation(), 1600 )

	
	aetherRange = J.GetBonusCastRange( bot )

    castW2Desire, castW2Target, sMotive = X.ConsiderW2()
	if ( castW2Desire > 0 ) then

        J.SetReportMotive( bDebugMode, sMotive )

        J.SetQueuePtToINT( bot, true )

		bot:ActionPush_UseAbilityOnEntity( abilityW2, castW2Target )
        return
    end

    castWDesire, sMotive = X.ConsiderW()
    if ( castWDesire > 0 ) then

		
		_G.W2Time[bot] = DotaTime()

        J.SetReportMotive( bDebugMode, sMotive )

        J.SetQueuePtToINT( bot, true )

		bot:ActionQueue_UseAbility( abilityW )
        return
    end

    castQDesire, castQLocation, sMotive = X.ConsiderQ()
    if ( castQDesire > 0 ) then

        J.SetReportMotive( bDebugMode, sMotive )

        J.SetQueuePtToINT( bot, true )

		bot:ActionQueue_UseAbilityOnLocation( abilityQ, castQLocation )

        return
    end

    castRDesire, sMotive = X.ConsiderR()
    if ( castRDesire > 0 ) then

        J.SetReportMotive( bDebugMode, sMotive )

        J.SetQueuePtToINT( bot, true )

		bot:ActionQueue_UseAbility( abilityR )

        return
    end

    castDDesire, castDTarget, sMotive = X.ConsiderD()
    if ( castDDesire > 0 ) then

        J.SetReportMotive( bDebugMode, sMotive )

        J.SetQueuePtToINT( bot, true )

		bot:ActionQueue_UseAbilityOnEntity( abilityD, castDTarget )

        return
    end

end

function X.ConsiderW2()
	if abilityW2:IsHidden() or not abilityW2:IsTrained() or not abilityW2:IsFullyCastable() then
		_G.W2Time[bot] = 999999
		return 0
	end
	local time = DotaTime()
	if _G.W2Time[bot] == 999999 then
		--异常状况
		_G.W2Time[bot] = time - 0.5
	end

	local nCastRange = abilityW2:GetCastRange() + aetherRange

	local nEnemysHeroesInCastRange = bot:GetNearbyHeroes( nCastRange + 99, true, BOT_MODE_NONE )
	local nEnemysHeroesInView = bot:GetNearbyHeroes( 880, true, BOT_MODE_NONE )
	local nSkillLV = abilityW:GetLevel()
	local nCastPoint = abilityW2:GetCastPoint()
	local remainTime = 5.4 - nCastPoint - (time - _G.W2Time[bot])

	--打断
	if #nEnemysHeroesInView > 0 then
		for i=1, #nEnemysHeroesInView do
			if J.IsValid( nEnemysHeroesInView[i] )
				and J.CanCastOnNonMagicImmune( nEnemysHeroesInView[i] )
				and J.CanCastOnTargetAdvanced( nEnemysHeroesInView[i] )
				and nEnemysHeroesInView[i]:IsChanneling()
			then
				return BOT_ACTION_DESIRE_HIGH, nEnemysHeroesInView[i], "W-打断"..J.Chat.GetNormName( botTarget )
			end
		end
	end

	if remainTime > 3.0 then return 0 end

	local nDamage = 16+14*nSkillLV
	if nLV >= 28 then nDamage = nDamage + 80 end
	nDamage = nDamage * (4.5 - remainTime)

	--击杀
	if #nEnemysHeroesInCastRange > 0 then
		for i=1, #nEnemysHeroesInCastRange do
			if J.IsValid( nEnemysHeroesInCastRange[i] )
				and J.CanCastOnNonMagicImmune( nEnemysHeroesInCastRange[i] )
				and J.CanCastOnTargetAdvanced( nEnemysHeroesInCastRange[i] )
				and J.WillKillTarget(nEnemysHeroesInCastRange[i], nDamage, DAMAGE_TYPE_PHYSICAL, nCastPoint + GetUnitToUnitDistance(bot,nEnemysHeroesInCastRange[i])/900)
			then
				return BOT_ACTION_DESIRE_HIGH, nEnemysHeroesInCastRange[i], "W-击杀"..J.Chat.GetNormName( botTarget )
			end
		end
	end

	--团战
	if J.IsInTeamFight( bot, 1200 ) and DotaTime() > 4 * 60 then
		local npcMostDangerousEnemy = nil
		local nMostDangerousDamage = 0

		for _, npcEnemy in pairs( nEnemysHeroesInCastRange )
		do
			if J.IsValid( npcEnemy )
				and J.CanCastOnNonMagicImmune( npcEnemy )
				and J.CanCastOnTargetAdvanced( npcEnemy )
				and not J.IsDisabled( npcEnemy )
			then
				local npcEnemyDamage = npcEnemy:GetEstimatedDamageToTarget( false, bot, 3.0, DAMAGE_TYPE_ALL )
				if ( npcEnemyDamage > nMostDangerousDamage )
				then
					nMostDangerousDamage = npcEnemyDamage
					npcMostDangerousEnemy = npcEnemy
				end
			end
		end
		if ( npcMostDangerousEnemy ~= nil ) then
			return BOT_ACTION_DESIRE_HIGH, npcMostDangerousEnemy, "W-团战晕眩高威胁目标"..J.Chat.GetNormName( botTarget )
		end
	end

	--常规
	if J.IsGoingOnSomeone( bot )
	then
		local target = J.GetProperTarget( bot )
		if J.IsValidHero( target )
			and J.CanCastOnNonMagicImmune( target )
			and J.CanCastOnTargetAdvanced( target )
			and J.IsInRange( target, bot, nCastRange )
			and (((GetUnitToLocationDistance(bot,target:GetExtrapolatedLocation(0.5 + nCastPoint))>(nCastRange/2))
			and not J.IsDisabled( target )
			and not target:IsDisarmed()) or remainTime <= 1.0 or nHP < 0.2 or target: GetHealth() < 500 )
		then
			return BOT_ACTION_DESIRE_HIGH, target,"W-追杀"..J.Chat.GetNormName( target )
		end
	end

	--撤退
	if J.IsRetreating( bot )
	then
		if J.IsValid( nEnemysHeroesInCastRange[1] )
			and ((J.CanCastOnNonMagicImmune( nEnemysHeroesInCastRange[1] )
			and J.CanCastOnTargetAdvanced( nEnemysHeroesInCastRange[1] )
			and not J.IsDisabled( nEnemysHeroesInCastRange[1] )
			and not nEnemysHeroesInCastRange[1]:IsDisarmed())
			 or (remainTime <= 1.0 or nHP < 0.2))
		then
			return BOT_ACTION_DESIRE_HIGH, nEnemysHeroesInCastRange[1],"W-撤退"..J.Chat.GetNormName( nEnemysHeroesInCastRange[1] )
		end
	end

	return BOT_ACTION_DESIRE_NONE
end

function X.ConsiderQ()

	if not abilityQ:IsFullyCastable() then return 0 end

	local nSkillLV = abilityQ:GetLevel()
	local nCastRange = abilityQ:GetCastRange() + aetherRange
	local nCastPoint = abilityQ:GetCastPoint()
	local nManaCost = abilityQ:GetManaCost()
	local nDamageType = DAMAGE_TYPE_PHYSICAL
	local nRadius = abilityQ:GetSpecialValueInt( 'radius' )
	if bot:GetLevel()>=10 then nRadius = nRadius + 100 end
	local nInRangeEnemyList = bot:GetNearbyHeroes( nCastRange + nRadius * 0.5, true, BOT_MODE_NONE )

	local nTargetLocation = nil

	--消耗，保持一定魔量；仅在兵线相持时消耗
	local nCanHurtEnemyAoE = bot:FindAoELocation( true, false, bot:GetLocation(), nCastRange, nRadius + 20, 0, 0 )
	if J.IsAllowedToSpam( bot, nManaCost) and nCanHurtEnemyAoE.count >= 3 then
		nTargetLocation = nCanHurtEnemyAoE.targetloc
		if #J.GetAllyCreepNearLoc(bot, nTargetLocation, 400)>1 then
			return BOT_ACTION_DESIRE_HIGH, nTargetLocation, 'Q消耗'
		end
	end

	--团战
	if J.IsInTeamFight( bot, 1200 ) then
		local nAoeLoc = J.GetAoeEnemyHeroLocation( bot, nCastRange, nRadius, 2 )
		if nAoeLoc ~= nil
		then
			nTargetLocation = nAoeLoc
			return BOT_ACTION_DESIRE_HIGH, nTargetLocation, 'Q团战'
		end
	end

	--追杀，目标速度不快就放
	if J.IsGoingOnSomeone( bot )
	then
		if J.IsValidHero( botTarget )
			and J.CanCastOnNonMagicImmune( botTarget )
			and J.IsInRange( botTarget, bot, nCastRange - 30 )
			and (botTarget:GetCurrentMovementSpeed() < 240 or botTarget:IsStunned() or botTarget:IsRooted())
		then
			nTargetLocation = J.GetDelayCastLocation( bot, botTarget, nCastRange, nRadius, nCastPoint )
			if nTargetLocation ~= nil
			then
				return BOT_ACTION_DESIRE_HIGH, nTargetLocation, "Q追杀"..J.Chat.GetNormName( botTarget )
			end
		end
	end

	--打野
	if J.IsFarming( bot ) and nSkillLV >= 2 and J.IsAllowedToSpam( bot, nManaCost) then
		if J.IsValid( botTarget )
			and botTarget:GetTeam() == TEAM_NEUTRAL
			and J.IsInRange( bot, botTarget, 1000 )
			and nMP > 0.4
		then
			local nShouldHurtCount = nMP > 0.6 and 2 or 3
			local locationAoE = bot:FindAoELocation( true, false, bot:GetLocation(), nCastRange, nRadius, 0, 0 )
			if ( locationAoE.count >= nShouldHurtCount )
			then
				nTargetLocation = locationAoE.targetloc
				return BOT_ACTION_DESIRE_HIGH, nTargetLocation, "Q打钱"..locationAoE.count
			end
		end
	end

	--带线
	if ( J.IsPushing( bot ) or J.IsDefending( bot ) or J.IsFarming( bot ) )
		and J.IsAllowedToSpam( bot, nManaCost )
		and nSkillLV >= 3 and DotaTime() > 9 * 60
		and #hEnemyList == 0
	then
		local laneCreepList = bot:GetNearbyLaneCreeps( nCastRange + 200, true )
		if #laneCreepList >= 4
			and J.IsValid( laneCreepList[1] )
			and not laneCreepList[1]:HasModifier( "modifier_fountain_glyph" )
		then
			local locationAoEHurt = bot:FindAoELocation( true, false, bot:GetLocation(), nCastRange, nRadius + 50, 0, 0 )
			if locationAoEHurt.count >= 3 then
				nTargetLocation = locationAoEHurt.targetloc
				return BOT_ACTION_DESIRE_HIGH, nTargetLocation, "Q带线"..locationAoEHurt.count
			end
		end
	end

	--肉山
	if bot:GetActiveMode() == BOT_MODE_ROSHAN
		and bot:GetMana() >= 600
	then
		if J.IsRoshan( botTarget ) and J.GetHP( botTarget ) > 0.1
			and J.IsInRange( botTarget, bot, nCastRange )
		then
			nTargetLocation = botTarget:GetLocation()
			return BOT_ACTION_DESIRE_HIGH, nTargetLocation, 'Q肉山'
		end
	end

	return BOT_ACTION_DESIRE_NONE

end

function X.ConsiderW()

	if abilityW:IsHidden() or not abilityW:IsFullyCastable() then
		return 0
	end

	local time = DotaTime()
	local nCastRange = abilityQ:GetCastRange() + aetherRange

	local nEnemysHeroesInCastRange = bot:GetNearbyHeroes( nCastRange / 4 * 3, true, BOT_MODE_NONE )
	local nEnemysHeroesInView = bot:GetNearbyHeroes( 880, true, BOT_MODE_NONE )
	local nSkillLV = abilityW:GetLevel()
	local nCastPoint = abilityW2:GetCastPoint()

	--打断
	if #nEnemysHeroesInView > 0 then
		for i=1, #nEnemysHeroesInView do
			if J.IsValid( nEnemysHeroesInView[i] )
				and J.CanCastOnNonMagicImmune( nEnemysHeroesInView[i] )
				and J.CanCastOnTargetAdvanced( nEnemysHeroesInView[i] )
				and nEnemysHeroesInView[i]:IsChanneling()
			then
				return BOT_ACTION_DESIRE_HIGH, "W-打断-开摇"..J.Chat.GetNormName( botTarget )
			end
		end
	end

	local nDamage = 16+14*nSkillLV
	if nLV >= 28 then nDamage = nDamage + 80 end
	nDamage = nDamage * 2.0

	--击杀
	if #nEnemysHeroesInCastRange > 0 then
		for i=1, #nEnemysHeroesInCastRange do
			if J.IsValid( nEnemysHeroesInCastRange[i] )
				and J.CanCastOnNonMagicImmune( nEnemysHeroesInCastRange[i] )
				and J.CanCastOnTargetAdvanced( nEnemysHeroesInCastRange[i] )
				and J.WillKillTarget(nEnemysHeroesInCastRange[i],DAMAGE_TYPE_PHYSICAL, nCastPoint + GetUnitToUnitDistance(bot,nEnemysHeroesInCastRange[i])/900)
			then
				return BOT_ACTION_DESIRE_HIGH, "W-击杀-开摇"..J.Chat.GetNormName( botTarget )
			end
		end
	end

	--团战
	if J.IsInTeamFight( bot, 1200 ) and DotaTime() > 4 * 60 then
		local npcMostDangerousEnemy = nil
		local nMostDangerousDamage = 0

		for _, npcEnemy in pairs( nEnemysHeroesInCastRange )
		do
			if J.IsValid( npcEnemy )
				and J.CanCastOnNonMagicImmune( npcEnemy )
				and J.CanCastOnTargetAdvanced( npcEnemy )
				and not J.IsDisabled( npcEnemy )
				and not npcEnemy:IsDisarmed()
			then
				local npcEnemyDamage = npcEnemy:GetEstimatedDamageToTarget( false, bot, 3.0, DAMAGE_TYPE_ALL )
				if ( npcEnemyDamage > nMostDangerousDamage )
				then
					nMostDangerousDamage = npcEnemyDamage
					npcMostDangerousEnemy = npcEnemy
				end
			end
		end

		if ( npcMostDangerousEnemy ~= nil )
		then
			return BOT_ACTION_DESIRE_HIGH, "W-团战晕眩高威胁目标-开摇"..J.Chat.GetNormName( botTarget )
		end
	end

	--常规
	if J.IsGoingOnSomeone( bot )
	then
		local target = J.GetProperTarget( bot )
		if J.IsValidHero( target )
			and J.CanCastOnNonMagicImmune( target )
			and J.CanCastOnTargetAdvanced( target )
			and J.IsInRange( target, bot, nCastRange )
			and (((GetUnitToLocationDistance(bot,target:GetExtrapolatedLocation(0.5 + nCastPoint))>nCastRange/4*3)
			and not J.IsDisabled( target )
			and not target:IsDisarmed()) or remainTime <= 0.5)
		then
			return BOT_ACTION_DESIRE_HIGH, "W-追杀-开摇"
		end
	end

	--撤退
	if J.IsRetreating( bot )
	then
		if J.IsValid( nEnemysHeroesInCastRange[1] )
			and J.CanCastOnNonMagicImmune( nEnemysHeroesInCastRange[1] )
			and J.CanCastOnTargetAdvanced( nEnemysHeroesInCastRange[1] )
			and not J.IsDisabled( nEnemysHeroesInCastRange[1] )
			and not nEnemysHeroesInCastRange[1]:IsDisarmed()
			and (GetUnitToLocationDistance(bot,target:GetExtrapolatedLocation(0.5 + nCastPoint))>nCastRange/4*3)
		then
			return BOT_ACTION_DESIRE_HIGH, "W-撤退-开摇"
		end
	end

	return BOT_ACTION_DESIRE_NONE
end

function X.ConsiderR()

	if not abilityR:IsFullyCastable() then return 0 end

	if J.IsInTeamFight( bot, 1200 ) then
		return BOT_ACTION_DESIRE_HIGH, "R-开战"
	end
	if nHP<0.5 or (bot:WasRecentlyDamagedByAnyHero(3.0) and nHP<0.7) then
		return BOT_ACTION_DESIRE_HIGH, "R-回复"
	end
	if J.IsGoingOnSomeone(bot) and J.IsValidHero( J.GetProperTarget( bot ) ) then
		return BOT_ACTION_DESIRE_HIGH, "R-追杀"
	end

	--肉山
	if bot:GetActiveMode() == BOT_MODE_ROSHAN then
		if J.IsRoshan( botTarget ) and J.GetHP( botTarget ) > 0.1
			and J.IsInRange( botTarget, bot, 500 ) then
			return BOT_ACTION_DESIRE_HIGH, 'R肉山'
		end
	end

	return BOT_ACTION_DESIRE_NONE

end

function X.ConsiderD()


	if not abilityD:IsTrained()
		or not abilityD:IsFullyCastable() 
	then
		return BOT_ACTION_DESIRE_NONE
	end
	
	local nCastRange = abilityD:GetCastRange() + aetherRange
	local nCastPoint = abilityD:GetCastPoint()
	local nManaCost = abilityD:GetManaCost()
	local nHealHealth = 400
	local hCastTarget = nil
	local sCastMotive = nil

	for _, npcAlly in pairs( hAllyList )
	do
		if J.IsValidHero( npcAlly )
			and J.IsInRange( bot, npcAlly, nCastRange + 300 )
			and not npcAlly:HasModifier( 'modifier_alchemist_berserk_potion' )
			and not npcAlly:IsMagicImmune()
			and not npcAlly:IsInvulnerable()
			and not npcAlly:IsIllusion()
		then
			--为加Buff
			if npcAlly:GetAttackTarget() ~= nil
				and npcAlly:GetAttackTarget():IsHero()
				and J.GetHP(npcAlly) >= 0.8
			then
				hCastTarget = npcAlly
				sCastMotive = 'D-加Buff:'..J.Chat.GetNormName( hCastTarget )
				return BOT_ACTION_DESIRE_HIGH, hCastTarget, sCastMotive
			end

			--为被减速队友解减速
			if J.ShouldDispelDebuff( npcAlly ) then
				hCastTarget = npcAlly
				sCastMotive = 'D-解Debuff:'..J.Chat.GetNormName( hCastTarget )
				return BOT_ACTION_DESIRE_HIGH, hCastTarget, sCastMotive			
			end

			--为撤退中的队友加血
			if J.IsRetreating( npcAlly )
				and not npcAlly:HasModifier( 'modifier_fountain_aura' )
				and npcAlly:GetMaxHealth() - npcAlly:GetHealth() >= nHealHealth * 0.7
				and npcAlly:WasRecentlyDamagedByAnyHero( 3.0 )
			then
				hCastTarget = npcAlly
				sCastMotive = 'D-加撤退中的队友:'..J.Chat.GetNormName( hCastTarget )
				return BOT_ACTION_DESIRE_HIGH, hCastTarget, sCastMotive
			end
			
			
			--为准备打架的非智力队友辅助
			if J.IsGoingOnSomeone( npcAlly )
				and npcAlly:GetPrimaryAttribute() ~= ATTRIBUTE_INTELLECT
			then
				local allyTarget = J.GetProperTarget( npcAlly )
				if J.IsValidHero( allyTarget )
					and npcAlly:IsFacingLocation( allyTarget:GetLocation(), 20 )
					and J.IsInRange( npcAlly, allyTarget, npcAlly:GetAttackRange() + 60 )
				then
					hCastTarget = npcAlly
					sCastMotive = 'D-进攻辅助队友:'..J.Chat.GetNormName( hCastTarget )
					return BOT_ACTION_DESIRE_HIGH, hCastTarget, sCastMotive
				end
			end
			
			--为残血队友buff
			if J.GetHP( npcAlly ) < 0.5
				and ( npcAlly:WasRecentlyDamagedByAnyHero( 5.0 ) or J.GetHP( npcAlly ) < 0.25 ) 
				and not npcAlly:HasModifier( 'modifier_fountain_aura' )
			then
				hCastTarget = npcAlly
				sCastMotive = 'D-为队友回血:'..J.Chat.GetNormName( hCastTarget )
				return BOT_ACTION_DESIRE_HIGH, hCastTarget, sCastMotive			
			end			
		end
	end

	return BOT_ACTION_DESIRE_NONE

end

return X
-- dota2jmz@163.com QQ:2462331592..




