local floor = math.floor
local ceil = math.ceil
local Enum = GetEnums()

local rune_double_apmlify_dmg = 0.15
local rune_invis_decrease_dmg = 0.05

local optim = {trick = {time=0, hand=0, apm=0, spell=0, doom=0, salo=0, snap={}}, ks = {bh = {}, kez = {}}}

local utils = {}

utils.incomingSpellDmgReduct = { --== type = nil -> static, type = 1/2 procent/special

	--Full reduced
	{
		modifierName = "modifier_winter_wyvern_winters_curse",
		type = Enum.INCOME_SPECIAL,
		is_ww = true,
	},
	{
		modifierName = "modifier_winter_wyvern_winters_curse_aura",
		type = Enum.INCOME_SPECIAL,
		is_ww = true,
	},
	{
		modifierName = "modifier_templar_assassin_refraction_absorb",
		type = Enum.INCOME_SPECIAL,
		is_refraction = true,
	},
	{
		modifierName = "modifier_abaddon_borrowed_time",
		type = Enum.INCOME_SPECIAL,
		is_refraction = true,
	},
	-- {
	-- 	modifierName = "modifier_faceless_void_backtrack_temp",
	-- 	type = Enum.INCOME_SPECIAL,
	-- 	is_refraction = true,
	-- },	
	{
		modifierName = "modifier_shadow_shaman_fowl_play_damage_reduction",
		type = Enum.INCOME_SPECIAL,
		is_refraction = true,
	},
	{
		modifierName = "modifier_legion_commander_duel",
		type = Enum.INCOME_SPECIAL,
		is_duel = true,
		var = "scepter_damage_reduction_pct",
	},
	-- {
	-- 	modifierName = "modifier_rune_invis",
	-- 	type = Enum.INCOME_SPECIAL,
	-- 	is_invis_rune= true,
	-- },

	-- Procent
	{
		modifierName = "modifier_spectre_dispersion",
		type = Enum.INCOME_PROCENT,
		var = "damage_reflection_pct",
		passive = true,
	},
	{
		modifierName = "modifier_nyx_assassin_burrow",
		type = Enum.INCOME_PROCENT,
		var = "damage_reduction",
	},	
	{
		modifierName = "modifier_underlord_portal_buff",
		type = Enum.INCOME_PROCENT,
		var = "damage_reduction",
	},	
	{
		modifierName = "modifier_bounty_hunter_wind_walk",
		type = Enum.INCOME_PROCENT,
		var = "damage_reduction_pct",
	},	
	{
		modifierName = "modifier_leshrac_pulse_nova",
		type = Enum.INCOME_PROCENT,
		var = "damage_resistance",
	},		
	{
		modifierName = "modifier_luna_moon_glaive_shield",
		type = Enum.INCOME_PROCENT,
		var = "rotating_glaives_damage_reduction",
	},		
	{
		modifierName = "modifier_ursa_enrage",
		type = Enum.INCOME_PROCENT,
		var = "damage_reduction",
	},		
	{
		modifierName = "modifier_muerta_parting_shot_physical_body_debuff",
		type = Enum.INCOME_PROCENT,
		var = "damage_reduction_percent",
	},	
	{
		modifierName = "modifier_item_prophets_pendulum",
		type = Enum.INCOME_PROCENT,
		var = "delay_pct",
	},	
	
	-- Static 
	{
		modifierName = "modifier_pudge_flesh_heap_block",
		var = "damage_block",
	},
	{
		modifierName = "modifier_item_infused_raindrop",
		var = "magic_damage_block",
		readyOnly = true,
		magicOnly = true,		
	},
	{
		modifierName = "modifier_item_dandelion_amulet",
		var = "magic_block",
		readyOnly = true,
		magicOnly = true,
	},

	--Aeon:
	{
		modifierName = "modifier_item_aeon_disk_buff",
		type = Enum.INCOME_PROCENT,
		reduce = 100,
	},

}

utils.incomingSpellDmgAmp = {

	{
		modifierName = "modifier_item_veil_of_discord_debuff",		
		var = "spell_amp",		
	},
	{
		modifierName = "modifier_item_bloodstone_aura",		
		var = "aura_spell_vulnerability",
	},	
	{
		modifierName = "modifier_hoodwink_hunters_mark",		
		var = "spell_amp",	
	},	
	{
		modifierName = "modifier_nyx_assassin_vendetta_armor_reduction",		
		var = "shard_magic_resist_reduction",		
	},
	{
		modifierName = "modifier_black_drake_magic_amplification",		
		var = "spell_amp",		
	},			
	{
		modifierName = "modifier_invoker_magic_amp_debuff",		
		var = "magic_amp",
	},			
	{
		modifierName = "modifier_grimstroke_soul_chain",		
		var = "bonus_reflected_spell_damage",
	},	
	{
		modifierName = "modifier_item_enhancement_audacious",		
		var = "incoming_damage",
	},	

	-- Increase dmg from attack
	{
		modifierName = "modifier_undying_flesh_golem_slow",		
		var = "damage_amp",	
		increase_attack = true,
	},
	{
		modifierName = "modifier_item_nemesis_curse",		
		var = "debuff_self",	
		increase_attack = true,	
	},	
	{
		modifierName = "modifier_item_nemesis_curse_debuff",		
		var = "debuff_enemy",	
		increase_attack = true,	
	},	
	{
		modifierName = "modifier_roshan_revengeroar",		
		var = "damage_pct",	
		increase_attack = true,	
	},		
	{
		modifierName = "modifier_bounty_hunter_track",		
		var = "target_damage_amp",	
		increase_attack = true,	
	},

	-- New 
	{
		modifierName = "modifier_shadow_demon_menace_crushed",		
		var = "stack",	
		increase_attack = true,	
		stack = true,
	},	
	{
		modifierName = "modifier_beastmaster_axe_stack_counter",		
		var = "damage_amp",	
		increase_attack = true,	
		only_self = true,		
		stack = true,
	},	
	{
		modifierName = "modifier_omniknight_degen_aura_effect",		
		var = "bonus_damage_per_stack",	
		increase_attack = true,	
		only_self = true,		
		stack = true,
	},	
	{
		modifierName = "modifier_vengefulspirit_retribution_tracker",		
		var = "target_damage_amp",	
		increase_attack = true,	
		only_self = true,		
		stack = true,
	},		
	{
		modifierName = "modifier_dark_willow_shadow_realm_aura_debuff",		
		var = "aura_damage_pct",	
		increase_attack = true,	
		only_self = true,		
	}

}

utils.incomingPhysDmgReduct = {		

	{
		modifierName = "modifier_mars_bulwark",	
		var = "physical_damage_reduction",	
		varExtra = "physical_damage_reduction_side",
	},
	{
		modifierName = "modifier_lich_frost_shield",
		var = "damage_reduction",		
		procent = true,
	},
	{
		modifierName = "modifier_windrunner_windrun_invis",
		var = "physical_damage_pct",
		procent = true,	
		negative = true,
		calc = true,
	},
}

utils.SelfDmgAmplify = {
    -- simple add
    modifier_item_enhancement_timeless = { var = "spell_amp", op = "add" },
    modifier_item_mysterious_hat       = { var = "spell_amp", op = "add" },
    modifier_item_meteor_hammer        = { var = "spell_amp", op = "add" },

    modifier_item_nether_shawl         = { var = "bonus_spell_amp", op = "add" },
    modifier_item_whisper_of_the_dread = { var = "bonus_spell_damage", op = "add" },

    modifier_bloodseeker_bloodrage     = { var = "spell_amp", op = "add" },
    modifier_lina_flame_cloak          = { var = "spell_amp", op = "add" },

    modifier_batrider_displacement_buff = { var = "spell_amplification", op = "add" },
    modifier_wisp_overcharge            = { var = "bonus_spell_amp", op = "add" },
    modifier_lion_to_hell_and_back_respawn_buff = { var = "spell_amp", op = "add" },

    modifier_queenofpain_masochist     = { var = "spell_amplification", op = "add" },
    modifier_largo_song_attack_burst   = { var = "spell_amp_bonus", op = "add" },

    modifier_item_partisans_brand      = { var = "bonus_damage_pct", op = "add" },
    modifier_oracle_diviners_deck_death = { var = "spell_amplification", op = "add" },

    -- subtract
    modifier_item_mage_slayer_debuff   = { var = "spell_amp_debuff", op = "sub" },
    modifier_rubick_fade_bolt_debuff   = { var = "damage_reduction", op = "sub" },

    -- stack
    modifier_muerta_supernatural = {
        var = "spell_amp_per_stack",
        op = "add",
        stack = true
    },
    modifier_pugna_oblivion_savant = {
        var = "tower_scale",
        op = "add",
        stack = true
    }
}

utils.physDmgBlock = {

	--Crimson Guard: Guard
	{
		modifierName = "modifier_item_crimson_guard_extra",
		meleeBlock = "block_damage_active",
		crimson_hp = "max_hp_pct"
	},

	--Tidehunter: Kraken Shell
	{
		modifierName = "modifier_tidehunter_kraken_shell",
		meleeBlock = "damage_reduction",
		bonus = "bonus_reduction_per_stack",
	},	
	--Tidehunter: Kraken Shell
	{
		modifierName = "modifier_tidehunter_kraken_shell_boost",
		meleeBlock = "damage_reduction",
		bonus = "bonus_reduction_per_stack",
		add = true,
	},

	--Crimson Guard: Damage Block
	{
		modifierName = "modifier_item_crimson_guard",
		meleeBlock = "block_damage_melee",
	},

	--Vanguard: Damage Block
	{
		modifierName = "modifier_item_vanguard",
		meleeBlock = "block_damage_melee",
	},
	{
		modifierName = "modifier_item_heavens_halberd",
		meleeBlock = "block_damage_melee",
	},	
	
	{
		modifierName = "modifier_item_poor_mans_shield",
		meleeBlock = "damage_block_melee",
	},

}


