local thtd_hecatia_model_list = 
{
	[1] = "models/new_touhou_model/hecatia/hecatia_earth/hecatia_earth.vmdl",
	[2] = "models/new_touhou_model/hecatia/hecatia_moon/hecatia_moon.vmdl",
	[3] = "models/new_touhou_model/hecatia/hecatia.vmdl",
}

local HECATIA_TYPE_EARTH = 1
local HECATIA_TYPE_MOON = 2
local HECATIA_TYPE_OTHERWORLD = 3

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

	if caster.thtd_hecatia_ball_table == nil then
		caster.thtd_hecatia_ball_table = {}
		caster.thtd_hecatia_ball_table["earth"] = nil
		caster.thtd_hecatia_ball_table["moon"] = nil
		caster.thtd_hecatia_ball_table["otherworld"] = nil
	end

	caster.thtd_hecatia_01_think_count = 0
	
	if caster.thtd_hecatia_ball_table["earth"] == nil then
		local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_earth.vpcf", PATTACH_CUSTOMORIGIN, caster)
		ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
		ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.4,0,0))
		ParticleManager:SetParticleControl(effectIndex, 2, Vector(200,0,0))

		caster.thtd_hecatia_ball_table["earth"] = 
		{
			["Vector"] = targetPoint + Vector(0,0,128),
			["EffectIndex"] = effectIndex
		}
	else
		caster.thtd_hecatia_ball_table["earth"]["Vector"] = targetPoint + Vector(0,0,128)
	end
end

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

	if caster.thtd_hecatia_ball_table == nil then
		caster.thtd_hecatia_ball_table = {}
		caster.thtd_hecatia_ball_table["earth"] = nil
		caster.thtd_hecatia_ball_table["moon"] = nil
		caster.thtd_hecatia_ball_table["otherworld"] = nil
	end	

	caster.thtd_hecatia_01_think_count = 0

	if caster.thtd_hecatia_ball_table["moon"] == nil then
		local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_moon.vpcf", PATTACH_CUSTOMORIGIN, caster)
		ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
		ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.3,0,0))
		ParticleManager:SetParticleControl(effectIndex, 2, Vector(150,0,0))

		caster.thtd_hecatia_ball_table["moon"] = 
		{
			["Vector"] = targetPoint + Vector(0,0,128),
			["EffectIndex"] = effectIndex
		}
	else
		caster.thtd_hecatia_ball_table["moon"]["Vector"] = targetPoint + Vector(0,0,128)
	end
end

