thtd_eirin_01 = class({})

function thtd_eirin_01:OnProjectileHit_ExtraData( hTarget, vLocation, data )
	local caster = self:GetCaster()
	local target = hTarget
	-- local source = data.attacker -- 注意不支持 table类型数据，会返回 nil
	local source = EntIndexToHScript(data.attacker_entindex)	

	-- print("caster : ", caster:GetUnitName())
	-- print("attacker : ", source:GetUnitName())

	caster:RemoveGesture(ACT_DOTA_CAST_ABILITY_1)

	if IsValidAlive(target) then
		target:EmitSound("Sound_THTD.thtd_eirin_01.end")			
		local damage = caster:THTD_GetAbilityPowerDamage(caster:FindAbilityByName("thtd_eirin_01"))
		local DamageTable = {
				ability = self,
				victim = target, 
				attacker = caster, 
				damage = damage, 
				damage_type = self:GetAbilityDamageType(), 
				damage_flags = DOTA_DAMAGE_FLAG_NONE
		}
		UnitDamageTarget(DamageTable)
		Eirin01HitCount(caster)
	end

	return false
end

function OnEirin01TrackingProjectileToTarget(caster,target,attacker)	
	local ability = caster:FindAbilityByName("thtd_eirin_01")
	local manaCost = ability:GetSpecialValueFor("mana_cost")
	local manaBonus = ability:GetSpecialValueFor("mana_bonus")/100
	local manaChance = ability:GetSpecialValueFor("mana_chance")
	if caster:GetMana() >= manaCost then
		if RollPercentage(caster:THTD_GetStar() * manaChance) then
			caster:SetMana(math.min(caster:GetMaxMana(), caster:GetMana() - manaCost + caster:GetMaxMana() * manaBonus))
		else
			caster:SetMana(caster:GetMana() - manaCost)
		end			

		local now = GameRules:GetGameTime()
		if now - (target.thtd_eirin_01_project or 0) < 1 then 
			local delay = GetDistanceBetweenTwoVec2D(caster:GetAbsOrigin(), target:GetAbsOrigin()) / 1400			
			caster:SetContextThink(DoUniqueString("dota_timer"), 
				function() 
					if GameRules:IsGamePaused() then return 0.1 end
					if IsValidAlive(target) then
						local ability = caster:FindAbilityByName("thtd_eirin_01")
						local damage = caster:THTD_GetAbilityPowerDamage(ability)								
						local DamageTable = {
								ability = ability,
								victim = target, 
								attacker = caster, 
								damage = damage, 
								damage_type = ability:GetAbilityDamageType(), 
								damage_flags = DOTA_DAMAGE_FLAG_NONE
						}					
						UnitDamageTarget(DamageTable)
						Eirin01HitCount(caster)
					end
					return nil 
				end, 
			delay)
			return
		end
		target.thtd_eirin_01_project = now

		caster:StartGesture(ACT_DOTA_CAST_ABILITY_1)
		local info = 
		{
			Target = target,
			Source = caster,
			Ability = ability,	
			EffectName = "particles/heroes/thtd_eirin/ability_eirin_01.vpcf",
	        iMoveSpeed = 1400,
			vSourceLoc= caster:GetAbsOrigin(),                -- Optional (HOW)
			bDrawsOnMinimap = false,                          -- Optional
		    bDodgeable = true,                                -- Optional
		  	bIsAttack = false,                                -- Optional
		    bVisibleToEnemies = true,                         -- Optional
		    bReplaceExisting = false,                         -- Optional
		    flExpireTime = GameRules:GetGameTime() + 10,      -- Optional but recommended
			bProvidesVision = true,                           -- Optional
			iVisionRadius = 400,                              -- Optional
			iVisionTeamNumber = caster:GetTeamNumber(),       -- Optional
			ExtraData = { 									  -- 注意，只支持简单类型，不支持 table数据
				attacker_entindex = attacker:GetEntityIndex()	
			}
		}
		local projectile = ProjectileManager:CreateTrackingProjectile(info)
		ParticleManager:DestroyLinearProjectileSystem(projectile,false)
	end
end