function DamageTaken(target,dmg,dmgType,source,throughBKB,IsAttack,custom)

	if not custom then	custom = {}	end
	
	if not custom.no_invule and IsInvul(target) then
		return 0
	end

	local tempDmg = dmg
	local ManaShield = 0 
	local amp = 0 
	local ampFromME = 0 
	local reduceProc = 0 
	local reduceProc2 = 0 
	local reduceStatic = 0 
	local reduceBlock = 0 
	local MagOnly = 0 
	local MagOnlyAfter = 0 
	local AA = 0 
	local SpellDmg = 0
	local modifiers = target:GetModifierManager()
	local count = modifiers and modifiers:GetCurrentBuffCount() or 0

	local barriers = modifiers and target:GetBarriers()

	local spell

	for i = 0, count - 1 do
		local buff = modifiers:GetBuffByIndex(i)
		local buffName = buff:GetName()

		-- Уникальные понижаторы урона
		if buffName == "modifier_bristleback_bristleback" then
			if not IsPassiveDisabled(target) then
				spell = buff:GetAbility()
				if spell then
					local burst = 0						
					local angle = FindRelativeAngle(target,source:GetAbsOrigin())
					if angle >= 110 then
						burst = spell:GetSpecialValue("back_damage_reduction")/100 --40%
					elseif angle >= 70 then
						burst = spell:GetSpecialValue("side_damage_reduction")/100 --20%
					end
					reduceProc = reduceProc + burst	
				end
			end		
		elseif buffName == "modifier_enigma_gravity_well" then
			spell = buff:GetAbility()
			if spell then
				local min_dis = spell:GetSpecialValue("min_dist")
				local reduct = spell:GetSpecialValue("damage_reduction")/100
				local distance = GetDistance2D(target,spell:GetCaster())
				if distance < min_dis then
					reduceProc = reduceProc + reduct
				else
					local max_dis = spell:GetSpecialValue("max_dist")
					reduceProc = reduceProc + (1 - (distance-min_dis)/(max_dis-min_dis))*reduct
				end
			end		
		elseif buffName == "modifier_monkey_king_transform" then	
			if buff:GetElapsedTime()<0.1 then
				reduceProc = reduceProc + 9
			end
			
		elseif buffName == "modifier_medusa_mana_shield" then
			spell = buff:GetAbility()	
			if spell and not custom.axe then				
				local burst = 0
				local per_lvl = spell:GetSpecialValue("damage_per_mana_per_level")*target:GetLevel()
				local threshold = spell:GetSpecialValue("damage_per_mana")+per_lvl
				local absorb = spell:GetSpecialValue("absorption_pct")/100
				if target:GetMana() >= tempDmg*absorb/threshold then
					burst = absorb							
				else
					burst = target:GetMana()*threshold/tempDmg
				end						
				ManaShield = burst	
			end
			custom.no_enchant = custom.axe	
		elseif buffName == "modifier_batrider_sticky_napalm" then
			local caster = buff:GetCaster()
			if caster and caster:GetIndex() == source:GetIndex() then	
				local spell = buff:GetAbility()
				if spell then
					tempDmg = tempDmg + spell:GetSpecialValue("damage")*buff:GetStackCount()
				end
			end		
		elseif buffName == "modifier_grimstroke_ink_trail" then
			if source and HaveModifier(source,"modifier_grimstroke_ink_trail_debuff") then	
				local spell = buff:GetAbility()
				if spell then
					reduceProc = reduceProc + spell:GetSpecialValue("damage_reduction")/100
				end
			end			
		
		elseif buffName == "modifier_item_martyrs_plate_effect" then
			local caster = buff:GetCaster()
			if caster and dmgType == Enum.DAMAGE_MAGC and caster:GetIndex() ~= source:GetIndex() then	
				local spell = buff:GetAbility()
				if spell then
					reduceProc = reduceProc + spell:GetSpecialValue("damage_redirection")/100
				end
			end	
		elseif buffName == "modifier_kunkka_ghost_ship_damage_absorb" then
			spell = buff:GetAbility()		
			if spell then			
				reduceProc2 = math.max(reduceProc2, spell:GetSpecialValue("ghostship_absorb")/100*2)
			end
		elseif buffName == "modifier_kunkka_ghost_ship_damage_absorb_lesser" then
			spell = buff:GetAbility()		
			if spell then			
				reduceProc2 = math.max(reduceProc2, spell:GetSpecialValue("ghostship_absorb")/100)
			end

		elseif buffName == "modifier_visage_gravekeepers_cloak" then
			if not IsPassiveDisabled(target) then
				spell = buff:GetAbility()
				if spell then
					reduceProc2 = math.max(reduceProc2, math.min(0.8,spell:GetSpecialValue("damage_reduction")/100*buff:GetStackCount()) )
				end
			end
		elseif buffName == "modifier_obsidian_destroyer_equilibrium" then
			if not IsPassiveDisabled(target) then
				spell = buff:GetAbility()
				if spell and AghanimState(spell:GetCaster()) and spell:GetCooldown() == 0 then
					reduceStatic = reduceStatic + target:GetMaxMana() * spell:GetSpecialValue("scepter_max_mana_barrier_pct")/100
				end
			end
		elseif buffName == "modifier_ice_blast" then
			spell = buff:GetAbility()					
			if spell and not custom.axe then
				AA = floor(spell:GetSpecialValue("kill_pct")/100 * target:GetMaxHealth())
			end
		elseif buffName == "silencer_oppressive_silence" then
			spell = buff:GetAbility()					
			if spell and IsSilenced(source) then
				reduceProc = reduceProc + spell:GetSpecialValue("damage_pct")/100
			end

		else
			--External Amplify	
			amp = amp + CalculateDmgAmpl(source,buff,buffName,IsAttack and dmgType == Enum.DAMAGE_PHYS)

			--External Reduction
			for i,v in ipairs(utils.incomingSpellDmgReduct) do				
				if buffName==v.modifierName then

					if v.type == Enum.INCOME_SPECIAL then
						if v.is_duel then --lc duel
							local caster = buff:GetCaster()						
							if caster and AghanimState(caster) and buff:GetAbility() then
								reduceProc = reduceProc + buff:GetAbility():GetSpecialValue(v.var)/100
							end
						elseif v.is_ww then--ww ult
							local caster = buff:GetCaster()						
							if caster then
								if caster:GetIndex() ~= source:GetIndex() then
									return 0
								else
									ampFromME = ampFromME + buff:GetAbility():GetSpecialValue("damage_amplification")/100
								end
							end				
						elseif v.is_invis_rune then
							local tim = floor((dota.GetGameTime()/60-6)/14) --6:00, 20:00, 34:00, 48:00, 62:00 rune picked after 62:00 gives 45% dmg resistance
							reduceProc = reduceProc + math.max(0.25 + tim*rune_invis_decrease_dmg, 0.25)
						elseif v.is_refraction then
							if not custom.axe then 
								return 0
							end 									
						end 
					else 
						spell = buff:GetAbility()
						if spell then
							local kef = not v.type and 1 or 100
							local burst = (v.var and math.abs(spell:GetSpecialValue(v.var) / kef)) or v.reduce or 0
							if kef == 100 then
								if v.modifierName == "modifier_underlord_portal_buff" then	burst = burst*2	end --temp fix
								if not v.passive or not IsPassiveDisabled(target) then
									reduceProc = reduceProc + burst
								end
							else 
								--Check if damage type is magical OR block accepts non-magical damage reduction									
								if not v.magicOnly or dmgType == Enum.DAMAGE_MAGC then
									if not v.magicOnly then
										reduceStatic = reduceStatic + burst
									else
										if not v.readyOnly or (spell and spell:GetCooldown() < 0.1) then 
											if not v.readyOnly then
												MagOnlyAfter = MagOnlyAfter + burst
											else 
												MagOnly = MagOnly + burst
											end
										end
									end										
								end
							end
						end
					end
					break
				end
			end
		end
	end

	reduceStatic = reduceStatic + (barriers and barriers.ALL or 0)


	--Amplification from source
	if IsHero(source) then
		if (optim.trick.time<dota.GetTick() or optim.trick.hand ~= source:GetIndex()) then
			optim.trick.time = dota.GetTick()+90
			optim.trick.hand = source:GetIndex()
			optim.trick.spell = 0
			optim.trick.apm = 0
			optim.trick.salo = 0
			optim.trick.snap = {}
			-- optim.trick.doom = 0
			local mymodifiers = source:GetModifierManager()
			local mycount = mymodifiers and mymodifiers:GetCurrentBuffCount() or 0
			if mycount > 0 then			
				for i = 0, mycount - 1 do
					local buff = mymodifiers:GetBuffByIndex(i)	
					local buffName = buff:GetName()					
					--From me apl
					if buffName == "modifier_item_aeon_disk_buff" then
						ampFromME = - 100		
						break		
					else
						local ab = buff:GetAbility()
						if ab then
							if buffName == "modifier_rattletrap_armor_power" then				
								ampFromME = ampFromME + ab:GetSpecialValue("damage_per_armor")*source:GetPhysicalArmorValue()/100					
							-- elseif buffName == "modifier_doom_bringer_lvl_pain" then
								-- optim.trick.doom = buff:GetAbility():GetSpecialValue("bonus_damage")/100					
							elseif buffName == "modifier_frogmen_riverborn_aura_bonus" then
								ampFromME = ampFromME + ab:GetSpecialValue("bonus_outgoing_damage")/100
																	
							elseif buffName == "modifier_item_divine_regalia" then
								ampFromME = ampFromME + ab:GetSpecialValue("outgoing_damage")/100
							
							elseif buffName == "silencer_oppressive_silence" then
								optim.trick.salo = ab:GetSpecialValue("damage_pct")/100
							
							elseif buffName == "modifier_snapfire_boomstick" then
								optim.trick.snap = {
									fn=function(dist, tab)
										if dist >= tab.max_dist then
											return 0
										elseif dist <= tab.min_dist then
											return tab.max_dmg
										end
										return (tab.max_dist - dist) / (tab.max_dist - tab.min_dist) * tab.max_dmg
									end,
									max_dmg=ab:GetSpecialValue("damage_amp_max")/100,
									min_dist=ab:GetSpecialValue("distance_threshold_min"),
									max_dist=ab:GetSpecialValue("distance_threshold_max"),
								}
							elseif buffName == "modifier_crystal_maiden_arcane_overflow_active" then
								if custom.is_spell then
									ampFromME = ampFromME + ab:GetSpecialValue("activation_spell_amp_pct")/100
								end
							end
						end
					end
				end
			end			
	
			SpellDmg = CalculateSpellAmpl(mymodifiers,mycount,source)
			optim.trick.spell = SpellDmg
			optim.trick.apm = ampFromME
		else
			SpellDmg = SpellDmg + optim.trick.spell
			ampFromME = ampFromME + optim.trick.apm			
		end
		if optim.trick.salo ~= 0 and IsSilenced(target) then
			ampFromME = ampFromME + optim.trick.salo	
		end		
		if optim.trick.snap.fn then
			ampFromME = ampFromME + optim.trick.snap.fn(GetDistance2D(source,target),optim.trick.snap)
		end	
		-- if optim.trick.doom ~= 0 and source:GetLevel() > math.min(29,target:GetLevel()) then
			-- ampFromME = ampFromME + optim.trick.doom	
		-- end
		if custom.no_enchant then
			SpellDmg = 0 ampFromME = 0
		end
	end 

	if dmgType == Enum.DAMAGE_PURE then
		if not throughBKB and IsMagicImmune(target) then
			tempDmg = 0
		else

			local base = tempDmg * (1-ManaShield)
			local my_increse =  (1 + ampFromME) * (1 + SpellDmg) 

			tempDmg = ( base * my_increse - reduceStatic) * (1 + amp - reduceProc) * (1 - reduceProc2) + AA
		end

	elseif dmgType == Enum.DAMAGE_MAGC then			
		if not throughBKB and IsMagicImmuneOld(target) then
			tempDmg = 0
		else
			reduceStatic = reduceStatic + (barriers and barriers.MGC or 0)

			local armore = 1 - target:GetMagicDmgResist()
			local base = tempDmg * (1-ManaShield)
			local my_increse =  (1 + ampFromME) * (1 + SpellDmg) 

			tempDmg = ( (base * my_increse - MagOnly) * armore - reduceStatic) * (1 + amp - reduceProc) * (1 - reduceProc2) - MagOnlyAfter + AA 
		end 

	elseif dmgType == Enum.DAMAGE_PHYS then
		if IsPhysDmgImmune(target) then
			tempDmg = 0
		else				
	
			if IsAttack then

				if not IsRanged(target) then 
					reduceBlock = math.max(reduceBlock,16)
				end 
				for i,v in ipairs(utils.physDmgBlock) do
					local mod = FindMod(modifiers,count,v.modifierName)
					if mod then 
						local spell = mod:GetAbility()
						if spell then
							local tempblock = spell:GetSpecialValue(v.meleeBlock)
							if v.crimson_hp and mod:GetCaster() then
								tempblock = tempblock + mod:GetCaster():GetMaxHealth()*spell:GetSpecialValue(v.crimson_hp)/100
							end
							if v.bonus then
								tempblock = tempblock + mod:GetStackCount()*spell:GetSpecialValue(v.bonus)
							end
							if v.add then
								reduceBlock = reduceBlock + tempblock
							else
								reduceBlock = math.max(reduceBlock,tempblock)
							end
						end
					end
				end
				SpellDmg = 0

			end

			reduceProc, reduceStatic = CalculatePhysReduction(target,source,modifiers,count,reduceProc,reduceStatic,IsAttack,barriers)
			
			if not throughBKB and IsMagicImmuneOld(target) then
				tempDmg = 0
			else

				reduceStatic = reduceStatic + (barriers and barriers.PHYS or 0)

				local armore = 0

				if custom.MinusArmor then
					armore = GetArmorResist(target,custom.MinusArmor)
				else
					armore = GetArmor(target)
				end

				local base = tempDmg * (1-ManaShield)
				local my_increse =  (1 + ampFromME) * (1 + SpellDmg) 

				tempDmg = ( (base * my_increse - reduceBlock) * armore - reduceStatic) * (1 + amp - reduceProc) * (1 - reduceProc2) + AA 
			end
		end
	end

	return math.max(0,tempDmg)