function OnHecatia03SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]
	
	if caster.thtd_hecatia_ball_table == nil then
		caster.thtd_hecatia_ball_table = {}
		caster.thtd_hecatia_ball_table["earth"] = nil
		caster.thtd_hecatia_ball_table["moon"] = nil
		caster.thtd_hecatia_ball_table["otherworld"] = nil
	end

	caster.thtd_hecatia_01_think_count = 0	
	
	if caster.thtd_hecatia_ball_table["otherworld"] == nil then		
		local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_otherworld.vpcf", PATTACH_CUSTOMORIGIN, caster)
		ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
		ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.4,0,0))
		ParticleManager:SetParticleControl(effectIndex, 2, Vector(200,0,0))

		caster.thtd_hecatia_ball_table["otherworld"] = 
		{
			["Vector"] = targetPoint + Vector(0,0,128),			
			["CurPoint"] = targetPoint + Vector(0,0,128),
			["EffectIndex"] = effectIndex
		}	
	else
		local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
		if not hasCombo then	
			caster.thtd_hecatia_ball_table["otherworld"]["Vector"] = targetPoint + Vector(0,0,128)
		else
			caster.thtd_hecatia_ball_table["otherworld"]["Vector"] = targetPoint + Vector(0,0,128)		
			caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = targetPoint + Vector(0,0,128)	
			caster.thtd_hecatia_ball_midOrigin = targetPoint + Vector(0,0,128)
			ParticleManager:SetParticleControl(caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"], 0, targetPoint + Vector(0,0,128))
		end
	end
end

function HecatiaRemoveAllBall(caster)
	if caster.thtd_hecatia_ball_table == nil then
		caster.thtd_hecatia_ball_table = {}
		caster.thtd_hecatia_ball_table["earth"] = nil
		caster.thtd_hecatia_ball_table["moon"] = nil
		caster.thtd_hecatia_ball_table["otherworld"] = nil
	end

	if caster.thtd_hecatia_ball_table["earth"] ~= nil then
		local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
		ParticleManager:DestroyParticleSystem(effectIndex,true)
	end
	if caster.thtd_hecatia_ball_table["moon"] ~= nil then
		local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
		ParticleManager:DestroyParticleSystem(effectIndex,true)
	end
	if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
		local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
		ParticleManager:DestroyParticleSystem(effectIndex,true)
	end
	if caster.thtd_hecatia_ball_midOrigin ~= nil then
		caster.thtd_hecatia_ball_midOrigin = nil
	end
	if caster.thtd_hecatia_01_think_count ~= nil then
		caster.thtd_hecatia_01_think_count = nil
	end

	caster.thtd_hecatia_ball_table = {}
end

local MIN_RADIUS = 300
function OnHecatia01Think(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	if caster.thtd_hecatia_ball_table == nil then
		caster.thtd_hecatia_ball_table = {}
		caster.thtd_hecatia_ball_table["earth"] = nil
		caster.thtd_hecatia_ball_table["moon"] = nil
		caster.thtd_hecatia_ball_table["otherworld"] = nil
	end
	if caster.cast_factor == nil then 
		caster.cast_factor = 10  -- 卡顿优化，每0.3秒释放一次技能（原0.03）
	end

	if caster.thtd_hecatia_01_think_count == nil then
		caster.thtd_hecatia_01_think_count = 0
	end

	if caster.thtd_hecatia_01_think_count < 360 then
		caster.thtd_hecatia_01_think_count = caster.thtd_hecatia_01_think_count + 1
	else
		caster.thtd_hecatia_01_think_count = 0
	end	

	if caster.thtd_hecatia_01_think_count_moon == nil then
		caster.thtd_hecatia_01_think_count_moon = 0
	end

	local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
	if caster.thtd_hecatia_01_think_count_moon < 360 then
		if hasCombo then 
			caster.thtd_hecatia_01_think_count_moon = caster.thtd_hecatia_01_think_count_moon + 2
		else
			caster.thtd_hecatia_01_think_count_moon = caster.thtd_hecatia_01_think_count_moon + 1
		end
	else
		caster.thtd_hecatia_01_think_count_moon = 0
	end

	if caster==nil or caster:IsNull()==true or caster:IsAlive()==false or caster:THTD_IsHidden() then
		HecatiaRemoveAllBall(caster)
	end

	if caster:FindAbilityByName("thtd_hecatia_04"):GetLevel() >= 1 and caster.thtd_hecatia_04_lock ~= true then
		OnHecatiaTriggerTriangle(caster)
	end	

	if caster.thtd_hecatia_ball_table ~= nil then
		if caster.thtd_hecatia_ball_table["earth"] ~= nil then
			if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
				if not hasCombo then
					local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
					local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"], 
																caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))

					local midOrigin = (caster.thtd_hecatia_ball_table["earth"]["Vector"] + caster.thtd_hecatia_ball_table["otherworld"]["Vector"])/2					
					local point = midOrigin + 
						Vector(
							math.cos(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
							math.sin(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
							0)

					ParticleManager:SetParticleControl(effectIndex, 0, point)
					caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point
					if caster.thtd_hecatia_ball_midOrigin ~= midOrigin then 	
						caster.thtd_hecatia_ball_midOrigin = midOrigin
					end
				else
					local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
					local distance = math.max(MIN_RADIUS * 2, GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"], 
																caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
					local curPoint = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]

					if caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] ~= nil then
						curPoint = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
					end

					local point = curPoint + 
						Vector(
							math.cos(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
							math.sin(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
							0)

					ParticleManager:SetParticleControl(effectIndex, 0, point)
					caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point

					if caster.thtd_hecatia_ball_midOrigin ~= caster.thtd_hecatia_ball_table["otherworld"]["Vector"] then 	
						caster.thtd_hecatia_ball_midOrigin = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]
					end
				end				
			else
				local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
				local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["earth"]["Vector"]))
				local point = caster:GetOrigin() + 
					Vector(
						math.cos(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
						math.sin(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
						128)
				ParticleManager:SetParticleControl(effectIndex, 0, point)
				caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point				
			end
			if caster.cast_factor >= 10 then 
				OnHecatiaEarthHit(caster)					
			end					
		end

		if caster.thtd_hecatia_ball_table["moon"] ~= nil then
			if caster.thtd_hecatia_ball_table["earth"] ~= nil then
				local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
				local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"], 
															caster.thtd_hecatia_ball_table["moon"]["Vector"]))
				local curPoint = caster.thtd_hecatia_ball_table["earth"]["Vector"]

				if caster.thtd_hecatia_ball_table["earth"]["CurPoint"] ~= nil then
					curPoint = caster.thtd_hecatia_ball_table["earth"]["CurPoint"]
				end

				local point = curPoint + 
					Vector(
						math.cos(caster.thtd_hecatia_01_think_count_moon * math.pi/90)*distance,
						math.sin(caster.thtd_hecatia_01_think_count_moon * math.pi/90)*distance,
						0)

				ParticleManager:SetParticleControl(effectIndex, 0, point)
				caster.thtd_hecatia_ball_table["moon"]["CurPoint"] = point
			else
				local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
				local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["moon"]["Vector"]))
				local point = caster:GetOrigin() + 
					Vector(
						math.cos(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
						math.sin(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
						128)
				ParticleManager:SetParticleControl(effectIndex, 0, point)
				caster.thtd_hecatia_ball_table["moon"]["CurPoint"] = point
			end
			if caster.cast_factor >= 10 then 
				OnHecatiaMoonHit(caster)			
			end				
		end

		if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
			if not hasCombo then
				if caster.thtd_hecatia_ball_table["earth"] ~= nil then
					local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
					local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"], 
																caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
	
					local midOrigin = (caster.thtd_hecatia_ball_table["earth"]["Vector"] + caster.thtd_hecatia_ball_table["otherworld"]["Vector"])/2
					local point = midOrigin + 
						Vector(
							math.cos((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
							math.sin((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
							0)
	
					ParticleManager:SetParticleControl(effectIndex, 0, point)
					caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = point
					if caster.thtd_hecatia_ball_midOrigin ~= midOrigin then 	
						caster.thtd_hecatia_ball_midOrigin = midOrigin
					end
				else
					local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
					local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
					local point = caster:GetOrigin() + 
						Vector(
							math.cos((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
							math.sin((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
							128)
					ParticleManager:SetParticleControl(effectIndex, 0, point)
					caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = point
				end
			else
				if caster.thtd_hecatia_ball_table["earth"] ~= nil then
					if caster.thtd_hecatia_ball_midOrigin ~= caster.thtd_hecatia_ball_table["otherworld"]["Vector"] then 	
						caster.thtd_hecatia_ball_midOrigin = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]
					end
				end
			end	
			if caster.cast_factor >= 10 then 
				OnHecatiaOtherworldHit(caster)
			end		
		end
	end

	if caster.cast_factor >= 10 then 
		caster.cast_factor = 0
		RefreshBonus(caster)
	else
		caster.cast_factor = caster.cast_factor + 1
	end
end

function RefreshBonus(caster)
	if caster.thtd_hecatia_ball_table["earth"] ~= nil then 
		caster:THTD_AddPowerPercentage(caster:GetAbilityValue("thtd_hecatia_01", "power_up"), "thtd_hecatia_01_bonus")
	else
		caster:THTD_AddPowerPercentage("thtd_hecatia_01_bonus")	
	end
	if caster.thtd_hecatia_ball_table["moon"] ~= nil then 
		caster:THTD_AddCritChance(caster:GetAbilityValue("thtd_hecatia_02", "chance"), "thtd_hecatia_02_bonus")
		caster:THTD_AddCritDamage(caster:GetAbilityValue("thtd_hecatia_02", "crit"), "thtd_hecatia_02_bonus")
	else
		caster:THTD_AddCritChance("thtd_hecatia_02_bonus")
		caster:THTD_AddCritDamage("thtd_hecatia_02_bonus")
	end
	if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then 
		caster:AddDamageOutgoingAll(caster:GetAbilityValue("thtd_hecatia_03", "damage_up"), "thtd_hecatia_03_bonus")
	else
		caster:AddDamageOutgoingAll("thtd_hecatia_03_bonus")
	end
end

function OnHecatiaEarthHit(caster)	
	local earthOrigin = caster.thtd_hecatia_ball_table["earth"]["CurPoint"]	
	local ability = caster:FindAbilityByName("thtd_hecatia_01")	
	if caster.thtd_hecatia_change_type == HECATIA_TYPE_EARTH then		
		if caster.thtd_hecatia_triangle_count == nil or caster.thtd_hecatia_triangle_count == 0 then
			OnHecatiaCreateTriangle(caster)
		end

		local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)		
		local range = ability:GetSpecialValueFor("range1")

		local targets = THTD_FindUnitsInRadius(caster,earthOrigin, range)
		for k,v in pairs(targets) do
			if not v:HasModifier("modifier_hecatia_01_earth_lock") then 
				ability:ApplyDataDrivenModifier(caster, v, "modifier_hecatia_01_earth_lock", {})		
				ability:ApplyDataDrivenModifier(caster, v, "modifier_thtd_hecatia_01_debuff", {})		
				local DamageTable = {
					ability = ability,
					victim = v, 
					attacker = caster, 
					damage = damage, 
					damage_type = ability:GetAbilityDamageType(), 
					damage_flags = DOTA_DAMAGE_FLAG_NONE,					
				}
				UnitDamageTarget(DamageTable)
			end
		end		
	else		
		local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)		
		local range = ability:GetSpecialValueFor("range2")

		local targets = THTD_FindUnitsInRadius(caster,earthOrigin, range)	
		for k,v in pairs(targets) do
			local targetOrigin = v:GetOrigin()
			local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_earth_rain.vpcf", PATTACH_CUSTOMORIGIN, caster)
			ParticleManager:SetParticleControl(effectIndex , 0, targetOrigin)
			ParticleManager:DestroyParticleSystemTime(effectIndex,0.5)
			
			local DamageTable = {
				ability = ability,
				victim = v, 
				attacker = caster, 
				damage = damage, 
				damage_type = ability:GetAbilityDamageType(), 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
			}
			UnitDamageTarget(DamageTable)
		end
	end
end

function OnHecatiaMoonHit(caster)
	local moonOrigin = caster.thtd_hecatia_ball_table["moon"]["CurPoint"]
	local ability = caster:FindAbilityByName("thtd_hecatia_02")	

	if caster.thtd_hecatia_change_type == HECATIA_TYPE_MOON then
		if caster.thtd_hecatia_triangle_count == 1 then
			OnHecatiaCreateTriangle(caster)
		end	

		local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)	
		local range = ability:GetSpecialValueFor("range1")
		local backDistance = ability:GetSpecialValueFor("back_distance")
		
		local targets = THTD_FindUnitsInRadius(caster,moonOrigin, range)	
		for k,v in pairs(targets) do
			if not v:HasModifier("modifier_hecatia_01_moon_lock") then 
				ability:ApplyDataDrivenModifier(caster, v, "modifier_hecatia_01_moon_lock", {})	

				local forward = (v:GetAbsOrigin()-Vector(moonOrigin.x,moonOrigin.y,0)):Normalized()
				v:SetAbsOrigin(v:GetOrigin()+forward*backDistance)
				FindClearSpaceForUnit(v, v:GetOrigin(), false)

				local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_hit.vpcf", PATTACH_CUSTOMORIGIN, caster)
				ParticleManager:SetParticleControl(effectIndex , 0, moonOrigin+Vector(0,0,64))
				ParticleManager:DestroyParticleSystem(effectIndex,false)			
				
				local DamageTable = {
					ability = ability,
					victim = v, 
					attacker = caster, 
					damage = damage, 
					damage_type = ability:GetAbilityDamageType(), 
					damage_flags = DOTA_DAMAGE_FLAG_NONE,					
				}
				UnitDamageTarget(DamageTable)
			end
		end	
	else		
		local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
		local range = ability:GetSpecialValueFor("range2")

		local targets = THTD_FindUnitsInRadius(caster,moonOrigin,range)
		if #targets > 0 then 
			local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_reflex.vpcf", PATTACH_CUSTOMORIGIN, caster)
			ParticleManager:SetParticleControl(effectIndex , 0, caster:GetOrigin())
			ParticleManager:SetParticleControl(effectIndex , 1, moonOrigin+Vector(0,0,64))
			ParticleManager:SetParticleControl(effectIndex , 9, caster:GetOrigin())
			ParticleManager:DestroyParticleSystem(effectIndex,false)

			local targets = THTD_FindUnitsInRadius(caster,moonOrigin,range)
			local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
			for k,v in pairs(targets) do
				local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_reflex.vpcf", PATTACH_CUSTOMORIGIN, caster)
				ParticleManager:SetParticleControl(effectIndex , 0, caster.thtd_hecatia_ball_table["moon"]["CurPoint"]+Vector(0,0,64))
				ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
				ParticleManager:SetParticleControl(effectIndex , 9, caster.thtd_hecatia_ball_table["moon"]["CurPoint"]+Vector(0,0,64))
				ParticleManager:DestroyParticleSystem(effectIndex,false)				
				local DamageTable = {
					ability = ability,
					victim = v, 
					attacker = caster, 
					damage = damage, 
					damage_type = ability:GetAbilityDamageType(), 
					damage_flags = DOTA_DAMAGE_FLAG_NONE
				}
				UnitDamageTarget(DamageTable)
			end
		end
	end
end

function OnHecatiaOtherworldHit(caster)
	local otherworldOrigin = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
	local ability = caster:FindAbilityByName("thtd_hecatia_03")	

	if caster.thtd_hecatia_change_type == HECATIA_TYPE_OTHERWORLD then
		if caster.thtd_hecatia_triangle_count == 2 then
			OnHecatiaCreateTriangle(caster)
		end

		local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)		
		local activeRange = ability:GetSpecialValueFor("active_range")
		local fullRange = ability:GetSpecialValueFor("full_range")
		local suckTime = ability:GetSpecialValueFor("suck_duration")	

		local targetsFirst = THTD_FindUnitsInRadius(caster,otherworldOrigin, activeRange)
		if #targetsFirst > 0 then 
			if caster.thtd_hecatia_otherworld_think_lock ~= true then
				caster.thtd_hecatia_otherworld_think_lock = true
				local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_otherworld.vpcf", PATTACH_CUSTOMORIGIN, nil)
				local time = suckTime			
				local clearGroup = {}
				THTD_SetSpellLock(caster, "thtd_hecatia_03", suckTime)
				caster:SetContextThink(DoUniqueString("ability_hecatia_otherworld_think"), 
					function()
						if GameRules:IsGamePaused() then return 0.03 end
						if time <= 0 or caster==nil or caster:IsNull()==true or caster:IsAlive()==false or caster:THTD_IsHidden() then
							for k,v in pairs(clearGroup) do
								if v~=nil and v:IsNull()==false and v:IsAlive() then
									FindClearSpaceForUnit(v, v:GetOrigin(), false)
								end								
							end			
							clearGroup = {}			
							caster.thtd_hecatia_otherworld_think_lock = false
							ParticleManager:DestroyParticleSystem(effectIndex,true)
							return nil
						end

						local cur_origin = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
						local targets = THTD_FindUnitsInRadius(caster,cur_origin, fullRange)
						clearGroup = targets
						for k,v in pairs(targets) do
							local forward = (Vector(cur_origin.x,cur_origin.y,0)-v:GetAbsOrigin()):Normalized()
							v:SetAbsOrigin(v:GetOrigin()+forward*100)
							UnitStunTarget(caster,v,0.2)
							local DamageTable = {
								ability = ability,
								victim = v, 
								attacker = caster, 
								damage = damage, 
								damage_type = ability:GetAbilityDamageType(), 
								damage_flags = DOTA_DAMAGE_FLAG_NONE
							}
							UnitDamageTarget(DamageTable)							
						end

						ParticleManager:SetParticleControl(effectIndex , 0, cur_origin)
						ParticleManager:SetParticleControl(effectIndex , 2, cur_origin)
						time = time - 0.3
						return 0.3
					end,
				0)
			end
		end
	else		
		local range = ability:GetSpecialValueFor("range2")
		local targetsFirst = THTD_FindUnitsInRadius(caster,otherworldOrigin,range)
		if #targetsFirst > 0 then 
			if caster.thtd_hecatia_otherworld_hit_lock ~= true then
				caster.thtd_hecatia_otherworld_hit_lock = true
				-- caster.thtd_hecatia_otherworld_hit_list = {}
				caster:SetContextThink(DoUniqueString("ability_hecatia_hit_delay"), 
					function()
						if GameRules:IsGamePaused() then return 0.03 end

						local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)						
						local targets = THTD_FindUnitsInRadius(caster,otherworldOrigin,range)
						for k,v in pairs(targets) do						
							local DamageTable = {
								ability = ability,
								victim = v, 
								attacker = caster, 
								damage = damage, 
								damage_type = ability:GetAbilityDamageType(), 
								damage_flags = DOTA_DAMAGE_FLAG_NONE
							}
							UnitDamageTarget(DamageTable)							
						end

						caster.thtd_hecatia_otherworld_hit_lock = false					
						return nil
					end,
				0.5)

				local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
				for i=1,12 do
					local forward1 = Vector(math.cos(i*math.pi/6),math.sin(i*math.pi/6),0)
					local forward2 = Vector(math.cos(i*math.pi/6+math.pi/2),math.sin(i*math.pi/6+math.pi/2),0)
					local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_otherworld_projectile.vpcf", PATTACH_CUSTOMORIGIN, caster)	
					if hasCombo then 			
						ParticleManager:SetParticleControl(effectIndex, 0, otherworldOrigin + Vector(0,0,128))
					else
						ParticleManager:SetParticleControl(effectIndex, 0, otherworldOrigin + forward1 * 150 + Vector(0,0,128))
					end
					ParticleManager:SetParticleControl(effectIndex, 1, forward2 * 800)
					ParticleManager:DestroyParticleSystemTime(effectIndex, 0.9)
				end

				-- for i=1,12 do
					-- local forward1 = Vector(math.cos(i*math.pi/6),math.sin(i*math.pi/6),0)
					-- local forward2 = Vector(math.cos(i*math.pi/6+math.pi/2),math.sin(i*math.pi/6+math.pi/2),0)
					-- local info = 
					-- {
					-- 		Ability = ability,
					-- 		EffectName = "particles/heroes/thtd_hecatia/ability_hecatia_otherworld_projectile.vpcf",
					-- 		vSpawnOrigin = otherworldOrigin + forward1 * 100 + Vector(0,0,128),
					-- 		fDistance = range,
					-- 		fStartRadius = 150,
					-- 		fEndRadius = 150,
					-- 		Source = caster,
					-- 		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 = forward2 * 500,
					-- 		bProvidesVision = true,
					-- 		iVisionRadius = 1000,
					-- 		iVisionTeamNumber = caster:GetTeamNumber()
					-- }
					-- local projectile = ProjectileManager:CreateLinearProjectile(info)
					-- ParticleManager:DestroyLinearProjectileSystem(projectile,false)
				-- end
			end
		end
	end
end

-- function OnHecatiaProjectileHit(keys)
	-- local caster = EntIndexToHScript(keys.caster_entindex)
	-- local target = keys.target	

	-- for k,v in pairs(caster.thtd_hecatia_otherworld_hit_list) do
	-- 	if v == target then 
	-- 		return
	-- 	end
	-- end
	
	-- local damage = caster:THTD_GetAbilityPowerDamage(caster:FindAbilityByName("thtd_hecatia_03"), 2)
	-- local DamageTable = {
	-- 		ability = keys.ability,
	--         victim = target, 
	--         attacker = caster, 
	--         damage = damage, 
	--         damage_type = keys.ability:GetAbilityDamageType(), 
	-- 		damage_flags = DOTA_DAMAGE_FLAG_NONE,		
   	-- }
	-- UnitDamageTarget(DamageTable)
	-- table.insert(caster.thtd_hecatia_otherworld_hit_list, target)
-- end

function OnHecatia04Think(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)	
	
	if caster:GetTowerPowerLevel() >= 3 then 
		if caster.thtd_hecatia_change_list == nil or #caster.thtd_hecatia_change_list == 0 then 
			caster.thtd_hecatia_change_list = {HECATIA_TYPE_EARTH, HECATIA_TYPE_MOON, HECATIA_TYPE_OTHERWORLD, HECATIA_TYPE_EARTH, HECATIA_TYPE_MOON, HECATIA_TYPE_OTHERWORLD}
		end
		local index = RandomInt(1,#caster.thtd_hecatia_change_list)
		local randomType = caster.thtd_hecatia_change_list[index]
		table.remove(caster.thtd_hecatia_change_list, index)
		caster:SetModel(thtd_hecatia_model_list[randomType])
		caster:SetOriginalModel(thtd_hecatia_model_list[randomType])
		caster.thtd_hecatia_change_type = randomType
		return
	end

	local randomType = RandomInt(1,3)
	caster:SetModel(thtd_hecatia_model_list[randomType])
	caster:SetOriginalModel(thtd_hecatia_model_list[randomType])
	caster.thtd_hecatia_change_type = randomType

	-- local level = 1
	-- if GetHecatiaBallCount(caster) == 3 then 
	-- 	level = 2
	-- end
	-- for i=1,4 do
	-- 	local ability = caster:FindAbilityByName("thtd_hecatia_0"..tostring(i))
	-- 	if ability ~= nil and ability:GetLevel() ~= level then 
	-- 		ability:SetLevel(level)
	-- 	end
	-- end
end

function OnHecatiaCreateTriangle(caster)	
	if caster.thtd_hecatia_ball_midOrigin == nil then
		return 
	end

	if caster.thtd_hecatia_triangle_count == nil then
		caster.thtd_hecatia_triangle_count = 0
	end

	if caster.thtd_hecatia_triangle_table == nil then
		caster.thtd_hecatia_triangle_table = {}
	end

	if caster.thtd_hecatia_triangle_angle == nil then 
		caster.thtd_hecatia_triangle_angle = RandomInt(0, 360)
	end

	if caster.thtd_hecatia_triangle_count < 3 then
		local radius = 900
		local point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,caster.thtd_hecatia_triangle_angle,0), caster.thtd_hecatia_ball_midOrigin + Vector(0, radius, 0))
		caster.thtd_hecatia_triangle_count = caster.thtd_hecatia_triangle_count + 1
		if caster.thtd_hecatia_triangle_count == 2 then
			point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,120,0), point)
		elseif caster.thtd_hecatia_triangle_count == 3 then
			point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,240,0), point)
		end

		local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_triangle.vpcf", PATTACH_CUSTOMORIGIN, nil)
		ParticleManager:SetParticleControl(effectIndex , 0, point)
		ParticleManager:SetParticleControl(effectIndex , 3, point)
		
		caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count] = {}
		caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count]["EffectIndex"] = effectIndex
		caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count]["Origin"] = point
	end
