"modifier_gnev"
{
"Passive" "0"
"IsHidden" "0"
"Duration" "25"
"EffectName" "particles/heroes/ghoul/invoker_forge_spirit_ambient_esl_embers2.vpcf"
"OnCreated"
{
"RunScript"
{
"ScriptFile" "abilities/ghoul/ghoul.lua"
"Function" "gnev_effect"
}
}
"OnAttackStart"
{
"RemoveModifier"
{
"ModifierName" "modifier_critical_strike_crit"
"Target" "CASTER"
}
"Random"
{
"Chance" "%crit_chance"
"OnSuccess"
{
"FireSound"
{
"EffectName" "Hero_SkeletonKing.CriticalStrike"
"Target" "CASTER"
}
"FireEffect"
{
"EffectName" "particles/units/heroes/hero_juggernaut/jugg_attack_blur.vpcf"
"EffectAttachType" "attach_sword"
"Target" "CASTER"
}
"ApplyModifier"
{
"ModifierName" "modifier_critical_strike_crit"
"Target" "CASTER"
}
}
}
}
}
"modifier_gnev"
{
"Passive" "0"
"IsHidden" "0"
"Duration" "25"
"EffectName" "particles/heroes/ghoul/invoker_forge_spirit_ambient_esl_embers2.vpcf"
"OnCreated"
{
"RunScript"
{
"ScriptFile" "abilities/ghoul/ghoul.lua"
"Function" "gnev_effect"
}
}
"OnAttackStart"
{
"RemoveModifier"
{
"ModifierName" "modifier_critical_strike_crit"
"Target" "CASTER"
}
"Random"
{
"Chance" "%crit_chance"
"OnSuccess"
{
"FireSound"
{
"EffectName" "Hero_SkeletonKing.CriticalStrike"
"Target" "CASTER"
}
"FireEffect"
{
"EffectName" "particles/units/heroes/hero_juggernaut/jugg_attack_blur.vpcf"
"EffectAttachType" "attach_sword"
"Target" "CASTER"
}
"ApplyModifier"
{
"ModifierName" "modifier_critical_strike_crit"
"Target" "CASTER"
}
}
}
}
}
--[[Author: YOLOSPAGHETTI
Date: March 24, 2016
Finds the next unit to jump to and deals the damage]]
function LightningJump(keys)
local caster = keys.caster
local target = keys.target
local ability = keys.ability
local jump_delay = ability:GetLevelSpecialValueFor("jump_delay", (ability:GetLevel() -1))
local radius = ability:GetLevelSpecialValueFor("radius", (ability:GetLevel() -1))
-- Applies damage to the current target
ApplyDamage({victim = target, attacker = caster, damage = ability:GetAbilityDamage(), damage_type = ability:GetAbilityDamageType()})
-- Removes the hidden modifier
target:RemoveModifierByName("modifier_arc_lightning_datadriven")
-- Waits on the jump delay
Timers:CreateTimer(jump_delay,
function()
-- Finds the current instance of the ability by ensuring both current targets are the same
local current
for i=0,ability.instance do
if ability.target[i] ~= nil then
if ability.target[i] == target then
current = i
end
end
end
-- Adds a global array to the target, so we can check later if it has already been hit in this instance
if target.hit == nil then
target.hit = {}
end
-- Sets it to true for this instance
target.hit[current] = true
-- Decrements our jump count for this instance
ability.jump_count[current] = ability.jump_count[current] - 1
-- Checks if there are jumps left
if ability.jump_count[current] > 0 then
-- Finds units in the radius to jump to
local units = FindUnitsInRadius(caster:GetTeamNumber(), target:GetAbsOrigin(), nil, radius, ability:GetAbilityTargetTeam(), ability:GetAbilityTargetType(), ability:GetAbilityTargetFlags(), 0, false)
local closest = radius
local new_target
for i,unit in ipairs(units) do
-- Positioning and distance variables
local unit_location = unit:GetAbsOrigin()
local vector_distance = target:GetAbsOrigin() - unit_location
local distance = (vector_distance):Length2D()
-- Checks if the unit is closer than the closest checked so far
if distance < closest then
-- If the unit has not been hit yet, we set its distance as the new closest distance and it as the new target
if unit.hit == nil then
new_target = unit
closest = distance
elseif unit.hit[current] == nil then
new_target = unit
closest = distance
end
end
end
-- Checks if there is a new target
if new_target ~= nil then
-- Creates the particle between the new target and the last target
local lightningBolt = ParticleManager:CreateParticle(keys.particle, PATTACH_WORLDORIGIN, target)
ParticleManager:SetParticleControl(lightningBolt,0,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))
ParticleManager:SetParticleControl(lightningBolt,1,Vector(new_target:GetAbsOrigin().x,new_target:GetAbsOrigin().y,new_target:GetAbsOrigin().z + new_target:GetBoundingMaxs().z ))
-- Sets the new target as the current target for this instance
ability.target[current] = new_target
-- Applies the modifer to the new target, which runs this function on it
ability:ApplyDataDrivenModifier(caster, new_target, "modifier_arc_lightning_datadriven", {})
else
-- If there are no new targets, we set the current target to nil to indicate this instance is over
ability.target[current] = nil
end
else
-- If there are no more jumps, we set the current target to nil to indicate this instance is over
ability.target[current] = nil
end
end)
end
--[[Author: YOLOSPAGHETTI
Date: March 24, 2016
Keeps track of all instances of the spell (since more than one can be active at once)]]
function NewInstance(keys)
local caster = keys.caster
local ability = keys.ability
local target = keys.target
-- Keeps track of the total number of instances of the ability (increments on cast)
if ability.instance == nil then
ability.instance = 0
ability.jump_count = {}
ability.target = {}
else
ability.instance = ability.instance + 1
end
-- Sets the total number of jumps for this instance (to be decremented later)
ability.jump_count[ability.instance] = ability:GetLevelSpecialValueFor("jump_count", (ability:GetLevel() -1))
-- Sets the first target as the current target for this instance
ability.target[ability.instance] = target
-- Creates the particle between the caster and the first target
local lightningBolt = ParticleManager:CreateParticle(keys.particle, PATTACH_WORLDORIGIN, caster)
ParticleManager:SetParticleControl(lightningBolt,0,Vector(caster:GetAbsOrigin().x,caster:GetAbsOrigin().y,caster:GetAbsOrigin().z + caster:GetBoundingMaxs().z ))
ParticleManager:SetParticleControl(lightningBolt,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))
end
Дело говоришь, именно так это обычно и работает.Или, на крайняк, на каждую последующую цель вешать модификатор на 0.5 секи, у которого OnDestroy(и если носитель жив) - пульнуть молнией в следующего. А цели, дабы избежать повторного попадания молнии в того же чувака, записывать в ability.targets = {}, и через этот же массив проверку делать.
function dragolnir_lightining( event )
local ability = event.ability
local target = event.target
if not target:IsMagicImmune() then
local hero = event.caster
local damage = ability:GetLevelSpecialValueFor( "bounce_damage", ability:GetLevel() - 1 )
local bounces = ability:GetLevelSpecialValueFor( "bounces", ability:GetLevel() - 1 )
local bounce_range = ability:GetLevelSpecialValueFor( "bounce_range", ability:GetLevel() - 1 )
local decay = ability:GetLevelSpecialValueFor( "bounce_decay", ability:GetLevel() - 1 ) * 0.01
local time_between_bounces = ability:GetLevelSpecialValueFor( "time_between_bounce", ability:GetLevel() - 1 )
local lightningBolt = ParticleManager:CreateParticle("particles/items_fx/chain_lightning.vpcf", PATTACH_WORLDORIGIN, hero)
ParticleManager:SetParticleControl(lightningBolt,0,Vector(hero:GetAbsOrigin().x,hero:GetAbsOrigin().y,hero:GetAbsOrigin().z + hero:GetBoundingMaxs().z ))
ParticleManager:SetParticleControl(lightningBolt,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))
EmitSoundOn("Hero_Zuus.ArcLightning.Target", target)
ApplyDamage({ victim = target, attacker = hero, damage = damage, damage_type = DAMAGE_TYPE_MAGICAL, ability = ability })
local targetsStruck = {}
target.struckByChain = true
table.insert(targetsStruck,target)
local dummy = nil
local units = nil
ability:StartCooldown(ability:GetCooldown(ability:GetLevel()))
ability:ApplyDataDrivenModifier(hero,hero,"modifier_item_lia_lightning_spear_cooldown",nil)
hero:RemoveModifierByName("modifier_item_lia_lightning_spear_lightning")
CreateTimer(DoUniqueString("ChainLightning"), {
endTime = time_between_bounces,
callback = function()
units = FindUnitsInRadius(hero:GetTeamNumber(), target:GetOrigin(), target, bounce_range, DOTA_UNIT_TARGET_TEAM_ENEMY,
DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_NONE, FIND_ANY_ORDER, true)
targetVec = target:GetAbsOrigin()
targetVec.z = target:GetAbsOrigin().z + target:GetBoundingMaxs().z
if dummy ~= nil then
dummy:RemoveSelf()
end
dummy = CreateUnitByName("dummy_unit", targetVec, false, hero, hero, hero:GetTeam())
local possibleTargetsBounce = {}
for _,v in pairs(units) do
if not v.struckByChain then
table.insert(possibleTargetsBounce,v)
end
end
local newTarget
local distance = 9999999
local newTargetVec
for _,v in pairs(possibleTargetsBounce) do
newTargetVec = v:GetAbsOrigin()
--print(v,DistanceBetweenVectors(targetVec,newTargetVec))
if v ~= target then
if DistanceBetweenPoints(targetVec,newTargetVec) < distance then
newTarget = v
distance = DistanceBetweenPoints(targetVec,newTargetVec)
end
end
end
target = newTarget
if target then
target.struckByChain = true
table.insert(targetsStruck,target)
else
for _,v in pairs(targetsStruck) do
v.struckByChain = false
v = nil
end
return
end
local lightningChain = ParticleManager:CreateParticle("particles/items_fx/chain_lightning.vpcf", PATTACH_WORLDORIGIN, dummy)
ParticleManager:SetParticleControl(lightningChain,0,Vector(dummy:GetAbsOrigin().x,dummy:GetAbsOrigin().y,dummy:GetAbsOrigin().z + dummy:GetBoundingMaxs().z ))
damage = damage - (damage*decay)
ApplyDamage({ victim = target, attacker = hero, damage = damage, damage_type = DAMAGE_TYPE_MAGICAL, ability = ability })
print("Bounce "..bounces.." Hit Unit "..target:GetEntityIndex().. " for "..damage.." damage")
EmitSoundOn("Hero_Zuus.ArcLightning.Target",target)
ParticleManager:SetParticleControl(lightningChain,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))
bounces = bounces - 1
if bounces > 0 then
return time_between_bounces
else
for _,v in pairs(targetsStruck) do
v.struckByChain = false
v = nil
end
end
end
})
end
end
Timer - отдельная библеотека от BMD.Вот нашел код из ЛИА только почему то он не хочет работать и пишет что не может идентифицировать Тimers