end

function CalculateSpellAmpl(mymodifiers,mycount, source)
	local SpellDmg = 0
	local SpellDmg_kaya = 0
	-- local SpellDmg_am = 0
	if mycount > 0 then			
		for i = 0, mycount - 1 do
			local buff = mymodifiers:GetBuffByIndex(i)
			local buffName = buff:GetName()			
			local data = utils.SelfDmgAmplify[buffName]
			local spell = buff:GetAbility()
			
			if data then
				
				if spell then
					local value = spell:GetSpecialValue(data.var) / 100
					if data.stack then
						value = value * buff:GetStackCount()
					end
					if data.op == "add" then
						SpellDmg = SpellDmg + value
					else
						SpellDmg = SpellDmg - value
					end
				end

			elseif buffName == "modifier_item_kaya_and_sange" or buffName =="modifier_item_yasha_and_kaya" or buffName == "modifier_item_kaya" then
				if spell then		
					SpellDmg_kaya = math.max(SpellDmg_kaya, spell:GetSpecialValue("spell_amp")/100)
				end

			elseif buffName == "modifier_item_divine_rapier" then
				if spell and spell:ToggleState() then		
					SpellDmg = SpellDmg + spell:GetSpecialValue("bonus_spell_amp")/100
				end

			elseif buffName == "modifier_item_vambrace"then	
				if buff:GetStackCount() == 1 then						
					if spell then 									
						SpellDmg = SpellDmg + spell:GetSpecialValue("bonus_spell_amp")/100
					end	
				end
			elseif buffName == "modifier_rubick_arcane_supremacy" then
				if not source or not IsPassiveDisabled(source) then
					if spell then
						SpellDmg = SpellDmg + spell:GetSpecialValue("spell_amp")/100
					end
				end					
			
			elseif buffName == "modifier_oracle_false_promise" then	
				if spell and AghanimState(spell:GetCaster()) then 
					SpellDmg = SpellDmg + spell:GetSpecialValue("shard_spell_amp_bonus")/100
				end

			elseif buffName == "modifier_special_bonus_spell_amplify" then 
				if spell and spell:GetLevel()~=0 then 
					SpellDmg = SpellDmg + spell:GetSpecialValue("value")/100						
				end

			elseif buffName == "modifier_pugna_life_drain_spell_amp" then	
				if buff:IsDebuff() then 
					SpellDmg = SpellDmg - buff:GetStackCount()/100
				else 
					SpellDmg = SpellDmg + buff:GetStackCount()/100
				end	

			elseif buffName == "modifier_oracle_clairvoyant_curse" then	
				if spell then 
					local owner = spell:GetCaster()
					if owner then
						SpellDmg = SpellDmg + spell:GetSpecialValue("spell_amplification")/100*owner:GetLevel()
					end
				end					
		
			elseif buffName == "modifier_razor_dynamo" then	
				if spell then 
					local owner = spell:GetCaster()
					if owner then
						SpellDmg = SpellDmg + GetTrueMinDmg(owner)/spell:GetSpecialValue("spell_amp_damage_divisor")/100
					end
				end	
			elseif buffName == "modifier_morphling_flow" then	
				if spell then 
					local owner = spell:GetCaster()
					if owner then
						SpellDmg = SpellDmg + dota.EntityToBaseNPCHero(owner):GetAgilityTotal()/spell:GetSpecialValue("agi_per_one_spell_amp")/100
					end
				end										

			elseif buffName == "modifier_item_harmonizer" then	
				if spell then 
					local amp = spell:GetSpecialValue("spell_amp")/100
					local count = 0
					local src = spell:GetCaster()
					for i = 1,6 do
						local sp = src:GetAbility(i)
						if sp and sp:GetCooldown() ~= 0 then
							count = count + 1
						end 
					end 
					SpellDmg = SpellDmg + count*amp
				end	

			-- elseif buffName ==  "modifier_alchemist_scepter_bonus_damage" then 	
			-- 	SpellDmg = SpellDmg + buff:GetStackCount()*5/100			
			elseif buffName ==  "modifier_rune_doubledamage" then 	
				SpellDmg = SpellDmg + rune_double_apmlify_dmg
			end

		end
	end	
	return SpellDmg+SpellDmg_kaya--SpellDmg_am
end

function CalculateSpellAmplW(source)
	local mymodifiers = source:GetModifierManager()
	local mycount = mymodifiers and mymodifiers:GetCurrentBuffCount() or 0
	return 1 + CalculateSpellAmpl(mymodifiers,mycount,source)
end