function OnDestroyEirin01Count(keys)
	local caster = keys.caster	

	caster.thtd_eirin_01_count_lock = true 
	caster:SetContextThink(DoUniqueString("dota_timer"), 
		function() 
			if GameRules:IsGamePaused() then return 0.1 end
			caster.thtd_eirin_01_count_lock = nil 
			return nil
		end, 
	0.2)

	local factor = math.floor(caster.thtd_eirin_01_count/50)
	if factor > 0 then 
		local power = keys.power_bonus * factor
		local crit = keys.crit_bonus * factor
		local chance = keys.crit_chance * factor
		caster:THTD_AddBasePower(power)
		caster:THTD_AddBaseAttack(power)
		caster:THTD_AddCritChance(chance)
		caster:THTD_AddCritDamage(crit)
		local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_legion_commander/legion_commander_duel_victory.vpcf", PATTACH_CUSTOMORIGIN, caster) --PATTACH_OVERHEAD_FOLLOW
		ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin() + Vector(0, 0, 410))
		local time = 25.0
		caster:SetContextThink(DoUniqueString("dota_timer"), 
			function() 
				if GameRules:IsGamePaused() then return 0.1 end							
				if time < 0 then 
					caster:THTD_AddBasePower(-power)
					caster:THTD_AddBaseAttack(-power)
					caster:THTD_AddCritChance(-chance)
					caster:THTD_AddCritDamage(-crit)
					return nil 
				end 
				time = time - 0.2
				return 0.2
			end, 
		0)
	end
	
	
	ParticleManager:DestroyParticleSystem(caster.thtd_eirin_01_count_effect, true)
	caster.thtd_eirin_01_count_effect = nil			
	caster.thtd_eirin_01_count = 0
end

function Eirin01HitCount(caster)
	if caster.thtd_eirin_01_count_lock == true then 
		return
	end

	if not caster:HasModifier("modifier_eirin_01_count") then 
		caster:FindAbilityByName("thtd_eirin_02"):ApplyDataDrivenModifier(caster, caster, "modifier_eirin_01_count", {duration = SpawnSystem.CurTime})
		local effectName = "particles/addons_gameplay/morokai_orb_overhead_counter.vpcf"
		local effectIndex = ParticleManager:CreateParticle(effectName, PATTACH_CUSTOMORIGIN, caster) 
		ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin() + Vector(0, 0, 410))	
		ParticleManager:SetParticleControl(effectIndex, 2, Vector(1, 0, 0))
		caster.thtd_eirin_01_count_effect = effectIndex		
	end

	caster.thtd_eirin_01_count = (caster.thtd_eirin_01_count or 0) + 1
	if caster.thtd_eirin_01_count > 500 then 
		caster.thtd_eirin_01_count = 500
		return
	end

	local one = math.floor(caster.thtd_eirin_01_count/100)
	local two = math.floor((caster.thtd_eirin_01_count - one * 100)/10)
	local three = caster.thtd_eirin_01_count - one * 100 - two * 10
	if three == 0 then three = 1 end
	ParticleManager:SetParticleControl(caster.thtd_eirin_01_count_effect, 2, Vector(three, two, one))
end

