function OnItem2001_SpellStart(keys)
	local caster = keys.caster
	if caster:IsRealHero() or caster:GetUnitName() == "reimu_pet" then
		local entities = Entities:FindAllByClassname("npc_dota_creature")

		for k,v in pairs(entities) do
			local findNum =  string.find(v:GetUnitName(), 'creature')
			if findNum ~= nil and v~=nil and v:IsNull()==false and v:IsAlive() then 
				if SpawnSystem.IsUnLimited then 
					if v.thtd_player_index == caster:GetPlayerOwnerID() then						
						caster:NpcKill(v)					
					end					
				else
					caster:NpcKill(v)				
				end
			end
		end
		
		if SpawnSystem.CurWave > 100 then 
			if caster:GetUnitName() == "reimu_pet" then						
				caster:GetOwner().use_item2001_count = (caster:GetOwner().use_item2001_count or 0) + 1
			else					
				caster.use_item2001_count = (caster.use_item2001_count or 0) + 1
			end			
			if SpawnSystem.RankMinWave >= SpawnSystem.CurWave then 
				SpawnSystem.RankMinWave = SpawnSystem.RankMinWave + 1
			end
		end

		local particle = ParticleManager:CreateParticle("particles/heroes/yumemi/ability_yumemi_04_exolosion.vpcf",PATTACH_CUSTOMORIGIN,caster)
		ParticleManager:SetParticleControl(particle,0,caster:GetOrigin())
		ParticleManager:DestroyParticleSystem(particle,false)

		if keys.ability:IsItem() then
			local charge = keys.ability:GetCurrentCharges()
			if charge > 1 then
				keys.ability:SetCurrentCharges(charge-1)
			else
				caster:RemoveItem(keys.ability)
			end
		end
	end
end

function OnItem2002_SpellStart(keys)
	local caster = keys.caster
	if caster:IsRealHero() then
		if keys.ability:IsItem() then
			local select_cards = {}
			for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
				if v["quality"] == 4 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
					select_cards[v["itemName"]] = v["itemName"]
				end
			end
			CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
			caster.thtd_last_select_item = keys.ability
		end
	end
end

function OnItem2003_SpellStart(keys)
	local caster = keys.caster
	if caster:IsRealHero() then
		if keys.ability:IsItem() then
			local select_cards = {}
			for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
				if v["quality"] == 3 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
					select_cards[v["itemName"]] = v["itemName"]
				end
			end
			CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
			caster.thtd_last_select_item = keys.ability
		end
	end
end

function OnItem2004_SpellStart(keys)
	local caster = keys.caster
	if caster:IsRealHero() then
		if keys.ability:IsItem() then
			local select_cards = {}
			for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
				if v["quality"] == 2 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
					select_cards[v["itemName"]] = v["itemName"]
				end
			end
			CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
			caster.thtd_last_select_item = keys.ability
		end
	end
end

function OnItem2021_SpellStart(keys)	
	local target = keys.target	
	
	if target:THTD_IsTower() and target:HasModifier("modifier_item_2021_buff") == false then
		local duration_time = math.max(keys.duration_min, keys.duration_max - keys.step * (target.item2021_count or 0)) * 1.0
		target.item2021_count = (target.item2021_count or 0) + 1
		keys.ability:ApplyDataDrivenModifier(target, target, "modifier_item_2021_buff", {duration = duration_time})

		if keys.ability:IsItem() then
			local charge = keys.ability:GetCurrentCharges()
			if charge > 1 then
				keys.ability:SetCurrentCharges(charge-1)
			else
				keys.caster:RemoveItem(keys.ability)
			end
		end
	else
		keys.ability:EndCooldown()
	end
end

function OnCreatedItem2021Buff(keys)
	local target = keys.target	
	local bonus = keys.bonus	
	target:THTD_AddManaRegenPercentage(bonus, "thtd_item_2021_bonus")
	target:THTD_AddAttackSpeed(bonus, "thtd_item_2021_bonus")
	target:THTD_AddCritChance(bonus, "thtd_item_2021_bonus")
	target:THTD_AddCritDamage(bonus, "thtd_item_2021_bonus")
	target:THTD_AddPowerPercentage(bonus, "thtd_item_2021_bonus")
	target:THTD_AddAttackPercentage(bonus, "thtd_item_2021_bonus")	
	target:SetModelScale(target:GetModelScale() * 1.25)
end

function OnRemoveItem2021Buff(keys)
	local target = keys.target	
	target:THTD_AddManaRegenPercentage("thtd_item_2021_bonus")
	target:THTD_AddAttackSpeed("thtd_item_2021_bonus")
	target:THTD_AddCritChance("thtd_item_2021_bonus")
	target:THTD_AddCritDamage("thtd_item_2021_bonus")
	target:THTD_AddPowerPercentage("thtd_item_2021_bonus")
	target:THTD_AddAttackPercentage("thtd_item_2021_bonus")
	target:SetModelScale(target:GetModelScale() / 1.25)