end

function OnHecatiaTriggerTriangle(caster)	
	if caster.thtd_hecatia_triangle_count == nil then
		caster.thtd_hecatia_triangle_count = 0
	end

	if caster.thtd_hecatia_triangle_table == nil then
		caster.thtd_hecatia_triangle_table = {}
	end

	if caster.thtd_hecatia_triangle_count >= 3 and THTD_HasUnitsInRadius(caster, caster:GetAbsOrigin(), 1500) then			
		local ability = caster:FindAbilityByName("thtd_hecatia_04")	
		local duration = math.floor(ability:GetSpecialValueFor("duration_time")	* 100 + 0.5)/100
		local power_bonus = ability:GetSpecialValueFor("power_bonus")
		local durationDelay = 0
		local delayCount = 0
		local time = 0		
		local count = 0
		local triangleTable = caster.thtd_hecatia_triangle_table
		caster.thtd_hecatia_04_lock = true
			
		caster:SetContextThink(DoUniqueString("ability_hecatia_triangle_think"), 
			function()
				if GameRules:IsGamePaused() then return 0.03 end
				if time > duration + durationDelay or THTD_IsValid(caster) == false then
					ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[1]["EffectIndex"],true)
					ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[2]["EffectIndex"],true)
					ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[3]["EffectIndex"],true)
					triangleTable = {}
					caster.thtd_hecatia_triangle_table = {}
					caster.thtd_hecatia_triangle_count = 0
					caster.thtd_hecatia_triangle_angle = nil
					caster.thtd_hecatia_04_lock = false
					return nil
				end
				-- 改为三角连接和中心发射同时进行
				count = count + 1
				if count > 3 then
					count = 1
				end
				local countNext = count + 1
				if countNext > 3 then
					countNext = 1
				end

				local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
				ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[count]["Origin"])
				ParticleManager:SetParticleControl(effectIndex , 1, triangleTable[countNext]["Origin"])
				ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[count]["Origin"])
				ParticleManager:DestroyParticleSystem(effectIndex,false)

				local distance = GetDistanceBetweenTwoVec2D(triangleTable[count]["Origin"], triangleTable[countNext]["Origin"])
				local speed = 3000
				local delayTime = distance / speed
				time = time + delayTime	
				if delayCount < 3 then 
					delayCount = delayCount + 1
					durationDelay = delayTime

					if delayCount == 3 then 	
						caster:THTD_AddBasePower(power_bonus, "thtd_hecatia_04_buff")				
						caster:SetContextThink(DoUniqueString("dota_timer"), 
							function() 
								if GameRules:IsGamePaused() then return 0.1 end
								if time > duration + durationDelay or THTD_IsValid(caster) == false then
									caster:THTD_AddBasePower("thtd_hecatia_04_buff")	
									return nil
								end

								caster:SetContextThink(DoUniqueString("dota_timer"), 
									function() 
										local center,radius = GetCircleCenterAndRadius(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"]) 
										local targets = THTD_FindUnitsInRadius(caster,center,radius)									
										local damage = caster:THTD_GetAbilityPowerDamage(ability)
										for k,v in pairs(targets) do												
											if v ~= nil and v:IsNull() == false and v:IsAlive() and IsInTriangle(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"],v:GetAbsOrigin()) then																						
												local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
												ParticleManager:SetParticleControl(effectIndex , 0, center)
												ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
												ParticleManager:SetParticleControl(effectIndex , 9, center)
												ParticleManager:DestroyParticleSystem(effectIndex,false)

												local DamageTable = {
													ability = ability,
													victim = v, 
													attacker = caster, 
													damage = damage, 
													damage_type = ability:GetAbilityDamageType(), 
													damage_flags = DOTA_DAMAGE_FLAG_NONE
												}
												UnitDamageTarget(DamageTable)
											end
										end
										return nil
									end, 
								0.3)

								return 0.5
							end, 
						0)
					end

				end
				return delayTime

				-- 这个效果是三个三角依次连接后再从中心发射
				-- if count < 3 then
					-- count = count + 1

					-- local countNext = count + 1
					-- if countNext > 3 then
					-- 	countNext = 1
					-- end

					-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)

					-- ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[count]["Origin"])
					-- ParticleManager:SetParticleControl(effectIndex , 1, triangleTable[countNext]["Origin"])
					-- ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[count]["Origin"])
					-- ParticleManager:DestroyParticleSystem(effectIndex,false)

					-- local distance = GetDistanceBetweenTwoVec2D(triangleTable[count]["Origin"], triangleTable[countNext]["Origin"])
					-- local speed = 3000
					-- local delayTime = distance / speed
					-- time = time - delayTime		
					-- return delayTime
				-- else
					-- local center,radius = GetCircleCenterAndRadius(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"]) 
					-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)

					-- ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[1]["Origin"])
					-- ParticleManager:SetParticleControl(effectIndex , 1, caster.thtd_hecatia_ball_midOrigin)
					-- ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[1]["Origin"])
					-- ParticleManager:DestroyParticleSystem(effectIndex,false)

		            -- local distance = GetDistanceBetweenTwoVec2D(triangleTable[1]["Origin"], caster.thtd_hecatia_ball_midOrigin)
					-- local speed = 3000
					-- local delayTime = distance / speed

					-- caster:SetContextThink(DoUniqueString("ability_hecatia_04_delay"), 
					-- 	function()
					-- 		if GameRules:IsGamePaused() then return 0.03 end
					-- 		local damage = caster:THTD_GetAbilityPowerDamage(ability)							
					-- 		local targets = THTD_FindUnitsInRadius(caster,center,radius)
					-- 		for k,v in pairs(targets) do
					-- 			local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
					-- 			ParticleManager:SetParticleControl(effectIndex , 0, caster.thtd_hecatia_ball_midOrigin)
					-- 			ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
					-- 			ParticleManager:SetParticleControl(effectIndex , 9, caster.thtd_hecatia_ball_midOrigin)
					-- 			ParticleManager:DestroyParticleSystem(effectIndex,false)

					-- 			local DamageTable = {
					-- 				ability = ability,
					-- 		        victim = v, 
					-- 		        attacker = caster, 
					-- 		        damage = damage, 
					-- 		        damage_type = ability:GetAbilityDamageType(), 
					-- 		        damage_flags = DOTA_DAMAGE_FLAG_NONE
					-- 		   	}
					-- 		   	UnitDamageTarget(DamageTable)
					-- 		end
					-- 		return nil
					-- 	end,
					-- delayTime)

					-- count = 0

					-- time = time - tick
					-- return tick
				-- end			
			end,
		0)
	end
end

function GetHecatiaBallCount(caster)
	if caster.thtd_hecatia_ball_table == nil then return 0 end
	local count = 0
	if caster.thtd_hecatia_ball_table["earth"] ~= nil then 
		count = count + 1
	end
	if caster.thtd_hecatia_ball_table["moon"] ~= nil then 
		count = count + 1
	end
	if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then 
		count = count + 1
	end
	return count
end