function CalculateDmgAmpl(from,buff,buffName,isAttack)
	for _,v in ipairs(utils.incomingSpellDmgAmp) do		
		if buffName==v.modifierName and (not isAttack or v.increase_attack) then
			if v.only_self and (not buff:GetCaster() or buff:GetCaster():GetIndex() ~= from:GetIndex()) then
				 break
			end
			local spell = buff:GetAbility()
			if spell then
				local burst = math.abs(spell:GetSpecialValue(v.var))
				if buffName == "modifier_dark_willow_shadow_realm_aura_debuff" then
					local rs_realm = spell:GetSpecialValue("max_damage_duration")
					return burst / 100 * math.min(buff:GetElapsedTime(),rs_realm)/rs_realm
				end
			
				local stack = (v.stack and buff:GetStackCount()) or 1
				return burst/100*stack
			end
			break
		end
	end
	return 0
end

function CalculateDmgAmplW(from,target)
	local modifiers = target:GetModifierManager()
	local count = modifiers and modifiers:GetCurrentBuffCount() or 0
	local amp = 0
	for i = 0, count - 1 do
		local buff = modifiers:GetBuffByIndex(i)
		local buffName = buff:GetName()
		amp = amp + CalculateDmgAmpl(from,buff,buffName)
	end 
	return 1 + amp
end

function CalculatePhysReduction(target,source,modifiers,count,reduceProc,reduceStatic,isAttack,barriers)
	for i,v in ipairs(utils.incomingPhysDmgReduct) do
		if (isAttack or not v.only_attack) then 
			local mod = FindMod(modifiers,count,v.modifierName)
			if mod then 
				local spell = mod:GetAbility()
				if spell then 
					if v.modifierName == "modifier_mars_bulwark" then	
						if not IsPassiveDisabled(target) then
							local angle = FindRelativeAngle(target,source:GetAbsOrigin())
							if angle <= 70 then
								reduceProc = reduceProc + spell:GetSpecialValue(v.var) / 100
							elseif angle <= 120 then
								reduceProc = reduceProc+ spell:GetSpecialValue(v.varExtra) / 100
							end
						end
					elseif v.procent then 
						reduceProc = reduceProc + spell:GetSpecialValue(v.var)/100 * (v.negative and -1 or 1)
					else 
						reduceStatic = reduceStatic + spell:GetSpecialValue(v.var)						
					end 
				end
			end 
		end
	end
	return reduceProc, reduceStatic
end

function killstealReload()
	optim = {trick = {time=0, hand=0, apm=0, spell=0, doom=0}, ks = {bh = {}, kez = {}}}
end