end

function OnItem2022_SpellStart(keys)
	if SpawnSystem.IsUnLimited then return end
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target

	if caster:IsRealHero() then
		if target:THTD_IsTower() and target:THTD_GetLevel()<THTD_MAX_LEVEL then
			target:THTD_SetLevel(THTD_MAX_LEVEL)
		else
			keys.ability:EndCooldown()	
		end
	end
end

function OnItem3146_SpellStart(keys)	
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target

	if caster:IsRealHero() == false then 
		CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_hero_use"})	
		return
	end	

	if target:THTD_IsTower() then	
		local maxLevel = target:GetMaxPowerLevel()
		local modifier = target:FindModifierByName("modifier_fairy_count")		
		if modifier == nil then 
			target:AddNewModifier(target, nil, "modifier_fairy_count", nil):SetStackCount(math.min(maxLevel,keys.point))
			target.thtd_power_from_item = (target.thtd_power_from_item or 0) + math.min(maxLevel,keys.point)
		else
			local count = modifier:GetStackCount()
			if count >= maxLevel then 
				CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="reach_to_limit"})	
				return
			end	
			target.thtd_power_from_item = (target.thtd_power_from_item or 0) + math.min(maxLevel - count, keys.point)
			count = math.min(maxLevel, count + keys.point)
			modifier:SetStackCount(count)	
			if target.thtd_power_level ~= nil then 
				target.thtd_power_level = count 
				target:AddPowerBonus()
			end			
		end
		target:EmitSound("Quest.Completed")	
		Service:SavePowerMaxCount(keys.ability.owner_player_id, false)		
		keys.ability:RemoveSelf()
	end
end

function OnItem3150_SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)	
	if not caster:THTD_IsTower() then return end

	local radius = 900
	local duration = 10

	if keys.ability.spell_effect ~= nil then 
		ParticleManager:DestroyParticle(keys.ability.spell_effect, true)
	end	
	local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_riki/riki_tricks.vpcf", PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 1, Vector(radius,radius,radius))
	ParticleManager:SetParticleControl(effectIndex, 2, Vector(duration,0,0))		
	keys.ability.spell_effect = effectIndex

	local damage = caster:THTD_GetStarDamage() * keys.power_damage		
	local attackDamage = caster:THTD_GetAttack()
	local targets = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), radius)
	local count = 0
	for k,v in pairs(targets) do
		count = count + 1
		if count <= 3 then 
		-- 多了造成卡顿，改为取消普通攻击动画实现
		--倒数第二个参数：bFakeAttack如果为true，则不会造成伤害
		--第三个参数如果为false，则会触发OnAttack事件，但是不会触发其余的几个事件（start、land、finish），这样有些攻击命中才生效的逻辑就不会触发了
		--PerformAttack(handle hTarget, bool bUseCastAttackOrb, bool bProcessProcs, bool bSkipCooldown, bool bIgnoreInvis, bool bUseProjectile, bool bFakeAttack, bool bNeverMiss)
			caster:PerformAttack(v,true,true,true,false,false,false,true)
		end

		local DamageTable = {
				ability = keys.ability,
				victim = v, 
				attacker = caster, 
				damage = damage, 
				damage_type = DAMAGE_TYPE_PHYSICAL, 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
		}
		if count > 3 then
			DamageTable.damage = DamageTable.damage + attackDamage
		end
		UnitDamageTarget(DamageTable)			
	end	
end

function OnItem3151_SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target
	if keys.ability:IsCooldownReady() then
		keys.ability:StartCooldown(keys.ability:GetCooldown(0))
	else
		return
	end		

	target:EmitSound("Hero_Spirit_Breaker.Charge.Impact")
	local effectIndex = ParticleManager:CreateParticle("particles/dzz/qingshanjiansheng_yjzcs.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
	ParticleManager:DestroyParticleSystem(effectIndex,false)

	local damage = caster:THTD_GetStarDamage() * keys.power_damage	
	local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), keys.range)
	for k,v in pairs(targets) do
		local DamageTable = {
				ability = keys.ability,
				victim = v, 
				attacker = caster, 
				damage = damage, 
				damage_type = DAMAGE_TYPE_MAGICAL, 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
		}
		UnitDamageTarget(DamageTable)		
	end	
end

local item3152_effect_caster = {
	"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crowrotating.vpcf",
	"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crowrotating_b.vpcf",
	"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crow.vpcf",
}
local item3152_effect_target = {
	"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff.vpcf",
	"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_creep.vpcf",
}