function OnEirin02AttackLanded(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)	
	local range = caster:Script_GetAttackRange()

	local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),range)
	if #targets > 0 then
		local target = nil
		local index = RandomInt(1, #targets)
		for k,v in pairs(targets) do
			index = index - 1
			if THTD_IsValid(v) and index == 0 then
				target = v
				break
			end 
		end
		local ability = caster:FindAbilityByName("thtd_eirin_01")
		if target ~= nil and ability ~= nil then
			OnEirin01TrackingProjectileToTarget(caster,target,keys.attacker)
		end
	end	
end

function OnEirin03SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]
	local hero = caster:GetOwner()

	if hero.thtd_eirin_03_lock == nil then
		hero.thtd_eirin_03_lock = false
	end

	if hero.thtd_eirin_03_lock == true then
		return
	end
	hero.thtd_eirin_03_lock = true


	
	caster:EmitSound("Sound_THTD.thtd_eirin_02")

	local time = keys.duration_time
	local range = keys.range

	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_eirin/ability_eirin_03.vpcf", PATTACH_CUSTOMORIGIN, nil)
	ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
	ParticleManager:SetParticleControl(effectIndex, 1, Vector(range,0,0))
	ParticleManager:SetParticleControl(effectIndex, 2, Vector(range,0,0))
	ParticleManager:SetParticleControl(effectIndex, 4, targetPoint)
	ParticleManager:SetParticleControl(effectIndex, 15, targetPoint)

	local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_eirin/ability_eirin_03_aeons.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex2, 0, targetPoint)
	ParticleManager:SetParticleControl(effectIndex2, 1, Vector(range,range,range))


	local hitblockTag = DoUniqueString("hitblock")

	local hitblock = {
		circlePoint = targetPoint,
		radius = range,
		tag = hitblockTag,
	}
	table.insert(THTD_Custom_Hit_Block,hitblock)

	caster:SetContextThink(DoUniqueString("thtd_eirin_03_spell_think"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			if time <= 0 then 
				ParticleManager:DestroyParticleSystem(effectIndex,true)
				ParticleManager:DestroyParticleSystem(effectIndex2,true)
				for index,block in pairs(THTD_Custom_Hit_Block) do
					if block.tag == hitblockTag then
						table.remove(THTD_Custom_Hit_Block,index)
					end
				end				
				hero.thtd_eirin_03_lock = false
				return nil 
			end
			time = time - 0.1
			local targets = THTD_FindUnitsInRadius(caster,targetPoint,450)
			
			for k,v in pairs(targets) do
				if GetDistanceBetweenTwoVec2D(targetPoint, v:GetOrigin()) > range then
					local forward = (v:GetAbsOrigin() - targetPoint):Normalized()
					v:SetAbsOrigin(targetPoint+forward*range)
				end
			end
			return 0.1
		end, 
	0.1)
end

function OnEirin04SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local vecCaster = keys.target_points[1]
	local targetPoint = keys.target_points[1]
	local pointRad = 0

	if GetHitCustomBlock(vecCaster,targetPoint) ~= nil then
		return
	end

	caster:EmitSound("Sound_THTD.thtd_eirin_04")

	local maxRad = math.pi*150/180

	for i=0,36 do
		local forwardVec = Vector(math.cos(pointRad-maxRad/2+maxRad/12*i)*1500,math.sin(pointRad-maxRad/2+maxRad/12*i)*1500,0):Normalized()

		local BulletTable = {
		    Ability        	 	=   keys.ability,
			EffectName			=	"particles/heroes/thtd_eirin/ability_eirin_04.vpcf",
			vSpawnOrigin		=	vecCaster,
			vSpawnOriginNew		=	vecCaster,
			fDistance			=	5000,
			fStartRadius		=	120,
			fEndRadius			=	120,
			Source         	 	=   caster,
			bHasFrontalCone		=	false,
			bRepalceExisting 	=   false,
			iUnitTargetTeams		=	"DOTA_UNIT_TARGET_TEAM_ENEMY",
			iUnitTargetTypes		=	"DOTA_UNIT_TARGET_HERO | DOTA_UNIT_TARGET_CREEP",
			iUnitTargetFlags		=	"DOTA_UNIT_TARGET_FLAG_NONE",
			fExpireTime     =   GameRules:GetGameTime() + 10.0,
			bDeleteOnHit    =   false,
			vVelocity       =   forwardVec,
			bProvidesVision	=	true,
			iVisionRadius	=	400,
			iVisionTeamNumber = caster:GetTeamNumber(),
			iReflexCount = 0,
			bReflexByBlock = true,
		}

		if i%2 == 0 then
			BulletTable.EffectName = "particles/heroes/thtd_eirin/ability_eirin_04_red.vpcf"
		end

		CreateProjectileMoveToTargetPoint(BulletTable,caster,2000,0,0,
			function(v,vecProjectile,reflexCount)
				if v:IsNull()==false and v~=nil then
					local damage_table = {
						victim = v,
						attacker = caster,
						ability = keys.ability,
						damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + reflexCount * keys.damage_up / 100),
						damage_type = keys.ability:GetAbilityDamageType(), 
						damage_flags = keys.ability:GetAbilityTargetFlags()
					}
					UnitDamageTarget(damage_table)
				end
			end
		)
	end
end