function CalculateMinusArmore(self,target)
	local minus_armor = {}
	local final = 0
	for i, v in ipairs(GetAllItems(self,true)) do
		local name = v:GetName()
		if name == "item_blight_stone" then
			minus_armor[#minus_armor+1] = {val=v:GetSpecialValue("corruption_armor"),name="modifier_blight_stone_buff"}
		elseif name == "item_desolator" then
			minus_armor[#minus_armor+1] = {val=v:GetSpecialValue("corruption_armor"),name="modifier_desolator_buff"}
		elseif name == "item_desolator_2" then
			minus_armor[#minus_armor+1] = {val=v:GetSpecialValue("corruption_armor"),name="modifier_desolator_2_buff"}
		elseif name == "item_orb_of_destruction" then
			minus_armor[#minus_armor+1] = {val=-v:GetSpecialValue("armor_reduction"),name="modifier_orb_of_destruction_debuff"}
		end
	end		
	for z,x in ipairs(minus_armor) do
		if not HaveModifier(target,x.name) then
			final = final + x.val
		end
	end
	return final
end
function DamageTakenPhys(self,target,dmg,minus)
	local dmgtype = CanAttackInGhost(self) and Enum.DAMAGE_MAGC or Enum.DAMAGE_PHYS
	local minus_value = minus and CalculateMinusArmore(self,target) or nil
	return DamageTaken(target,dmg or GetTrueMinDmg(self),dmgtype,self,true,true,{MinusArmor = minus_value})
end


local killsteal = {}

function killsteal:New(ent)
	local info = {}
	local setting = {}
	local count = 0
	local sf_coil = true
	
	for i,v in ipairs(ReadLines(dota.GetLuaPath().."scripts/config/KSManager.txt")) do
		setting[v] = true
	end

	for i = 1, Enum.SLOT_SPELL_MAX do
		local spell = ent:GetAbility(i)
		if spell then
			local name = PrettyName(spell:GetName())
			local x = not spell:IsTalant() and not spell:IsInnate() and GetFastInfo(name)
			if x and ((not x.KillSteal and setting[name]) or (x.KillSteal and not setting[name])) and not x.KillStealIgnore and (not x.SfCoil or sf_coil) then
				count = count + 1
				local tab= {}
				tab.base = x
				tab.MagicImmunityPierce = x.MagicImmunityPierce
				tab.dmgType = x.DamageType or spell:GetAbilityDamageType()
				if tab.dmgType == 0 then
					tab.dmgType = Enum.DAMAGE_MAGC
				end

				tab.GetSimpleDamage = KillStealDamage(name)
				tab.GetComplexDamage = KillStealDamage2(name)
				tab.GetDoubleDamage = KillStealDamage3(name)

				--// KS info
				tab.spell = spell
				tab.name = name
				tab.class_name = spell:GetNewClassName()

				if x.KillStealShadowPoison then
					tab.KsType = Enum.KILL_SD
				elseif IsBehaviour(spell,Enum.BEHAVIOR_UNIT_TARGET) and not x.TargetButPos or x.KsFixTarget then
					tab.KsType = Enum.KILL_TARGET
					if x.KillWithGlobal then
						tab.KsType = Enum.KILL_WITH_GLOBAL
					elseif x.AbilityName == "bounty_hunter_shuriken_toss" then
						tab.KsType = Enum.KILL_BH
					elseif x.AbilityName == "tiny_toss" then
						tab.KsType = Enum.KILL_TINY
					end
					tab.KsIsTarget = true
				elseif IsBehaviour(spell,Enum.BEHAVIOR_NO_TARGET) then
					tab.KsType = Enum.KILL_NO_TARGET
					if x.Radius and spell:GetCastRange()==0 then
						tab.KsRange = spell:GetLevelSpecialValue(x.Radius,1)
					end
				else
					tab.KsType = Enum.KILL_POS
					tab.KsIsSkillShot = x.IsSkillShot
				end

				--// Specific
				if x.SfCoil then
					tab.spell3 = FindSpellMax(ent,"nevermore_shadowraze3")
					tab.spell2 = FindSpellMax(ent,"nevermore_shadowraze2")
					tab.spell1 = FindSpellMax(ent,"nevermore_shadowraze1")
					sf_coil = false
				elseif x.TalantToData then --oracle E не учитвается
					tab.KsTalant = TalantNameToEnum(ent,x.TalantToData)
				end

				tab.Stolen = (spell:IsStolen() and IsTalant(ent, Enum.TALANT_8) and ent:GetName() == "npc_dota_hero_rubick" and 1.317 or 1)

				if x.SpellLevel then tab.qwe = FindSpellMax(ent,x.SpellLevel) or FindSpellOnMap(false,false,x.SpellLevel) end

				if x.KillStealRange then
					tab.KsRange = x.KillStealRange
				elseif x.Global or x.KillWithGlobal then
					tab.KsRange = 99999
				end

				table.insert(info,tab)

				if count==2 then
					break
				end

			end
		else
			break
		end
	end
	return info
end

--// Global Get [me,v,abilty,info]
function GetAbilityDmg(self,target,spell,x,custom)
	if not x then
		x = GetFastInfo(spell:GetName())
	end
	if not x or not x.Damage then
		return 0, 0
	end
	if not x.calculate then
		local name = x.AbilityName

		local tab={}
		tab.base = x
		tab.MagicImmunityPierce = x.MagicImmunityPierce					
		tab.dmgType = x.DamageType or spell:GetAbilityDamageType()
		if tab.dmgType == 0 then
			tab.dmgType = Enum.DAMAGE_MAGC
		end

		tab.GetSimpleDamage = KillStealDamage(name)
		tab.GetComplexDamage = KillStealDamage2(name)
		tab.GetDoubleDamage = KillStealDamage3(name)

		if x.Radius and IsBehaviour(spell,Enum.BEHAVIOR_NO_TARGET) then
			tab.KsRange = spell:GetLevelSpecialValue(x.Radius,1)
		end

		--// Specific
		if x.SfCoil then
			tab.spell3 = FindSpellMax(self,"nevermore_shadowraze3")
			tab.spell2 = FindSpellMax(self,"nevermore_shadowraze2")
			tab.spell1 = FindSpellMax(self,"nevermore_shadowraze1")
		elseif x.TalantToData then
			tab.KsTalant = TalantNameToEnum(self,x.TalantToData)
		end

		x.calculate = tab
	end

	x.calculate.spell = spell
	x.calculate.MaxDmg = x.MaxDmg

	local lvl = 0
	if x.SpellLevel then
		x.calculate.qwe = FindSpellMax(self,x.SpellLevel) or FindSpellOnMap(false,false,x.SpellLevel)
		lvl = x.calculate.qwe and x.calculate.qwe:GetLevel() or 0
	else
		lvl = spell:GetLevel()
	end

	if lvl == 0 then
		return 0, 0
	end

	local rubickPlus = (spell:IsStolen() and IsTalant(self, Enum.TALANT_8) and self:GetName() == "npc_dota_hero_rubick" and 1.317 or 1)

	local damage = x.calculate.GetSimpleDamage(self,spell,x.calculate,lvl)
	damage = x.calculate.GetComplexDamage(self,spell,target,x.calculate,damage or 0)*(rubickPlus or 1)

	local damage2 = x.calculate.GetDoubleDamage and not custom.no_double and x.calculate.GetDoubleDamage(self,spell,target, x.calculate, custom and custom.brooch, 1, damage) or 0
	if damage > 0 then
		return damage, damage2
	else
		return 0, 0
	end
end

function CalculateAbilityDmg(self,target,spell,custom)
	local info = GetFastInfo(spell:GetName())

	if not info then return 0 end
	custom = custom or {}

	if info.ProcastDmgFn and custom.procast then 
		local dmg =  info.ProcastDmgFn(self,spell)*(custom.inc_full or 1)*(spell:GetAbilityDamageType()==Enum.DAMAGE_MAGC and custom.inc_mgc or 1)
		return dmg > 0 and floor(DamageTaken(target,dmg,spell:GetAbilityDamageType(),self,info.MagicImmunityPierce,info.HitDamage,custom)) or 0
	end

	if not info.Damage then return 0 end

	local brooch_type = (info.ExtraPhysDmg or info.HitDamage) and CanAttackInGhost(self) and Enum.DAMAGE_MAGC

	if custom.max_dmg then info.MaxDmg = custom.max_dmg	end
	local dmg, dmg2 = GetAbilityDmg(self,target,spell,info,{brooch=brooch_type,no_double=custom.no_double})
	if custom.max_dmg then info.MaxDmg = nil end

	local dmg_type = (info.HitDamage and brooch_type) or info.calculate.dmgType

	if custom.inc_full then
		dmg = dmg*custom.inc_full
		dmg2 = dmg2*custom.inc_full
	end
	if custom.inc_mgc and not info.IncreaseMagicDmg and (dmg_type==Enum.DAMAGE_MAGC or dmg_type==Enum.DAMAGE_ZERO) then
		dmg = dmg*custom.inc_mgc
	end

	if custom.calc_armore and info.HitDamage and dmg_type == Enum.DAMAGE_PHYS then		
		custom.MinusArmor = CalculateMinusArmore(self,target)
	end 

	return dmg > 0 and floor(DamageTaken(target,dmg,dmg_type,self,info.MagicImmunityPierce,info.HitDamage,custom) + dmg2) or 0
end

function CalculateAllDmg(self,v,offspell,check_range)
	local inc_mgc = 1
	local inc_full = 1

	local specific = {}

	local data = table.filter(GetAllItems(self,true),function(x) return CanBeCasted(x) and (not check_range or GetDistance2D(self,v)<GetRealCastRange(x)) end)
	for i = 1, Enum.SLOT_SPELL_VISIBLE do
		local sp = self:GetAbility(i)
		if sp and (i ~= 5 or not sp:IsHidden()) and (not offspell or sp:GetName()~=offspell)  then
			if sp:GetName() == "nyx_assassin_vendetta" then
				specific.nyx_ult = sp					
			else 
				if CanBeCasted(sp) and not sp:InAbilityPhase() and (not check_range or GetDistance2D(self,v)<GetRealCastRange(sp)) then
					if sp:GetName() == "necrolyte_reapers_scythe" then
						specific.necr_ult = sp
					else
						data[#data+1] = sp
						if sp:GetName() == "nyx_assassin_jolt" then
							specific.nyx_w = sp
						end
					end
				end
			end
		end
	end

	for i, spell in ipairs(data) do
		local info = GetFastInfo(spell:GetName())
		if info then
			if info.IncreaseMagicDmg then
				if not info.IncreaseMagicDmgModifier or not HaveModifier(v, info.IncreaseMagicDmgModifier) then
					inc_mgc = inc_mgc + math.abs(spell:GetSpecialValue(info.IncreaseMagicDmg)) / 100
				end
			elseif info.IncreaseFullDmg and (not info.IncreaseFullDmgModifier or not HaveModifier(v,info.IncreaseFullDmgModifier)) then
				inc_full = inc_full + math.abs(spell:GetSpecialValue(info.IncreaseFullDmg)) / 100
			end
		end
	end

	local hpRegen = v:GetHealthRegen()
	local maxp = v:GetMaxHealth()
	local hp = (v:IsAlive() and v:IsVisible() and v:GetHealth()) or maxp
	local hp_init = hp

	for i, spell in ipairs(data) do
		local charges = math.max(spell:GetCharges(),1)
		local hp_regen = (maxp == hp and 0 or hpRegen * (RealCastPoint(spell) + 0.1))
		hp = hp - CalculateAbilityDmg(self, v, spell, {inc_mgc=inc_mgc, inc_full=inc_full, procast=true})*charges + hp_regen
	end

	if specific.necr_ult and hp > 0 then 
		local info = GetFastInfo(specific.necr_ult:GetName())
		local done = v:GetHealth()-hp
		local necro_dmg = floor((v:GetMaxHealth() - v:GetHealth() + done) * specific.necr_ult:GetSpecialValue(info.Damage))
		return hp - floor(DamageTaken(v,necro_dmg,specific.necr_ult:GetAbilityDamageType(),self,info.MagicImmunityPierce,info.HitDamage)) + hpRegen*2
	elseif specific.nyx_ult and (CanBeCasted(specific.nyx_ult) or HaveModifier(self,"modifier_nyx_assassin_vendetta")) then
		local info = GetFastInfo(specific.nyx_ult:GetName())
		local ult_dmg = specific.nyx_ult:GetSpecialValue(info.BonusDamage)
		hp = hp - floor(DamageTaken(v,GetTrueMinDmg(self),Enum.DAMAGE_PHYS,self,true))*inc_full
		hp = hp - floor(DamageTaken(v,ult_dmg,specific.nyx_ult:GetAbilityDamageType(),self,info.MagicImmunityPierce))
	end

	if specific.nyx_w then
		local info = GetFastInfo(specific.nyx_w:GetName())
		hp = hp - floor(DamageTaken(v,(hp_init-hp)*specific.nyx_w:GetSpecialValue(info.IncreaseEndDmg)/120,specific.nyx_w:GetAbilityDamageType(),self,false))
	end

	
	return hp
end

function GetFromModifierSpecialValue(ent,spell_name,special_name,if_zero)
	local sp = FindSpell(ent,spell_name)
	if sp then
		local value = sp:GetSpecialValue(special_name)
		if value == 0 and if_zero then return if_zero end
		return value
	end 
	return 0
end


--// Damage Calculate Table
local simple = {

	lina_dragon_slave = -- w,r спеллы на этой функции висят
    function(self,spell,tab,lvl)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
		if IsHero(self) and self:GetFacetID() == 2 then
			dmg = dmg*0.6
		end
        if AghanimStateLow(self) then
			local mod = FindModifier(self,"modifier_lina_fiery_soul")
			if mod then
				dmg = dmg + mod:GetStackCount() * mod:GetAbility():GetSpecialValue("bonus_spell_damage")
			end 
        end
        return dmg
    end,  

	techies_suicide =
    function(self,spell,tab,lvl)
        return spell:GetSpecialValue(tab.base.Damage) + spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl)*self:GetMaxHealth()/100
    end,    	
	
	dazzle_shadow_wave =
    function(self,spell,tab,lvl)
		local increase = FindSpell(self,"dazzle_innate_weave")
		tab.base.ArmoreValue = nil
		if increase then
			increase = increase:GetSpecialValue("armor_change") * increase:GetSpecialValue("enemy_multiplier")
			if increase ~= 0 then
				tab.base.ArmoreValue = -increase
			end 
		end 
        return spell:GetSpecialValue(tab.base.Damage)
    end,   

	earthshaker_enchant_totem =
    function(self,spell,tab,lvl)
		local e = FindSpell(self,"earthshaker_aftershock")
		if e then
			return e:GetSpecialValue("aftershock_damage")
		end
		return 1 -- чтобы считался урон у автоуворота
    end,    	
	
	pangolier_shield_crash =
    function(self,spell,tab,lvl)
        return spell:GetSpecialValue(tab.base.Damage) * (100+spell:GetSpecialValue(tab.base.DamageExtra))/100
    end,    

    morphling_adaptive_strike_agi =
    function(self,spell,tab,lvl)
        local ks_dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        local agi = floor(self:GetAgilityTotal())
        local dmg = agi/floor(self:GetStrengthTotal())
        if dmg > 1.5 then
            return floor(0.5*(lvl+1)*agi + ks_dmg)
        elseif dmg < 0.5 then
            return floor(0.5*agi + ks_dmg)
        elseif (dmg >= 0.5 and dmg <= 1.5) then
            return floor(0.25+((dmg-0.5)*(0.5*(lvl+1)))*agi+ks_dmg)
        end
    end,
    
    visage_soul_assumption =
    function(self,spell,tab,lvl)
        local soul = FindModifier(self,"modifier_visage_soul_assumption")
        if soul then
			local dmg = spell:GetSpecialValue(tab.base.DamageExtra)
			local stacks = tab.MaxDmg or soul:GetStackCount()
            return spell:GetLevelSpecialValue(tab.base.Damage,lvl)+(dmg*stacks)
        end
        return spell:GetLevelSpecialValue(tab.base.Damage,lvl)
    end,    
    
    centaur_double_edge =
    function(self,spell,tab,lvl)
        local scale = spell:GetSpecialValue(tab.base.DamageExtra)/100
        return spell:GetLevelSpecialValue(tab.base.Damage,lvl) + self:GetStrengthTotal()*scale
    end,
    
    lion_finger_of_death =
    function(self,spell,tab,lvl)
        local dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        local perStack = spell:GetSpecialValue(tab.base.DamageExtra)
        local mod = FindModifier(self,"modifier_lion_finger_of_death_kill_counter")
        if mod then
            dmg = dmg +perStack*mod:GetStackCount()
        end
        return dmg
    end,
    
    monkey_king_boundless_strike =
    function(self,spell,tab,lvl,no_crit)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
        local bonus = 0
        local master = FindModifier(self,"modifier_monkey_king_quadruple_tap_bonuses")
        if master then
            local ability = master:GetAbility()
            if ability then
                bonus = ability:GetSpecialValue("bonus_damage")
            end
        end
		if no_crit then dmg = 100 end
		local flat = spell:GetSpecialValue(tab.base.DamageExtra)
        return (GetTrueMinDmg(self) + bonus)*dmg/100 + flat
    end,
    
    lich_frost_nova =
    function(self,spell,tab,lvl)
		local ks_dmg = tab.base.Damage=="AbilityDamage" and spell:GetAbilityDamage() or spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return ks_dmg + spell:GetSpecialValue(tab.base.DamageExtra)
    end,
    
    undying_soul_rip =
    function(self,spell,tab,lvl)
        local count = -1
        local pos = self:GetAbsOrigin()
    
        local lane_creeps = dota.FindEntities(dota.kDotaBaseNPCHero)
        for i,v in ipairs(lane_creeps) do
            if v:IsVisible() and v:IsAlive()  and GetDistance2D(v,pos) < 1300 then
                count = count + 1
            end
        end
        lane_creeps = dota.FindEntitiesWithName("C_DOTA_BaseNPC_Creep")
        for i,v in ipairs(lane_creeps) do
            if v:IsVisible() and v:IsAlive() and not v:IsWaitingToSpawn() and GetDistance2D(v,pos) < 1300 then
                count = count + 1
            end
        end
        lane_creeps = dota.FindEntitiesWithName("C_DOTA_Unit_Undying_Zombie")
        for i,v in ipairs(lane_creeps) do
            if v:IsVisible() and v:IsAlive() and GetDistance2D(v,pos) < 1300 then
                count = count + 1
            end
        end
        local bonus = spell:GetLevelSpecialValue(tab.base.MaxUnit,lvl)
        return math.min(count,bonus) * spell:GetSpecialValue(tab.base.Damage)
    end,  

	legion_commander_overwhelming_odds =
    function(self,spell,tab,lvl)
        local ks_dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        local ks_dmg2 = spell:GetSpecialValue(tab.base.DamageExtra)
        local pos = self:GetAbsOrigin()
		local team =  self:GetTeamIndex()
		local dmg_creeps = spell:GetLevelSpecialValue("damage_per_unit",lvl)
		local range = spell:GetAOERadius()
        for i,v in ipairs(dota.FindEntities(dota.kDotaBaseNPCHero)) do
            if v:IsVisible() and v:IsAlive() and not v:IsTeam(team)and GetDistance2D(v,pos) < range then
                ks_dmg = ks_dmg + ks_dmg2
            end
        end
        for i,v in ipairs(dota.FindEntitiesWithName("C_DOTA_BaseNPC_Creep")) do
            if v:IsVisible() and v:IsAlive() and not v:IsTeam(team) and not v:IsWaitingToSpawn() and GetDistance2D(v,pos) < range then
				ks_dmg = ks_dmg + dmg_creeps
            end
        end
        return ks_dmg
    end,
    
    tusk_walrus_punch =
    function(self,spell,tab,lvl,no_crit)
		tab.dmgType = Enum.DAMAGE_PHYS
        local dmg = spell:GetSpecialValue(tab.base.Damage)
		if no_crit then	dmg = 100 end
        return (GetTrueMinDmg(self) + spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl))*dmg/100
    end,
    
    phantom_assassin_stifling_dagger =
    function(self,spell,tab,lvl,no_crit)
		local dmg = spell:GetSpecialValue(tab.base.Damage)
		local ex_dmg = spell:GetSpecialValue(tab.base.DamageExtra)/100
		local mod = FindModifier(self,"modifier_phantom_assassin_mark_of_death") 
		local mult = mod and mod:GetAbility() and mod:GetAbility():GetSpecialValue("crit_bonus") / 100 or 1
		if no_crit then	mult = 1 end
		return (dmg + (GetTrueMinDmg(self) * ex_dmg)) * math.max(mult,1)
    end,
    
    tiny_toss =
    function(self,spell,tab,lvl)
		local bonus = GetFromModifierSpecialValue(self,"tiny_grow","toss_bonus_damage")
        return (spell:GetLevelSpecialValue(tab.base.Damage,lvl) + bonus)*(100+spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl))/100
    end,

	tiny_toss_tree123 =
    function(self,spell,tab,lvl)
        return spell:IsHidden() and 0 or (GetTrueMinDmg(self))
    end,
    
    tiny_toss_tree =
    function(self,spell,tab,lvl)
		local main_spell = FindSpell(self,"tiny_tree_grab")
		local remove_dmg = main_spell and main_spell:GetSpecialValue(tab.base.Damage) or 0
        return GetTrueMinDmg(self) - remove_dmg + spell:GetSpecialValue(tab.base.Damage)
    end,
    
    tiny_tree_channel =
    function(self,spell,tab,lvl)
        return GetTrueMinDmg(self)
    end,
    
    winter_wyvern_winters_curse =
    function(self,spell,tab,lvl)
        return spell:GetSpecialValue(tab.base.KSDuration) - 0.3
    end,
    
    legion_commander_duel =
    function(self,spell,tab,lvl)
        return spell:GetLevelSpecialValue(tab.base.KSDuration,lvl)
    end,   
	
	doom_bringer_doom =
    function(self,spell,tab,lvl)
        return (spell:GetLevelSpecialValue(tab.base.KSDuration,lvl)+1)*spell:GetLevelSpecialValue(tab.base.Damage,lvl)
    end,
    
    dark_willow_shadow_realm =
    function(self,spell,tab,lvl)
        local ks_dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        if tab.MaxDmg then
			local rs_realm = spell:GetLevelSpecialValue(tab.base.MaxDmgDuration,lvl)
            return math.min(ks_dmg*(rs_realm or 3),ks_dmg)
        end
        local mod = FindModifier(self,"modifier_dark_willow_shadow_realm_buff")
        if mod then
			local rs_realm = spell:GetLevelSpecialValue(tab.base.MaxDmgDuration,lvl)
            return math.min(ks_dmg*(mod:GetElapsedTime()/(rs_realm or 3)),ks_dmg)
        end
        return 0
    end,
    
    skeleton_king_hellfire_blast =
    function(self,spell,tab,lvl)
        local dmg = tab.base.Damage=="AbilityDamage" and spell:GetAbilityDamage() or spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return dmg+spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl)*2
    end,
    
    invoker_sun_strike =
    function(self,spell,tab,lvl)
		local level = IsExistSpell(tab.qwe) and tab.qwe:GetLevel() or Enum.INVOKER_MAX_LVL
		if level == 0 then return 0 end
        return spell:GetLevelSpecialValue(tab.base.Damage,level)
    end,
    
    invoker_deafening_blast =
    function(self,spell,tab,lvl)
		local level = IsExistSpell(tab.qwe) and tab.qwe:GetLevel() or Enum.INVOKER_MAX_LVL
		if level == 0 then return 0 end
        return spell:GetLevelSpecialValue(tab.base.Damage,level)
    end,
    
    invoker_tornado =
    function(self,spell,tab,lvl)
		local level = IsExistSpell(tab.qwe) and tab.qwe:GetLevel() or Enum.INVOKER_MAX_LVL
		if level == 0 then return 0 end
         return spell:GetLevelSpecialValue(tab.base.Damage,level) + spell:GetLevelSpecialValue(tab.base.DamageExtra,level)
    end,

    invoker_chaos_meteor =
    function(self,spell,tab,lvl)
        local level = IsExistSpell(tab.qwe) and tab.qwe:GetLevel() or Enum.INVOKER_MAX_LVL
		if level == 0 then return 0 end
		return (spell:GetLevelSpecialValue(tab.base.Damage,level) + spell:GetLevelSpecialValue(tab.base.DamageExtra,level)) * 3
    end,
    
    invoker_emp =
    function(self,spell,tab,lvl)
        local level = IsExistSpell(tab.qwe) and tab.qwe:GetLevel() or Enum.INVOKER_MAX_LVL
		if level == 0 then return 0 end
        return spell:GetLevelSpecialValue(tab.base.Damage,level)
    end,
    
    skywrath_mage_arcane_bolt =
    function(self,spell,tab,lvl)
        tab.MagicImmunityPierce = IsTalant(self,Enum.TALANT_7) and not IsStolen(spell)
		local dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return dmg + (spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl) or 1)*self:GetIntellectTotal()
    end,
    
    mars_gods_rebuke =
    function(self,spell,tab,lvl,no_crit)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
		if no_crit then	dmg = 100 end
        return GetTrueMinDmg(self)*dmg/100 + spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl)
    end,
    
    ember_spirit_sleight_of_fist =
    function(self,spell,tab,lvl)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
        return dmg + GetTrueMinDmg(self)
    end,
    
    tidehunter_anchor_smash =
    function(self,spell,tab,lvl)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
        return dmg + GetTrueMinDmg(self)
    end,
    
    mirana_arrow =
    function(self,spell,tab,lvl)
		local dmg = tab.base.Damage=="AbilityDamage" and spell:GetAbilityDamage() or spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return dmg + spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl)
    end,
    
    pangolier_swashbuckle =
    function(self,spell,tab,lvl)
        return spell:GetSpecialValue(tab.base.Damage)*spell:GetLevelSpecialValue(tab.base.Hits,lvl)
    end,
    
    alchemist_unstable_concoction_throw =
    function(self,spell,tab,lvl)
        local soul = FindModifier(self,"modifier_alchemist_unstable_concoction")
        if soul then
            local dmg = spell:GetSpecialValue(tab.base.Damage)
            return dmg * math.min(1,(soul:GetElapsedTime())/5)
        elseif tab.MaxDmg then
			return tab.MaxDmg * spell:GetSpecialValue(tab.base.Damage)
		end 
        return 0
    end,
    
    juggernaut_omni_slash =
    function(self,spell,tab,lvl)
        local duration = spell:GetLevelSpecialValue("duration",lvl)
        local attacks = GetAttackTime(self)/1.8
        local damage = GetTrueMinDmg(self)+spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        local durAttack = ceil(duration/attacks)
		local bonus = 1
		-- local mod = FindModifier(self,"modifier_juggernaut_duelist")
		-- if mod then
		-- 	bonus = bonus + mod:GetAbility():GetSpecialValue("front_damage_increase")/200
		-- end
        return (durAttack+(floor(durAttack/5)))*damage*bonus
    end,
    
    juggernaut_swift_slash =
    function(self,spell,tab,lvl)
        local duration = spell:GetLevelSpecialValue("duration",lvl)
        local attacks = GetAttackTime(self) /1.8
        local damage = GetTrueMinDmg(self)+spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        local durAttack = ceil(duration/attacks)
		local bonus = 1
		-- local mod = FindModifier(self,"modifier_juggernaut_duelist")
		-- if mod then
		-- 	bonus = bonus + mod:GetAbility():GetSpecialValue("front_damage_increase")/200
		-- end
        return (durAttack+(floor(durAttack/5)))*damage*bonus
    end,
    
    oracle_purifying_flames =
    function(self,spell,tab,lvl)
		local tal_value = (tab.KsTalant and IsTalant(self,tab.KsTalant.enum) and tonumber(tab.KsTalant.value) or 0)
        return spell:GetLevelSpecialValue(tab.base.Damage,lvl)*(1+tal_value/100)
    end,
    
    ember_spirit_fire_remnant =
    function(self,spell,tab,lvl)
        local dmg = spell:GetSpecialValue(tab.base.Damage)
        return dmg*spell:GetCharges()
    end,
    
    omniknight_hammer_of_purity =
    function(self,spell,tab,lvl)
        local dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return dmg + spell:GetSpecialValue(tab.base.DamageExtra)/100*self:GetDamageMin()
    end,

	ogre_magi_unrefined_fireblast =
    function(self,spell,tab,lvl)
        local dmg = spell:GetLevelSpecialValue(tab.base.Damage,lvl)
        return dmg + (spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl) * self:GetStrengthTotal())
    end,    

	sven_storm_bolt =
    function(self,spell,tab,lvl)
		local dmg = tab.base.Damage=="AbilityDamage" and spell:GetAbilityDamage() or spell:GetLevelSpecialValue(tab.base.Damage,lvl)
		if spell:GetAltCastState() then
			dmg = dmg + spell:GetLevelSpecialValue(tab.base.DamageExtra,lvl)
		end
		return dmg
	end,		
	
	spirit_breaker_charge_of_darkness =
    function(self,spell,tab,lvl)
		return 0
	end,		
	
	hoodwink_acorn_shot =
    function(self,spell,tab,lvl)
		return spell:GetSpecialValue(tab.base.DamageExtra)*GetTrueMinDmg(self)/100+spell:GetSpecialValue(tab.base.Damage)-1
	end,		
	
	clinkz_burning_barrage =
    function(self,spell,tab,lvl)
		return spell:GetSpecialValue(tab.base.Damage)*GetTrueMinDmg(self)/100
	end,	

	kez_echo_slash = 
	function(self,spell,tab,lvl)
		local hits = tab.MaxDmg or 1
		return (spell:GetSpecialValue(tab.base.Damage)*GetTrueMinDmg(self)/100 + spell:GetSpecialValue(tab.base.DamageExtra)) * hits
	end,	
	
	kez_raptor_dance = 
	function(self,spell,tab,lvl)
		return spell:GetSpecialValue(tab.base.Damage)
	end,	
	
	kez_kazurai_katana = 
	function(self,spell,tab,lvl)
		return GetTrueMaxDmg(self)
	end,	
	
	sandking_scorpion_strike = 
	function(self,spell,tab,lvl)
		local mult = (tab.base.GrabDataFromVPK and tab.base.GrabDataFromVPK[2]) or 0
		mult = (100+mult)/100
		return GetTrueMinDmg(self) * mult + spell:GetSpecialValue(tab.base.Damage)
	end,

	item_ethereal_blade =
    function(self,spell,tab,lvl)
        local dmg = spell:GetSpecialValue(tab.base.Damage) + (self:GetStrengthTotal() + self:GetAgilityTotal() + self:GetIntellectTotal()) * spell:GetSpecialValue(tab.base.DamageExtra)
		tab.blade_scepter = spell:GetSpecialValue(tab.base.DamageScepter)
        return dmg
    end,

	techies_mutually_assured_destruction =
    function(self,spell,tab,lvl)
        return spell:GetSpecialValue(tab.base.Damage) + spell:GetSpecialValue(tab.base.DamageExtra)*self:GetMaxMana()/100
    end,

    base =
    function(self,spell,tab,lvl)
		if tab.base.Damage == "AbilityDamage" then
			return spell:GetAbilityDamage()
        elseif tab.base.KsMultyTalant then
			return spell:GetLevelSpecialValue(tab.base.Damage,lvl)
		else
			return spell:GetSpecialValue(tab.base.Damage)
		end
    end,
    
}

