function OnSpellStartKyouko01(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)	
	local targetPoint = keys.ability:GetCursorPosition()
	local effects = {
		"particles/units/heroes/hero_queenofpain/queen_sonic_wave.vpcf",
		"particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave.vpcf",
		"particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave_v2.vpcf",
	}

	local powerDamageUp = 0
	local pv = caster:GetAbilityPowerValue("thtd_kyouko_01")
	if pv ~= nil then 					
		powerDamageUp = pv[1]	
	end
	caster.thtd_kyouko_01_damage_up = keys.damage_up + powerDamageUp
		
	if caster:IsPower999() then 
		if caster.kyouko_power999_bonus ~= true then 
			caster:THTD_AddCritChance(75)
			caster:THTD_AddCritDamage(500)
			caster.kyouko_power999_bonus = true
		end		
	else
		if caster.kyouko_power999_bonus == true then
			caster:THTD_AddCritChance(-75)
			caster:THTD_AddCritDamage(-500)
			caster.kyouko_power999_bonus = nil
		end
	end

	local direction = (targetPoint - caster:GetAbsOrigin()):Normalized()
	direction.z = 0

	if caster:IsPower666() then 
		local count = 3
		caster:SetContextThink(DoUniqueString("dota_timer"), 
			function() 				
				if GameRules:IsGamePaused() then return 0.1 end
				count = count - 1
				if count < 0 then 				
					return nil 
				end 
				
				local info = 
				{
					Ability = keys.ability,
					EffectName = effects[#effects - count],
					vSpawnOrigin = caster:GetAbsOrigin(),
					fDistance = keys.distance,
					fStartRadius = keys.starting_aoe,
					fEndRadius = keys.final_aoe,
					Source = caster,
					iSourceAttachment = "mouth",
					bHasFrontalCone = false,
					bReplaceExisting = false,
					iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
					iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
					iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
					fExpireTime = GameRules:GetGameTime() + 10.0,
					bDeleteOnHit = false,
					vVelocity = direction * keys.speed,
					bProvidesVision = false,
					ExtraData = {}
				}
				ProjectileManager:CreateLinearProjectile(info)
				return 1.0
			end, 
		0)
	else	
		local info = 
		{
			Ability = keys.ability,
			EffectName = effects[RandomInt(1, #effects)],
			vSpawnOrigin = caster:GetAbsOrigin(),
			fDistance = keys.distance,
			fStartRadius = keys.starting_aoe,
			fEndRadius = keys.final_aoe,
			Source = caster,
			iSourceAttachment = "mouth",
			bHasFrontalCone = false,
			bReplaceExisting = false,
			iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
			iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
			iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
			fExpireTime = GameRules:GetGameTime() + 10.0,
			bDeleteOnHit = false,
			vVelocity = direction * keys.speed,
			bProvidesVision = false,
			ExtraData = {}
		}
		ProjectileManager:CreateLinearProjectile(info)
	end
end

function OnProjectileHitUnitKyouko01(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target
	local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + (caster.thtd_byakuren_buff_kyouko or 0)/100)

	local crit = 1.0
	local modifier = target:FindModifierByName("modifier_thtd_kyouko_01_debuff")
	if modifier ~= nil then 
		local count = modifier:GetStackCount()
		crit = crit + count * caster.thtd_kyouko_01_damage_up/100
		modifier:SetStackCount(math.min(999, count+1))
	else
		keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_thtd_kyouko_01_debuff", nil):SetStackCount(1)
	end

	local DamageTable = {
			ability = keys.ability,
	        victim = target, 
	        attacker = caster, 
	        damage = damage * crit, 
	        damage_type = keys.ability:GetAbilityDamageType(), 
	        damage_flags = DOTA_DAMAGE_FLAG_NONE
   	}
	UnitDamageTarget(DamageTable)
end


function OnSpellStartKyouko02(keys)
	local caster = keys.caster	

	if caster:IsPower999() then 
		if caster.kyouko_power999_bonus ~= true then 
			caster:THTD_AddCritChance(75)
			caster:THTD_AddCritDamage(500)
			caster.kyouko_power999_bonus = true
		end		
	else
		if caster.kyouko_power999_bonus == true then
			caster:THTD_AddCritChance(-75)
			caster:THTD_AddCritDamage(-500)
			caster.kyouko_power999_bonus = nil
		end
	end
	
	caster.thtd_kyouko_02_first = true

	if caster:IsPower666() then 
		local count = 3
		caster:SetContextThink(DoUniqueString("dota_timer"), 
			function() 				
				if GameRules:IsGamePaused() then return 0.1 end
				if count == 2 then caster.thtd_kyouko_02_first = false end
				count = count - 1
				if count < 0 then 				
					return nil 
				end				
				OnSpellStartKyouko02Work(keys)
				return 0.9
			end, 
		0)
	else	
		OnSpellStartKyouko02Work(keys)
	end
end

function OnSpellStartKyouko02Work(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]

	local effects = {
		[1] = {
			["start"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_start.vpcf",
			["ground"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_ground.vpcf",
			["proj"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_proj.vpcf",
		},
		[2] = {
			["start"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_start_v2.vpcf",
			["ground"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_ground_v2.vpcf",
			["proj"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_proj_v2.vpcf",
		},
	}
	local effectTable = effects[RandomInt(1,2)]

	local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)

	-- if #targets > 0 then
	-- 	EmitSoundOnLocationWithCaster(targetPoint, "Hero_EarthShaker.EchoSlam", caster)
	-- else		
	-- 	EmitSoundOnLocationWithCaster(targetPoint, "Hero_EarthShaker.EchoSlamSmall", caster)
	-- end

	-- caster:SetContextThink(DoUniqueString("OnSpellStartKyouko02"), 
	-- 	function()
	-- 		if #targets == 2 then
	-- 			local random_response = RandomInt(1, 4)
	-- 			if random_response >= 3 then random_response = random_response + 1 end	
	-- 			EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_0"..random_response, caster)
	-- 		elseif #targets >= 3 then
	-- 			EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_03", caster)
	-- 		elseif #targets == 0 then				
	-- 			EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_0"..(RandomInt(6, 7)), caster)
	-- 		end
	-- 		return nil
	-- 	end,
	-- 0.5)

	local powerDamage = 0
	local pv = caster:GetAbilityPowerValue("thtd_kyouko_02")
	if pv ~= nil then 					
		powerDamage = pv[1]	
	end
	caster.thtd_kyouko_02_damage = (keys.power_damage + powerDamage) * caster:THTD_GetStarDamage()

	local effect_counter = 0
	
	local count = 0
	for _, enemy in pairs(targets) do	
		count = count + 1		
		if count%5 == 0 then 
			if effect_counter < 5 then 
				effect_counter = effect_counter + 1
			end
			caster:SetContextThink(DoUniqueString("OnSpellStartKyouko02"), 
				function()					
					local echo_slam_death_pfx = ParticleManager:CreateParticle(effectTable["ground"], PATTACH_ABSORIGIN, enemy)
					ParticleManager:SetParticleControl(echo_slam_death_pfx, 6, Vector(math.min(effect_counter, 1), math.min(effect_counter, 1), math.min(effect_counter, 1)))
					ParticleManager:SetParticleControl(echo_slam_death_pfx, 10, Vector(keys.duration_time + 1, 0, 0)) -- earth particle duration
					ParticleManager:ReleaseParticleIndex(echo_slam_death_pfx)
					return nil
				end,
			0.1)
		end

		local crit = 1.0
		local modifier = enemy:FindModifierByName("modifier_thtd_kyouko_01_debuff")
		if modifier ~= nil then 
			crit = crit + modifier:GetStackCount() * caster.thtd_kyouko_01_damage_up/100				
		end

		if caster.thtd_kyouko_02_first == true then UnitStunTarget(caster,enemy,keys.duration_time) end
		local DamageTable = {
			ability = keys.ability,
	        victim = enemy, 
	        attacker = caster, 
	        damage = caster.thtd_kyouko_02_damage * crit, 
	        damage_type = keys.ability:GetAbilityDamageType(), 
	        damage_flags = DOTA_DAMAGE_FLAG_NONE
   		}
   		UnitDamageTarget(DamageTable)
		if enemy.is_random_boss == true then
			local pfx_screen = ParticleManager:CreateParticleForPlayer("particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_aftershock_screen.vpcf", PATTACH_ABSORIGIN_FOLLOW, enemy, caster:GetPlayerOwner())
			ParticleManager:ReleaseParticleIndex(pfx_screen)
		end		
		
		local echo_enemies = THTD_FindUnitsInRadius(caster,enemy:GetAbsOrigin(),keys.range)
		
		for _, echo_enemy in pairs(echo_enemies) do
			if echo_enemy ~= enemy then
				-- echo_enemy:EmitSound("Hero_EarthShaker.EchoSlamEcho")				
				ProjectileManager:CreateTrackingProjectile(
				{
					Target 				= echo_enemy,
					Source 				= enemy,
					Ability 			= keys.ability,
					EffectName 			= effectTable["proj"],
					iMoveSpeed			= 1100,
					vSourceLoc 			= enemy:GetAbsOrigin(),
					bDrawsOnMinimap 	= false,
					bDodgeable 			= false,
					bIsAttack 			= false,
					bVisibleToEnemies 	= true,
					bReplaceExisting 	= false,
					flExpireTime 		= GameRules:GetGameTime() + 10.0,
					bProvidesVision 	= false,
					ExtraData = {}
				})
			end
		end
	end

	local echo_slam_particle = ParticleManager:CreateParticle(effectTable["start"], PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControl(echo_slam_particle, 0, targetPoint) 
	ParticleManager:SetParticleControl(echo_slam_particle, 10, Vector(keys.duration_time + 1, 0, 0)) 
	ParticleManager:SetParticleControl(echo_slam_particle, 11, Vector(math.min(#targets, 1), math.min(#targets, 1), 0 )) 
	ParticleManager:ReleaseParticleIndex(echo_slam_particle)

end

function OnProjectileHitUnitKyouko02(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target
	
	if caster.thtd_kyouko_02_first == true then UnitStunTarget(caster,target,keys.duration_time) end

	local crit = 1.0
	local modifier = target:FindModifierByName("modifier_thtd_kyouko_01_debuff")
	if modifier ~= nil then 
		crit = crit + modifier:GetStackCount() * caster.thtd_kyouko_01_damage_up/100				
	end

	local DamageTable = {
		ability = keys.ability,
		victim = target, 
		attacker = caster, 
		damage = caster.thtd_kyouko_02_damage * crit, 
		damage_type = keys.ability:GetAbilityDamageType(), 
		damage_flags = DOTA_DAMAGE_FLAG_NONE
   	}
   	UnitDamageTarget(DamageTable)
end