371 lines
12 KiB
Lua
Executable File
371 lines
12 KiB
Lua
Executable File
local suika_model_scale_table =
|
|
{
|
|
[1] = 0.5,
|
|
[2] = 0.7,
|
|
[3] = 0.8,
|
|
[4] = 1.0,
|
|
[5] = 1.2,
|
|
[6] = 2.0,
|
|
[7] = 3.0,
|
|
}
|
|
|
|
local suika_count_table =
|
|
{
|
|
[1] = 7,
|
|
[2] = 3,
|
|
[3] = 1,
|
|
[4] = 0,
|
|
[5] = 0,
|
|
[6] = 0,
|
|
[7] = 0,
|
|
}
|
|
|
|
local suika_damage_increase =
|
|
{
|
|
[1] = 0.125,
|
|
[2] = 0.25,
|
|
[3] = 0.5,
|
|
[4] = 1,
|
|
[5] = 2,
|
|
[6] = 4,
|
|
[7] = 8,
|
|
}
|
|
|
|
local suika_damage_chance =
|
|
{
|
|
[1] = 50,
|
|
[2] = 50,
|
|
[3] = 50,
|
|
[4] = 50,
|
|
[5] = 25,
|
|
[6] = 12.5,
|
|
[7] = 6.25,
|
|
}
|
|
|
|
local suika_damage_radius =
|
|
{
|
|
[1] = 200,
|
|
[2] = 200,
|
|
[3] = 200,
|
|
[4] = 400,
|
|
[5] = 600,
|
|
[6] = 800,
|
|
[7] = 1000,
|
|
}
|
|
|
|
function OnSuika01SpellStartUp(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
|
|
if caster.thtd_suika_01_scale == nil then
|
|
caster.thtd_suika_01_scale = 4
|
|
end
|
|
|
|
if caster.thtd_suika_01_scale > 1 then
|
|
caster.thtd_suika_01_scale = caster.thtd_suika_01_scale - 1
|
|
caster:SetModelScale(suika_model_scale_table[caster.thtd_suika_01_scale])
|
|
RemoveAllSuikaTinySuika(keys)
|
|
SuikaCreateTinySuika(keys)
|
|
end
|
|
end
|
|
|
|
function OnSuika01SpellStartDown(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
|
|
if caster.thtd_suika_01_scale == nil then
|
|
caster.thtd_suika_01_scale = 4
|
|
end
|
|
|
|
if caster.thtd_suika_01_scale < 7 then
|
|
caster.thtd_suika_01_scale = caster.thtd_suika_01_scale + 1
|
|
caster:SetModelScale(suika_model_scale_table[caster.thtd_suika_01_scale])
|
|
RemoveAllSuikaTinySuika(keys)
|
|
SuikaCreateTinySuika(keys)
|
|
end
|
|
end
|
|
|
|
function RemoveAllSuikaTinySuika(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
if caster.thtd_suika_01_tiny_suika_table == nil then
|
|
caster.thtd_suika_01_tiny_suika_table = {}
|
|
end
|
|
for k,v in pairs(caster.thtd_suika_01_tiny_suika_table) do
|
|
if v~=nil and v:IsNull() == false and v:IsAlive() then
|
|
v:AddNoDraw()
|
|
v:ForceKill(true)
|
|
end
|
|
end
|
|
caster.thtd_suika_01_tiny_suika_table = {}
|
|
end
|
|
|
|
function SuikaCreateTinySuika(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
local count = suika_count_table[caster.thtd_suika_01_scale]
|
|
|
|
if caster.thtd_suika_01_tiny_suika_table == nil then
|
|
caster.thtd_suika_01_tiny_suika_table = {}
|
|
end
|
|
|
|
local particle = ParticleManager:CreateParticle("particles/heroes/thtd_suika/ability_suika_01_smoke.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
|
ParticleManager:SetParticleControl(particle,0,caster:GetOrigin())
|
|
ParticleManager:SetParticleControl(particle,1,Vector(100,100,100))
|
|
ParticleManager:DestroyParticleSystem(particle,false)
|
|
|
|
for i=1,count do
|
|
local offset = 100
|
|
local rad = math.pi/2
|
|
if i > 3 then
|
|
offset = 200
|
|
rad = rad - math.pi/4 - 3*math.pi/2
|
|
end
|
|
local tinySuika = CreateUnitByName(
|
|
"tiny_suika",
|
|
caster:GetOrigin() + Vector(math.cos(rad*(i+1)),math.sin(rad*(i+1)),0)*offset,
|
|
false,
|
|
caster:GetOwner(),
|
|
caster:GetOwner(),
|
|
caster:GetTeam()
|
|
)
|
|
tinySuika.thtd_spawn_unit_owner = caster
|
|
local suikaAbility01 = caster:FindAbilityByName("thtd_suika_01")
|
|
if suikaAbility01~=nil then
|
|
suikaAbility01:ApplyDataDrivenModifier(caster, tinySuika, "passive_suika_01_attack_landed", nil)
|
|
end
|
|
keys.ability:ApplyDataDrivenModifier(caster, tinySuika, "modifier_suika_02_illusion", nil)
|
|
tinySuika:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
|
tinySuika:SetBaseDamageMax(caster:THTD_GetAttack())
|
|
tinySuika:SetBaseDamageMin(caster:THTD_GetAttack())
|
|
tinySuika:SetModelScale(suika_model_scale_table[caster.thtd_suika_01_scale])
|
|
tinySuika:SetForwardVector(caster:GetForwardVector())
|
|
table.insert(caster.thtd_suika_01_tiny_suika_table,tinySuika)
|
|
|
|
local particle = ParticleManager:CreateParticle("particles/heroes/thtd_suika/ability_suika_01_smoke.vpcf",PATTACH_CUSTOMORIGIN,tinySuika)
|
|
ParticleManager:SetParticleControl(particle,0,tinySuika:GetOrigin())
|
|
ParticleManager:SetParticleControl(particle,1,Vector(100,100,100))
|
|
ParticleManager:DestroyParticleSystem(particle,false)
|
|
end
|
|
end
|
|
|
|
function OnSuika01AttackLanded(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
local target = keys.target
|
|
|
|
if caster:GetUnitName() == "tiny_suika" then
|
|
caster = caster.thtd_spawn_unit_owner
|
|
end
|
|
|
|
if caster.thtd_suika_01_scale == nil then
|
|
caster.thtd_suika_01_scale = 4
|
|
end
|
|
|
|
if RandomInt(1,100) < suika_damage_chance[caster.thtd_suika_01_scale] then
|
|
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),suika_damage_radius[caster.thtd_suika_01_scale])
|
|
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)*suika_damage_increase[caster.thtd_suika_01_scale]
|
|
for k,v in pairs(targets) do
|
|
local damage_table = {
|
|
victim = v,
|
|
attacker = caster,
|
|
damage = damage,
|
|
ability = keys.ability,
|
|
damage_type = keys.ability:GetAbilityDamageType(),
|
|
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
|
}
|
|
UnitDamageTarget(damage_table)
|
|
|
|
local suikaAbility01 = caster:FindAbilityByName("thtd_suika_01")
|
|
if suikaAbility01~=nil then
|
|
suikaAbility01:ApplyDataDrivenModifier(caster, v, "modifier_suika_01_slow_debuff", {Duration = 5.0})
|
|
end
|
|
end
|
|
|
|
local particle = ParticleManager:CreateParticle("particles/heroes/thtd_suika/ability_suika_01.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
|
ParticleManager:SetParticleControl(particle,0,target:GetOrigin()+Vector(0,0,64))
|
|
ParticleManager:SetParticleControl(particle,1,Vector(suika_damage_radius[caster.thtd_suika_01_scale],suika_damage_radius[caster.thtd_suika_01_scale],suika_damage_radius[caster.thtd_suika_01_scale]))
|
|
ParticleManager:DestroyParticleSystem(particle,false)
|
|
end
|
|
end
|
|
|
|
function OnSuika01Think(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
if caster==nil or caster:IsNull() or caster:IsAlive() == false or caster:THTD_IsHidden() then
|
|
RemoveAllSuikaTinySuika(keys)
|
|
end
|
|
end
|
|
|
|
function OnSuika03SpellStart(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
local targetPoint = keys.target_points[1]
|
|
|
|
if caster.thtd_suika_01_scale == nil then
|
|
caster.thtd_suika_01_scale = 4
|
|
end
|
|
|
|
if caster.thtd_suika_01_tiny_suika_table == nil then
|
|
caster.thtd_suika_01_tiny_suika_table = {}
|
|
end
|
|
|
|
Suika03ThrowBallToPoint(keys,caster:GetOrigin(),targetPoint,120)
|
|
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),1000)
|
|
for k,v in pairs(caster.thtd_suika_01_tiny_suika_table) do
|
|
if v~=nil and v:IsNull() == false and v:IsAlive() and #targets>0 then
|
|
Suika03ThrowBallToPoint(keys,v:GetOrigin(),targets[RandomInt(1,#targets)]:GetOrigin(),120)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Suika03ThrowBallToPoint(keys,origin,targetpoint,vhigh)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
|
|
local curOrigin = Vector(origin.x,origin.y,origin.z)
|
|
|
|
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_suika/ability_suika_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
|
ParticleManager:SetParticleControl(effectIndex, 0, curOrigin)
|
|
ParticleManager:SetParticleControl(effectIndex, 1, Vector(suika_damage_radius[caster.thtd_suika_01_scale]/1000,0,0))
|
|
ParticleManager:SetParticleControl(effectIndex, 2, Vector(suika_damage_radius[caster.thtd_suika_01_scale]/2,0,0))
|
|
|
|
local g = -10
|
|
local dis = GetDistanceBetweenTwoVec2D(origin,targetpoint)
|
|
local vh = vhigh
|
|
local t = math.abs(2*vh/g)
|
|
local speed = dis/t
|
|
local rad = GetRadBetweenTwoVec2D(origin,targetpoint)
|
|
|
|
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * suika_damage_increase[caster.thtd_suika_01_scale]
|
|
|
|
caster:SetContextThink(DoUniqueString("ability_suika_03"),
|
|
function()
|
|
if GameRules:IsGamePaused() then return 0.03 end
|
|
vh = vh + g
|
|
curOrigin = Vector(curOrigin.x + math.cos(rad) * speed,curOrigin.y + math.sin(rad) * speed,curOrigin.z + vh)
|
|
ParticleManager:SetParticleControl(effectIndex, 0, curOrigin)
|
|
if curOrigin.z >= caster:GetOrigin().z - 50 then
|
|
return 0.02
|
|
else
|
|
curOrigin.z = caster:GetOrigin().z
|
|
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
|
local effectIndex2 = ParticleManager:CreateParticle("particles/thd2/heroes/suika/ability_suika_04_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
|
ParticleManager:SetParticleControl(effectIndex2, 0, curOrigin)
|
|
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
|
|
|
local targets = THTD_FindUnitsInRadius(caster,curOrigin,suika_damage_radius[caster.thtd_suika_01_scale]/2)
|
|
for k,v in pairs(targets) do
|
|
local DamageTable = {
|
|
ability = keys.ability,
|
|
victim = v,
|
|
attacker = caster,
|
|
damage = damage,
|
|
damage_type = keys.ability:GetAbilityDamageType(),
|
|
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
|
}
|
|
UnitDamageTarget(DamageTable)
|
|
end
|
|
return nil
|
|
end
|
|
end,
|
|
0)
|
|
end
|
|
|
|
function OnSuika04SpellStart(keys)
|
|
local caster = EntIndexToHScript(keys.caster_entindex)
|
|
local target = keys.target
|
|
|
|
if caster.thtd_suika_01_scale == nil then
|
|
caster.thtd_suika_01_scale = 4
|
|
end
|
|
|
|
if caster.thtd_suika_01_tiny_suika_table == nil then
|
|
caster.thtd_suika_01_tiny_suika_table = {}
|
|
end
|
|
|
|
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.range)
|
|
if #targets>0 then
|
|
for index,lockTarget in pairs(targets) do
|
|
if lockTarget.thtd_suika_04_lock~=true then
|
|
lockTarget.thtd_suika_04_lock = true
|
|
OnSuika04LockToTarget(keys,caster,lockTarget)
|
|
end
|
|
end
|
|
end
|
|
|
|
for k,v in pairs(caster.thtd_suika_01_tiny_suika_table) do
|
|
if v~=nil and v:IsNull() == false and v:IsAlive() then
|
|
local targets = THTD_FindUnitsInRadius(caster,v:GetOrigin(),keys.range)
|
|
if #targets>0 then
|
|
for index,lockTarget in pairs(targets) do
|
|
if lockTarget.thtd_suika_04_lock~=true then
|
|
lockTarget.thtd_suika_04_lock = true
|
|
OnSuika04LockToTarget(keys,v,lockTarget)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function OnSuika04LockToTarget(keys,caster,target)
|
|
local originalCaster = EntIndexToHScript(keys.caster_entindex)
|
|
local vecHook = target:GetOrigin()
|
|
|
|
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_suika/ability_suika_04.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
|
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
|
ParticleManager:SetParticleControl(effectIndex, 1, vecHook)
|
|
ParticleManager:SetParticleControlEnt(effectIndex , 3, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
|
ParticleManager:SetParticleControl(effectIndex, 4, Vector(2400,0,0))
|
|
ParticleManager:SetParticleControl(effectIndex, 5, Vector(2400,0,0))
|
|
ParticleManager:SetParticleControl(effectIndex, 6, vecHook)
|
|
|
|
local timecount = keys.duration_time
|
|
local range = keys.range
|
|
ParticleManager:DestroyParticleSystemTime(effectIndex,timecount)
|
|
|
|
caster:SetContextThink(DoUniqueString("ability_suika_04"),
|
|
function()
|
|
if GameRules:IsGamePaused() then return 0.03 end
|
|
if timecount <= 0 or target==nil or target:IsNull() or target:IsAlive()==false then
|
|
ParticleManager:DestroyParticleSystem(effectIndex, true)
|
|
if THTD_IsValid(target) then
|
|
FindClearSpaceForUnit(target, target:GetOrigin(), false)
|
|
target.thtd_suika_04_lock = false
|
|
end
|
|
return nil
|
|
end
|
|
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), target:GetOrigin()) > range then
|
|
local forward = (target:GetOrigin() - caster:GetAbsOrigin()):Normalized()
|
|
target:SetAbsOrigin(caster:GetOrigin()+forward*range)
|
|
local damage = originalCaster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2 * suika_damage_increase[originalCaster.thtd_suika_01_scale]
|
|
if originalCaster == caster then
|
|
if not (RandomInt(1,100) <= suika_damage_chance[caster.thtd_suika_01_scale]) then
|
|
damage = originalCaster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2
|
|
end
|
|
end
|
|
local DamageTable = {
|
|
ability = keys.ability,
|
|
victim = target,
|
|
attacker = originalCaster,
|
|
damage = damage,
|
|
damage_type = keys.ability:GetAbilityDamageType(),
|
|
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
|
}
|
|
UnitDamageTarget(DamageTable)
|
|
end
|
|
|
|
local damage = originalCaster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2 * suika_damage_increase[originalCaster.thtd_suika_01_scale]
|
|
if originalCaster == caster then
|
|
if RandomInt(1,100) > suika_damage_chance[caster.thtd_suika_01_scale] then
|
|
damage = originalCaster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2
|
|
end
|
|
end
|
|
local DamageTable = {
|
|
ability = keys.ability,
|
|
victim = target,
|
|
attacker = originalCaster,
|
|
damage = damage,
|
|
damage_type = keys.ability:GetAbilityDamageType(),
|
|
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
|
}
|
|
UnitDamageTarget(DamageTable)
|
|
|
|
timecount = timecount - 0.2
|
|
return 0.2
|
|
end,
|
|
0)
|
|
end |