local comp = {

    item_ethereal_blade =
        function(self,spell,v,tab,damage)
			local bonus = ((IsGhosted(v) or IsMagicImmuneNew(v)) and 1) or (1-tab.blade_scepter/100)
			return (damage)*bonus
        end,

	windrunner_powershot = 
		function(self,spell,v,tab,damage)
			return damage
		end,

	pudge_meat_hook =
        function(self,spell,v,tab,damage)
            return damage + GetDistance2D(self,v)*spell:GetSpecialValue(tab.base.DamageExtra)/100
        end,

	snapfire_scatterblast =
			function(self,spell,v,tab,damage)
				local dmg = damage
				local aspect = spell:GetSpecialValue("bonus_applies_at_long_range") == 0
				local range = GetDistance2D(self,GetSimpleFastPrediction(v,spell:GetCastPoint()+0.1)) - spell:GetSpecialValue("point_blank_range")
				if (aspect and range < 0) or (not aspect and range > 0) then
					dmg = dmg * (1+spell:GetSpecialValue(tab.base.NormalDmgIncrease)/100)
				end
				return dmg
			end,

    antimage_mana_void =
        function(self,spell,v,tab,damage)
            return  floor((v:GetMaxMana() - v:GetMana()) * damage)
        end,

    bounty_hunter_shuriken_toss =
        function(self,spell,v,tab,damage)
            -- local mod = FindModifier(v,"modifier_bounty_hunter_track")
            -- if mod and mod:GetAbility() then
            --     return damage*mod:GetAbility():GetSpecialValue("toss_crit_multiplier")/100
            -- end
            return damage
        end,

    phantom_assassin_fan_of_knives =
        function(self,spell,v,tab,damage)
            return  floor(v:GetMaxHealth() * damage/100)
        end,

    mirana_starfall =
        function(self,spell,v,tab,damage)
            if GetDistance2D(self,v) < tab.KsRange-25 then
                return damage*(1+spell:GetSpecialValue(tab.base.DamagePercent)/100)-3
            end
            return damage
        end,

	phantom_assassin_stifling_dagger =
        function(self,spell,v,tab,damage,data)
            local dmg = damage
            local mult = 1
			if not (data and data.no_crit) and self:GetFacetID() == 2 then
				local mod = FindModifier(v,"modifier_phantom_assassin_mark_of_death") 
				mult = mod and mod:GetAbility() and mod:GetAbility():GetSpecialValue("crit_bonus") / 100 or 1
			end
            return dmg*mult
        end,

    necrolyte_reapers_scythe =
        function(self,spell,v,tab,damage,data)
			local dagon = data and data.dagon or 0
            return  floor((v:GetMaxHealth() - v:GetHealth() + dagon) * damage)
        end,

	nyx_assassin_jolt =
        function(self,spell,v,tab,damage,data)
			local max_mana = v:GetMaxMana()
			if max_mana == 0 then
				return 0
			end
            local tempBurn =  damage * floor(max_mana)/100
			local sum = data and data.dagon or 0
            local proc = spell:GetSpecialValue(tab.base.IncreaseEndDmg)
			local extra = data and data.nyx

            if extra then
                local time = dota.GetMapTime()
                local duration = spell:GetSpecialValue("damage_echo_duration")
                for a,s in ipairs(table.filter(extra, function(x) return x.time + duration > time end)) do
					sum = sum + s.dmg
				end
			end

            tempBurn = tempBurn + sum * proc / 100

            return tempBurn
        end,

    invoker_emp =
        function(self,spell,v,tab,damage)
            local tempBurn =  math.min(damage,v:GetMana())
            return tempBurn*spell:GetSpecialValue(tab.base.DamageExtra)/100
        end,

    obsidian_destroyer_sanity_eclipse =
        function(self,spell,v,tab,damage)
            local mult = spell:GetSpecialValue(tab.base.DamageExtra)
            return math.max(0,self:GetMaxMana() - v:GetMaxMana()) * mult + damage
        end,

    shadow_demon_shadow_poison =
        function(self,spell,v,tab,damage)
            local actDmg = {1, 2, 4, 8, 16}
            local poison = FindModifier(v,"modifier_shadow_demon_shadow_poison")
            if poison then
                local Mod = poison:GetStackCount()
                if Mod > 5 then
                    return ((damage*16) + ((Mod-5)*50))
                elseif Mod ~= 0 then
                    return ((actDmg[Mod]) * damage)
                end
            end
            return 0
        end,

    shadow_demon_shadow_poison_release =
        function(self,spell,v,tab,damage)
            local actDmg = {1, 2, 4, 8, 16}
            local poison = FindModifier(v,"modifier_shadow_demon_shadow_poison")
            if poison then
                local w = poison:GetAbility()
                if w then
                    local damage = w:GetSpecialValue(tab.base.Damage)
                    local Mod = poison:GetStackCount()
                    if Mod > 5 then
                        return ((damage*16) + ((Mod-5)*50))
                    elseif Mod ~= 0 then
                        return ((actDmg[Mod]) * damage)
                    end
                end
            end
            return 0
        end,

	zuus_arc_lightning =
	    function(self,spell,v,tab,damage)
			local extra = GetFromModifierSpecialValue(self,"zuus_static_field","damage_health_pct",2)/100
			return damage + extra*v:GetHealth()
		end,

	zuus_lightning_bolt =
	    function(self,spell,v,tab,damage)
			local extra = GetFromModifierSpecialValue(self,"zuus_static_field","damage_health_pct",2)/100
			return damage + extra*v:GetHealth()
		end,

	zuus_thundergods_wrath =
	    function(self,spell,v,tab,damage)
			local extra = GetFromModifierSpecialValue(self,"zuus_static_field","damage_health_pct",2)/100
			return damage + extra*v:GetHealth()
		end,

    shredder_whirling_death =
        function(self,spell,v,tab,damage)
            if v:GetPrimaryAttribute() ~= 0 then
                return damage
            else
                local bonus = spell:GetSpecialValue(tab.base.DamageExtra)
                return damage + floor(v:GetStrengthTotal()*bonus*21/100)*0.95
            end
        end,

    nevermore_shadowraze3 =
        function(self,spell,v,tab,damage)
            local debuff = FindModifier(v,"modifier_nevermore_shadowraze_debuff")
            if debuff then
                local ex_dmg = spell:GetSpecialValue(tab.base.DamageExtra)
                return damage + debuff:GetStackCount()*ex_dmg
            end
            return damage
        end,
	kez_raptor_dance = 
		function(self,spell,v,tab,damage)
			local hits = spell:GetSpecialValue(tab.base.Hits)
			return (damage + (spell:GetSpecialValue(tab.base.DamageExtra) * v:GetMaxHealth() / 100) ) *hits
		end,	
		
	kez_kazurai_katana = 
		function(self,spell,v,tab,damage)
			local accumulated = FindModifier(v,"modifier_kez_katana_bleed")
			local bonus = 0
			if accumulated and AghanimStateLow(self) then
				if FindRelativeAngle(v,self:GetAbsOrigin()) >= 120 then
					bonus = accumulated:GetStackCount()
				end
			end
			return (damage + bonus)
		end,
	--broken
    huskar_life_break =
        function(self,spell,v,tab,damage)
            return floor(v:GetHealth() * damage)
        end,	
	--broken
    razor_plasma_field =
        function(self,spell,v,tab,damage)
			local radius_dmg = (GetDistance2D(self,v)-24)/(tab.KsRange or 800)
            return math.min(radius_dmg,1)*damage*2
        end,
    --broken
    elder_titan_earth_splitter =
        function(self,spell,v,tab,damage)
            return  floor(v:GetMaxHealth()*damage/100)
        end,
    --broken
    bristleback_quill_spray =
        function(self,spell,v,tab,damage)
            local poison = FindModifier(v,"modifier_bristleback_quill_spray")
            if poison then
                damage = damage + spell:GetSpecialValue(tab.base.DamageExtra) * poison:GetStackCount()
            end
            return damage
        end,

	skywrath_mage_arcane_bolt = 
		function(self,spell,v,tab,damage)
			if tab.MagicImmunityPierce and IsMagicImmuneNew(v) then
				return damage*2
			end 
			return damage
		end,

    base =
        function(self,spell,v,tab,damage)
            return damage
        end,

}