function OnItem3152_SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target	
	
	if keys.ability:IsCooldownReady() then
		keys.ability:StartCooldown(keys.ability:GetCooldown(0))
	else
		return
	end		

	if caster.item3152_effect ~= nil then 	
		ParticleManager:DestroyParticleSystem(caster.item3152_effect, true)
	end
	local effectIndex = ParticleManager:CreateParticle(item3152_effect_caster[RandomInt(1, #item3152_effect_caster)], PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
	caster.item3152_effect = effectIndex	

	local effectIndex = ParticleManager:CreateParticle(item3152_effect_target[RandomInt(1, #item3152_effect_target)], PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "attach_hitloc", Vector(0,0,0), true)
	ParticleManager:DestroyParticleSystem(effectIndex,false)

	if not caster:THTD_IsTower() then return end

	local damage = caster:THTD_GetStarDamage() * keys.power_damage	
	local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), keys.range)
	for k,v in pairs(targets) do
		if not v:HasModifier("modifier_item_3152_debuff") then
			keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_item_3152_debuff", nil)
		end
		local DamageTable = {
				ability = keys.ability,
				victim = v, 
				attacker = caster, 
				damage = damage, 
				damage_type = DAMAGE_TYPE_PURE, 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
		}
		UnitDamageTarget(DamageTable)		
	end	
end

function OnCreatedItem3150(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3150_bonus")
	caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3150_bonus")
end

function OnDestroyItem3150(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower("item_3150_bonus")
	caster:THTD_AddBaseAttack("item_3150_bonus")

	local ability = keys.ability
	if ability.spell_effect then
		ParticleManager:DestroyParticle(ability.spell_effect, true)
		ability.spell_effect = nil			
	end	
end

function OnCreatedItem3151(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3151_bonus")
	caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3151_bonus")
end

function OnDestroyItem3151(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower("item_3151_bonus")
	caster:THTD_AddBaseAttack("item_3151_bonus")
end

function OnCreatedItem3152(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3152_bonus")
	caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3152_bonus")
end

function OnDestroyItem3152(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower("item_3152_bonus")
	caster:THTD_AddBaseAttack("item_3152_bonus")
end

function OnCreatedItem3153(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3153_bonus")
	caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3153_bonus")

	local effectIndex = ParticleManager:CreateParticle("particles/econ/items/monkey_king/mk_ti9_immortal/mk_ti9_immortal_army_ring.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
	ParticleManager:SetParticleControl(effectIndex, 1, Vector(700,50,1))
	caster.item3153_effect = effectIndex
	
	local count = 0
	caster:SetContextThink(DoUniqueString("thtd_item3153_cast"), 
		function()
			count = count + 1
			if count > 50 then 
				if caster.item3153_effect ~= nil then 
					ParticleManager:DestroyParticle(caster.item3153_effect, true)
					caster.item3153_effect = nil
					return nil
				end
			else
				if caster.item3153_effect ~= nil then
					ParticleManager:SetParticleControl(effectIndex, 1, Vector(700 - count * 15,50,1))
				end
				return 0.1
			end
		end,
	0)
end

function OnDestroyItem3153(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster:IsRealHero() then 
		return
	end		
	
	caster:THTD_AddBasePower("item_3153_bonus")
	caster:THTD_AddBaseAttack("item_3153_bonus")

	if caster.item3153_effect ~= nil then 
		ParticleManager:DestroyParticle(caster.item3153_effect, true)
	end

	caster:RemoveModifierByNameAndCaster("modifier_junko_01", caster)
end

function OnItem3153_SpellStart(keys)	
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target
	if caster:IsRealHero() then return end
	if keys.ability:IsCooldownReady() then
		keys.ability:StartCooldown(keys.ability:GetCooldown(0))
	else
		return
	end			

	local damageType = DAMAGE_TYPE_PURE
	local pureDg = caster:GetDamageOutgoingPure()
	local magicDg = caster:GetDamageOutgoingMagical()
	local phyDg = caster:GetDamageOutgoingPhysical()
	if pureDg >= magicDg and pureDg >= phyDg then
		damageType = DAMAGE_TYPE_PURE
	elseif magicDg >= pureDg and magicDg >= phyDg then
		damageType = DAMAGE_TYPE_MAGICAL
	elseif phyDg >= magicDg and phyDg >= pureDg then
		damageType = DAMAGE_TYPE_PHYSICAL
	end

	local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_omniknight/omniknight_purification.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, target:GetAbsOrigin())
	ParticleManager:SetParticleControl(effectIndex, 1, Vector(100,30,900))
	ParticleManager:DestroyParticleSystemTime(effectIndex, 2.5)

	local damage = caster:THTD_GetStarDamage() * keys.power_damage	
	local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), 700)
	for k,v in pairs(targets) do
		if not v:HasModifier("modifier_item_3153_debuff") then 
			keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_item_3153_debuff", nil)
		end

		local DamageTable = {
				ability = keys.ability,
				victim = v, 
				attacker = caster, 
				damage = damage, 
				damage_type = damageType, 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
		}
		UnitDamageTarget(DamageTable)		
	end	
end

function OnCreatedItem3153Debuff(keys)	
	keys.target:AddDamageIncomingAll(keys.damage_debuff, "thtd_item_3153_damage_up")
end

function OnDestroyItem3153Debuff(keys)		
	keys.target:AddDamageIncomingAll("thtd_item_3153_damage_up")
end