local double = {
	riki_blink_strike = 
		function(self,spell,v,tab,attack_mgc,increase)
			if CanAttack(self) and IsNewAttackReady(self) then 
				local dmg = GetTrueMinDmg(self)
				local bonus = 0
				local backstab = FindSpellMax(self,"riki_innate_backstab")
				if backstab then 
					bonus = self:GetAgilityTotal()*backstab:GetSpecialValue("damage_multiplier")
				end
				return DamageTaken(v,(dmg+bonus)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true)
			end
			return 0
		end,
	sniper_assassinate = 
		function(self,spell,v,tab,attack_mgc,increase)
			return DamageTaken(v,GetTrueMinDmg(self)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true)
		end,	
		
	omniknight_hammer_of_purity = 
		function(self,spell,v,tab,attack_mgc,increase)
			return DamageTaken(v,GetTrueMinDmg(self)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true)
		end,

	abaddon_death_coil =
    	function(self,spell,v,tab,attack_mgc,increase)
			if spell:GetSpecialValue("perform_attack") ~= 0 then
       			return DamageTaken(v,GetTrueMinDmg(self)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true) * spell:GetSpecialValue("damage_percentage_on_perform_attack") / 100
			else
				return 0
			end
    	end,

	nevermore_shadowraze3 =
    	function(self,spell,v,tab,attack_mgc,increase)
       		return IsTalant(self,Enum.TALANT_8) and not IsStolen(spell) and DamageTaken(v,GetTrueMinDmg(self)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true) or 0
    	end,

	bounty_hunter_shuriken_toss =
    	function(self,spell,v,tab,attack_mgc,increase)
			local idx = self:GetIndex()
			if not optim.ks.bh[idx] then optim.ks.bh[idx] = {} end
			if not optim.ks.bh[idx].time or optim.ks.bh[idx].time < dota.GetTick() then
				optim.ks.bh[idx].time = dota.GetTick() + 250
				optim.ks.bh[idx].dmg = 0
				if AghanimState(self) then
					local w = FindSpell(self,"bounty_hunter_jinada")
					if w then
						optim.ks.bh[idx].dmg = w:GetSpecialValue("bonus_damage")
					end
				end
			end
			if not optim.ks.bh[idx].dmg or optim.ks.bh[idx].dmg == 0 or increase ~= 1 then
				return 0
			else
				return DamageTaken(v,optim.ks.bh[idx].dmg,Enum.DAMAGE_PHYS,self,true,true)
			end			
    	end,
	kez_raptor_dance = 
		function(self,spell,v,tab,attack_mgc,increase,full_dmg)
			local idx = self:GetIndex()
			if not optim.ks.kez[idx] then optim.ks.kez[idx] = {} end
			if not optim.ks.kez[idx].time or optim.ks.kez[idx].time < dota.GetTick() then
				optim.ks.kez[idx].time = dota.GetTick() + 250
				optim.ks.kez[idx].dmg = 0
				optim.ks.kez[idx].duration = 0
				local w = FindSpell(self,"kez_kazurai_katana")
				if w then
					optim.ks.kez[idx].dmg = w:GetSpecialValue("katana_bleed_attack_damage_pct")
					optim.ks.kez[idx].duration = w:GetSpecialValue("katana_bleed_duration")
				end
			end
			if not full_dmg or not optim.ks.kez[idx].dmg or optim.ks.kez[idx].dmg == 0 or increase ~= 1 then
				return 0
			else
				local pass_dmg = optim.ks.kez[idx].dmg*full_dmg/100*optim.ks.kez[idx].duration 
				return DamageTaken(v,pass_dmg,Enum.DAMAGE_PHYS,self,true,true) - v:GetHealthRegen() * optim.ks.kez[idx].duration
			end		
		end,
	luna_lucent_beam =
    	function(self,spell,v,tab,attack_mgc,increase)
       		return IsTalant(self,Enum.TALANT_5) and not IsStolen(spell) and DamageTaken(v,GetTrueMinDmg(self)*increase,attack_mgc or Enum.DAMAGE_PHYS,self,true,true) or 0
    	end,
		
	dazzle_shadow_wave =
		function(self,spell,v,tab,attack_mgc,increase)
			local value = 0
			if AghanimState(self) then
				local extra_dmg = GetTrueMinDmg(self)*increase*spell:GetSpecialValue(tab.base.KsScepterIncrease)/100
				value = value + DamageTaken(v,extra_dmg,attack_mgc or Enum.DAMAGE_PHYS,self,true,true,{MinusArmor=tab.base.ArmoreValue})
			end
			return value
		end,
}

simple.lina_light_strike_array = simple.lina_dragon_slave
simple.lina_laguna_blade = simple.lina_dragon_slave
comp.nevermore_shadowraze1 = comp.nevermore_shadowraze3
comp.nevermore_shadowraze2 = comp.nevermore_shadowraze3
double.nevermore_shadowraze1 = double.nevermore_shadowraze3
double.nevermore_shadowraze2 = double.nevermore_shadowraze3
double.kez_echo_slash = double.kez_raptor_dance


function KillStealDamage(name)
	if simple[name] then
		return simple[name]
	else
		return simple["base"]
	end
end

function KillStealDamage2(name)
	if comp[name] then
		return comp[name]
	else
		return comp["base"]
	end
end

function KillStealDamage3(name)
	if double[name] then
		return double[name]
	end
end


function GetKillStealInfo(ent)
    return killsteal:New(ent)
end 